您尚未登录,请登录后浏览更多内容! 登录 | 立即注册

QQ登录

只需一步,快速开始

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 12430|回复: 0
打印 上一主题 下一主题

[html5] 在IIS上搭建WebSocket服务器(二)

[复制链接]
跳转到指定楼层
楼主
发表于 2018-11-7 00:43:37 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
服务器端代码编写
1.新建一个ASP.net Web MVC5项目
4 Y) P  I4 w' ?
2.新建一个“一般处理程序”
3.Handler1.ashx代码如下:
  1. using System;( _" _9 f! o3 N* q
  2. using System.Collections.Generic;
      Z+ n8 R8 j4 ?" O3 O+ O3 Q
  3. using System.Linq;( d+ ]! ]- v. |+ R6 H' g
  4. using System.Net.WebSockets;
    & n4 {- W8 H% L! H% ~
  5. using System.Text;! y! W" u6 b# X+ x, w
  6. using System.Threading;
    3 i5 n6 h7 }6 Y1 N
  7. using System.Threading.Tasks;
    6 I% K0 U- [+ n" ~
  8. using System.Web;# E! V" d4 T- z7 `$ w
  9. using System.Web.WebSockets;5 \( U  S8 E0 ?1 r. P% D% }6 z
  10. " [- q% Y/ w3 l( O: X

  11. / m) n" k& K! d& ~" T
  12. namespace WebApplicationWebsocketHandler6 Z8 R; P% }$ }( v4 |  a
  13. {3 r9 O" T( G# ~
  14.     /// <summary>9 a5 }+ @) W1 `$ z. R8 I
  15.     /// 离线消息
    * F/ ?6 l4 q% N6 h1 Z
  16.     /// </summary>+ K  T4 f& B- C3 g* w
  17.     public class MessageInfo/ Z! u% `$ [8 }+ o# H  \' [8 L
  18.     {# w; R8 S& ^, Z/ K% o
  19.         public MessageInfo(DateTime _MsgTime, ArraySegment<byte> _MsgContent)1 l+ y5 p0 H+ `3 `9 ], V7 ]
  20.         {
    6 g, n' b% N3 p, |& K+ s6 s! M7 M- l
  21.             MsgTime = _MsgTime;
    2 [( I3 w  |8 c0 h
  22.             MsgContent = _MsgContent;, e* ^' M+ k% }$ W1 }
  23.         }# R, X2 d1 c) K& ?: B0 r1 \
  24.         public DateTime MsgTime { get; set; }
    2 p  e  @6 q, V9 K1 P) ~) J8 r
  25.         public ArraySegment<byte> MsgContent { get; set; }7 I2 ?) r: ?/ C' R3 L4 U8 U9 i
  26.     }
    5 z! |. Y& z& q5 a; ?+ v, r

  27. ' X  o0 I3 v# i$ G0 V# D- d  {
  28. # T* E7 J: |1 Q$ i) W
  29. 4 Z7 ^6 j1 X$ w8 i) ^. @3 @, \
  30. : c$ l, b: L/ _$ n' j
  31.     /// <summary>
    2 F' k9 n: c* _. U
  32.     /// Handler1 的摘要说明5 v3 {; P5 s8 W: A1 |
  33.     /// </summary>
    * l; q3 a0 F* ]- p, m
  34.     public class Handler1 : IHttpHandler4 ~9 P5 Y. t/ V5 y
  35.     {
    + s# A- M* A5 y" @" T! e
  36.         private static Dictionary<string, WebSocket> CONNECT_POOL = new Dictionary<string, WebSocket>();//用户连接池
    % h1 e( h# d% t  W: I
  37.         private static Dictionary<string, List<MessageInfo>> MESSAGE_POOL = new Dictionary<string, List<MessageInfo>>();//离线消息池
    6 P2 L- @( q# H. K7 N, R
  38.         public void ProcessRequest(HttpContext context)9 [7 q( O9 g5 D% a
  39.         {
    ; C' u/ N) B* N$ G$ ^
  40.             //context.Response.ContentType = "text/plain";! w/ U1 G/ B: c. |! ^) Y
  41.             //context.Response.Write("Hello World");
    7 M2 I1 s* u7 F' H  G0 i% }
  42.             if (context.IsWebSocketRequest)
    + x! D! d/ q; d7 Q& g
  43.             {% Y7 P2 b# [  o- \9 L3 X
  44.                 context.AcceptWebSocketRequest(ProcessChat);1 t" |" |% }3 G# C" g  |. Q2 y! R
  45.             } 5 Y  `) h# T4 m( p# u6 v. |; e
  46.         }
    % C2 i' U- v  V4 ~: Z' U

  47. / D% O7 g1 ]4 S; d3 F' z3 h+ N$ v0 [
  48.         private async Task ProcessChat(AspNetWebSocketContext context)
    1 K, ~: ]# r7 {3 |3 I
  49.         {
    4 r9 z, ]" t/ R; F
  50.             WebSocket socket = context.WebSocket;9 v1 s! W5 s# s9 r! d( r0 J
  51.             string user = context.QueryString["user"].ToString();0 `' X) |+ b4 Z8 H

  52. * J5 k; p- O% `3 J0 p% t; V* ]
  53.             try
    ; j" A8 L) r+ H' r' [
  54.             {
    ) T7 ^' f. X3 \6 U
  55.                 #region 用户添加连接池, ?4 ^" ?5 r; A/ \: w2 N
  56.                 //第一次open时,添加到连接池中
    3 k! L& U, Q. [' m4 t/ ]
  57.                 if (!CONNECT_POOL.ContainsKey(user))
    & y2 V" n- h6 h. m
  58.                     CONNECT_POOL.Add(user, socket);//不存在,添加
    9 ]; l* u+ ]9 ~8 D/ F$ _( f
  59.                 else
    - c  i# n' b5 M  Z7 ^/ b/ V) A
  60.                     if (socket != CONNECT_POOL[user])//当前对象不一致,更新9 v. e2 }' `. N0 p; t
  61.                         CONNECT_POOL[user] = socket;
    ) `. m: U. T" U
  62.                 #endregion
    & y( j+ z0 e) B5 t5 ?8 [1 N( {4 L

  63. 8 A/ b0 ?' z% [$ Q2 N' A* K* L
  64.                 #region 离线消息处理
    : [% K* N( ~; p# R5 h
  65.                 if (MESSAGE_POOL.ContainsKey(user)): d" ^/ s7 w  r8 L( l9 Z* {
  66.                 {
    5 n* z; V( ^) z7 p- B) d
  67.                     List<MessageInfo> msgs = MESSAGE_POOL[user];
    ; k7 Y( p! f* \" M" J" d4 |
  68.                     foreach (MessageInfo item in msgs): k' N) K- V; L6 H  v, Y9 A) Q
  69.                     {
    : N4 f1 R+ |' n
  70.                         await socket.SendAsync(item.MsgContent, WebSocketMessageType.Text, true, CancellationToken.None);
    ; T) K7 F# o; }2 Z
  71.                     }
    8 k5 M, \0 ]: J8 Z& K# c! k) [
  72.                     MESSAGE_POOL.Remove(user);//移除离线消息: `4 B- Y# t3 [
  73.                 }/ w+ T7 A6 ~: w2 Y: M; Q
  74.                 #endregion
    0 b9 U# t6 ]; x% A
  75. 4 a1 S2 ]/ t$ L1 r, u
  76.                 string descUser = string.Empty;//目的用户
    $ [  |/ b! ~% d0 r' x: r( h
  77.                 while (true)
    & ]# b  }1 u0 T; j9 E/ \, y, _
  78.                 {  Y( `. w! f: V/ K: ~( L* A, W3 ^
  79.                     if (socket.State == WebSocketState.Open)2 I( _" Y. N& q; H
  80.                     {
    / u, _7 n) M% _
  81.                         ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[2048]);
    , u& o+ r0 b9 y" f  n7 M& J
  82.                         WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None);- v$ r- V1 P2 [

  83. ) @/ C7 s2 A. U! w, m$ l7 h
  84.                         #region 消息处理(字符截取、消息转发)
    5 H" {$ Y* N: \& x8 ?
  85.                         try& Y) S! o0 o& t3 Z" @+ T3 X+ ^( m
  86.                         {; T9 e+ f, i) |7 {: z
  87.                             #region 关闭Socket处理,删除连接池
    ; h! g# Z" A0 H1 p& W7 W
  88.                             if (socket.State != WebSocketState.Open)//连接关闭# ~' ~- N) Z# H1 Y  ]4 F
  89.                             {1 T, \- V9 f9 u& ~5 y
  90.                                 if (CONNECT_POOL.ContainsKey(user)) CONNECT_POOL.Remove(user);//删除连接池5 h6 N+ F/ k8 l8 E0 F
  91.                                 break;5 I  w3 R) d* S" M/ }9 j8 A
  92.                             }
    8 V6 h2 C, j1 Y8 K
  93.                             #endregion, Q3 K; C+ C6 o# C' ]. ~

  94. ( b3 P# F7 E) d6 I3 g  G! m
  95.                             string userMsg = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);//发送过来的消息; j; }  B2 \1 f8 E  p; q% ?
  96.                             string[] msgList = userMsg.Split('|');, t, g) e3 o$ r( [& c, r' T* t7 y. D  ?
  97.                             if (msgList.Length == 2)# u2 b! }- a) U, Q% Z
  98.                             {  n* W9 y! R7 R4 G, y- `
  99.                                 if (msgList[0].Trim().Length > 0)8 y/ J. X, _% _5 E  _8 P0 E
  100.                                     descUser = msgList[0].Trim();//记录消息目的用户, t- p# t3 i8 x  z9 j" @- |  _
  101.                                 buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(msgList[1]));
    $ W% h- h7 M$ c$ [( |1 B. s
  102.                             }8 b, P, a6 m/ J
  103.                             else
    % e. G% G8 l8 X  Y7 F: i% v
  104.                                 buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(userMsg));
    " h: ~8 R2 T. b

  105. 1 L# ^: u8 ?; d3 w1 w
  106.                             if (CONNECT_POOL.ContainsKey(descUser))//判断客户端是否在线) k9 l- }! [, ~4 m- p
  107.                             {9 E1 }2 V: `4 _& M& A
  108.                                 WebSocket destSocket = CONNECT_POOL[descUser];//目的客户端6 Q6 v8 S& ~2 k; b4 G( }
  109.                                 if (destSocket != null && destSocket.State == WebSocketState.Open)
    : y$ \; ?) m) o: ?. {/ I7 D
  110.                                     await destSocket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
    4 `; a* X& O. z7 N& j! h% v( D/ c2 c: f
  111.                             }" R  z4 G' W, h9 Y4 D& M; F5 T: v
  112.                             else
    # R5 Q0 S& @- h5 J7 Z/ Y1 F2 T
  113.                             {
    7 s; c7 k4 O' j
  114.                                 Task.Run(() =>
    ; i5 n1 d1 `4 [5 g7 a
  115.                                 {  X- y4 A- M" j& w; D; N
  116.                                     if (!MESSAGE_POOL.ContainsKey(descUser))//将用户添加至离线消息池中4 H8 J! V/ g; ~. _
  117.                                         MESSAGE_POOL.Add(descUser, new List<MessageInfo>());
    ; H  w  i; y: `; V7 J
  118.                                     MESSAGE_POOL[descUser].Add(new MessageInfo(DateTime.Now, buffer));//添加离线消息
    3 O; F9 X9 a; o  u: `, Z  S
  119.                                 });0 |6 r" f4 C) C+ E3 J# |7 A
  120.                             }
    9 Z9 x! c2 l7 n: q# D( ]4 l0 M
  121.                         }
    3 m2 o7 _) k! {0 z4 o2 E/ v
  122.                         catch (Exception exs)
    / g2 x7 y3 C/ m) z/ a, _3 z/ L- x
  123.                         {
    * G8 ^- ^4 E8 Y$ V" g
  124.                             //消息转发异常处理,本次消息忽略 继续监听接下来的消息
    9 f/ W. z- z7 I6 [- f, _
  125.                         }
    : v+ F3 B+ j. L. R* b
  126.                         #endregion# ]1 O! v: u$ V5 M
  127.                     }
    & U- ]" D. H0 q3 m- U' I
  128.                     else- @) Q7 R' O1 N' N, V
  129.                     {
    # \- \7 L" b. j
  130.                         break;! y4 W% H4 E9 e' l- d+ _9 d
  131.                     }
    # k. f3 R! E# j, I( v
  132.                 }//while end8 ~" G/ S& I! Y3 d! A
  133.             }
    ) @' }7 e/ R0 l3 D5 T( Y
  134.             catch (Exception ex). I  R" J1 }' p/ w' Q5 ]2 q) N
  135.             {2 j  p9 n/ C0 [6 }! H' A, v
  136.                 //整体异常处理
    " j/ ~% s/ P- G& f" K
  137.                 if (CONNECT_POOL.ContainsKey(user)) CONNECT_POOL.Remove(user);" D/ E6 V+ [9 `0 p$ B. P
  138.             }
      ?8 R; n' j* b, [1 ?
  139.         }% P( r+ {* L; P! O7 U# g, g
  140. , M5 f, T1 O3 @: |' l1 ^

  141. 5 J2 [( [2 b6 n6 C
  142.         public bool IsReusable4 m9 r9 y8 Q# |# c# E& @2 t( ~" @3 }
  143.         {+ g) ?$ n7 i5 s3 q5 V/ ]4 b7 |
  144.             get
    ! a- U! |$ w- b6 y4 g1 ~
  145.             {. p7 R- B( |' n' ~% [$ I. D4 w- t
  146.                 return false;
    ; v. e8 ~) g* V
  147.             }( }5 s4 s. G5 d6 n' H) v9 x
  148.         }4 S7 |! G2 n& S  `
  149.     }
    * r6 R4 H8 J- d, Z
  150. }
复制代码
4.运行看是否报错,若没错将我们的服务器网站发布到IIS(支持WebSocket的IIS上,win7的系统时不可以的)上
点击“生成”->"发布........",以文件系统的方式发布,目标位置为我们创建的IIS网站对应的物理路径

, l/ U# N! b: v4 {: I
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享分享 支持支持 反对反对
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

GMT+8, 2024-12-22 16:00 , Processed in 0.111909 second(s), 23 queries .

Copyright © 2001-2024 Powered by cncml! X3.2. Theme By cncml!