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

QQ登录

只需一步,快速开始

 找回密码
 立即注册

QQ登录

只需一步,快速开始

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

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

[复制链接]
跳转到指定楼层
楼主
发表于 2018-11-7 00:43:37 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
服务器端代码编写
1.新建一个ASP.net Web MVC5项目

7 C1 K2 Y0 z) A/ M7 L- C$ p
2.新建一个“一般处理程序”
3.Handler1.ashx代码如下:
  1. using System;8 ^6 [$ c" U9 O8 C0 A$ Y1 r
  2. using System.Collections.Generic;( u$ d) C8 E* G5 b
  3. using System.Linq;
    9 k  W: ~. o. R( |1 f5 h4 c. g
  4. using System.Net.WebSockets;
    % Y5 `1 I& B7 }& ^1 j- K& m
  5. using System.Text;
    0 n5 ^; S% m6 v9 |; _! y
  6. using System.Threading;. ~9 k0 Z7 Z6 x6 t6 x
  7. using System.Threading.Tasks;
    / o1 c( I% J& B/ w
  8. using System.Web;% @8 y" R8 G% n+ J- z
  9. using System.Web.WebSockets;. r* e; t- ~: U0 R

  10. 6 _" S) u( U$ O
  11. , k$ D" X! P9 V
  12. namespace WebApplicationWebsocketHandler
    , V5 u: m1 R: D5 x9 ~- ?
  13. {6 ~- m( z& N6 h- ~+ S. R9 k* \" U* ~
  14.     /// <summary>
    ! v0 `! s& f% g6 c
  15.     /// 离线消息) s. J* z. q. Q7 T
  16.     /// </summary>  i6 ?1 t! j3 n% k' r1 b
  17.     public class MessageInfo
    4 X  Q* k& C$ N9 |) V3 d7 b
  18.     {
    - H4 ]1 V1 v: p% U- r
  19.         public MessageInfo(DateTime _MsgTime, ArraySegment<byte> _MsgContent)1 c& c' \0 x% T2 q9 U- ]' ]
  20.         {
    ' o3 j' M. w2 V* {& E1 b; W
  21.             MsgTime = _MsgTime;
    - ?/ @* h0 p- Y3 e$ B+ l
  22.             MsgContent = _MsgContent;: S' [6 H/ _1 g* @( `
  23.         }& \: |$ G/ a4 \/ Q( y
  24.         public DateTime MsgTime { get; set; }
    , u) `4 W* ~8 }: G) x1 {& q
  25.         public ArraySegment<byte> MsgContent { get; set; }
    # f5 h9 a" @% ~) y7 H  V# \
  26.     }' ~- e1 D- B8 v, x7 `
  27. 3 b, A/ x: X: @
  28. , A) a, H, \( m8 }
  29. 7 d' }2 e3 i. q0 b
  30. 0 q' }2 D" C4 V) A
  31.     /// <summary>" t3 \% u0 k( s9 K0 W0 Y
  32.     /// Handler1 的摘要说明
    1 K1 `7 {: d, A
  33.     /// </summary>
    - i+ X5 i2 L0 g
  34.     public class Handler1 : IHttpHandler
    : A( r: j* k7 J) U: }
  35.     {1 O5 g' i9 K! C, X
  36.         private static Dictionary<string, WebSocket> CONNECT_POOL = new Dictionary<string, WebSocket>();//用户连接池
    ) ^; V1 K2 p9 p, W
  37.         private static Dictionary<string, List<MessageInfo>> MESSAGE_POOL = new Dictionary<string, List<MessageInfo>>();//离线消息池
    1 ]5 m5 Z  S1 q& L/ x" g" j
  38.         public void ProcessRequest(HttpContext context)5 {2 k. X3 Y& r! o% l
  39.         {
    $ n/ h* a9 q- Y& n8 [& P
  40.             //context.Response.ContentType = "text/plain";
    # q0 }) ?$ U7 H& K4 L' L( T
  41.             //context.Response.Write("Hello World");
    / o, Y/ j  ^, K" Z0 r$ n2 M( H( B
  42.             if (context.IsWebSocketRequest)
    / Y" f  v4 _3 W1 F! t0 ?
  43.             {
    ) ^2 M/ v7 z# |; O. q0 L
  44.                 context.AcceptWebSocketRequest(ProcessChat);
    % X: c; y' G6 ~; O
  45.             }
    7 V, k0 f9 O9 q  }2 c
  46.         }
    1 i- }" v* t3 h4 ^
  47. 1 G  W% V) S* o/ p/ {9 k9 u
  48.         private async Task ProcessChat(AspNetWebSocketContext context)# ]8 q2 N0 j) r
  49.         {
    0 y& J/ e0 ~' V& W) R6 D
  50.             WebSocket socket = context.WebSocket;2 s# T- p& W5 F' D; S' Y
  51.             string user = context.QueryString["user"].ToString();
    : C. h' }: G# O0 h
  52. * P+ Y1 }; u/ R& M
  53.             try
      W% r8 }" X1 J' S, R, P5 g
  54.             {0 j/ h+ h/ y6 r! G' X) p, G8 w
  55.                 #region 用户添加连接池
    ) K5 N- Z4 u: ]; }4 W
  56.                 //第一次open时,添加到连接池中- M; ~& [: f- s' H8 v. `
  57.                 if (!CONNECT_POOL.ContainsKey(user))
    0 }% ^; G& K7 @' Q) {
  58.                     CONNECT_POOL.Add(user, socket);//不存在,添加
    1 S1 I# H0 w* S' h( o# a
  59.                 else& x2 w' M( k3 }: ~5 u" h
  60.                     if (socket != CONNECT_POOL[user])//当前对象不一致,更新3 K7 ^5 f& U& `) }1 {, m
  61.                         CONNECT_POOL[user] = socket;
    & H: m* D3 s& W, J
  62.                 #endregion
    " F! M/ P' O* g
  63. ! T/ z: r7 S, `  X
  64.                 #region 离线消息处理9 i2 ?4 m7 ?- P. w' K' _' C
  65.                 if (MESSAGE_POOL.ContainsKey(user))
    ' _$ l- b+ w/ w% V, z2 }* T" d
  66.                 {
      H" @! m4 f* Y  z2 f1 j/ `
  67.                     List<MessageInfo> msgs = MESSAGE_POOL[user];
    . j. i9 p! F5 K; X, q
  68.                     foreach (MessageInfo item in msgs)& l+ P# w5 m! N, O3 f
  69.                     {9 ]4 D) ?4 ~! D- ^4 H
  70.                         await socket.SendAsync(item.MsgContent, WebSocketMessageType.Text, true, CancellationToken.None);
    8 i3 Q% M5 F. k2 b
  71.                     }
    9 U- `6 u& N! J* V/ U
  72.                     MESSAGE_POOL.Remove(user);//移除离线消息/ S! {8 W; ^, K
  73.                 }
    4 m( w0 ~8 W+ a# k$ v
  74.                 #endregion
    ( L3 f/ y3 B& b9 s
  75. 5 C) J. a8 z5 C+ Y/ A3 Z
  76.                 string descUser = string.Empty;//目的用户
    * D4 a& C: E4 M  Z" d. }/ x
  77.                 while (true): o  p& S) `7 \- l( \8 Y
  78.                 {
    * N7 d  e# n  ?0 s* ^7 I
  79.                     if (socket.State == WebSocketState.Open); Z% Q% v4 l* h, z, m8 D9 K
  80.                     {
    " y# F* k+ w1 t% L& _% S5 a: U
  81.                         ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[2048]);4 f0 d! t: q9 _: G7 @4 H
  82.                         WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None);6 x9 L2 M1 H* Z- U& v
  83. / t1 q$ ]5 M( |2 _
  84.                         #region 消息处理(字符截取、消息转发)$ Y' g3 n( e& x) ^+ ^% `, I4 X
  85.                         try, X4 c' c$ A0 k/ h( C; P
  86.                         {
    - ^; e6 J4 [# g7 `
  87.                             #region 关闭Socket处理,删除连接池6 o$ X2 {0 l. @
  88.                             if (socket.State != WebSocketState.Open)//连接关闭+ C- S$ S- C4 b1 l
  89.                             {/ Y+ G& D6 O. j8 ~
  90.                                 if (CONNECT_POOL.ContainsKey(user)) CONNECT_POOL.Remove(user);//删除连接池/ C+ j2 q0 y- C$ R$ _, u
  91.                                 break;
    # G' O9 s- I8 Q
  92.                             }+ k1 ?8 L2 h  q
  93.                             #endregion2 p, z/ ^1 e6 p) V' Z( v: C

  94. - J& ^1 I8 ^* u& v4 h  y9 Q% f2 M) z
  95.                             string userMsg = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);//发送过来的消息  p& V/ c+ ?% G1 ^5 C% ~. e
  96.                             string[] msgList = userMsg.Split('|');3 ~' _  x+ N3 J1 o
  97.                             if (msgList.Length == 2)
    * c- d. v. s5 A. P1 U( a
  98.                             {
    ) O+ p% z  z* v/ m
  99.                                 if (msgList[0].Trim().Length > 0)3 d; P: E2 k& l7 N
  100.                                     descUser = msgList[0].Trim();//记录消息目的用户5 z6 F1 |1 h& P- t, g
  101.                                 buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(msgList[1]));
    $ |& a  q. h, p9 c% j1 G! b
  102.                             }
    & w3 K+ `# R! |) X& F, y- w- U
  103.                             else
    ( w7 U- r2 s" `
  104.                                 buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(userMsg));7 Y9 X1 p1 l! L  K! D$ B9 A

  105.   P  O1 k7 N' S
  106.                             if (CONNECT_POOL.ContainsKey(descUser))//判断客户端是否在线
    1 e5 d2 j) q( c
  107.                             {( q9 v: y( q$ L2 ?' j
  108.                                 WebSocket destSocket = CONNECT_POOL[descUser];//目的客户端& B$ Q5 x5 |0 l3 V
  109.                                 if (destSocket != null && destSocket.State == WebSocketState.Open)
    - K( ^# h# [5 @& k: a
  110.                                     await destSocket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
    . i$ ^- O/ w0 ^) K0 G* f
  111.                             }
    . i. J9 ?3 B% z* Y: }6 k
  112.                             else5 a: k3 O) V' x
  113.                             {
    6 |1 D5 V9 k: g! k$ I: e
  114.                                 Task.Run(() =>' q  ~" J" o, t6 k# k: R% E
  115.                                 {) h; `+ c; b' Q
  116.                                     if (!MESSAGE_POOL.ContainsKey(descUser))//将用户添加至离线消息池中' q' f5 b* x$ f! E8 ^( G
  117.                                         MESSAGE_POOL.Add(descUser, new List<MessageInfo>());
    " t4 r: ^. g- n7 c7 d4 W
  118.                                     MESSAGE_POOL[descUser].Add(new MessageInfo(DateTime.Now, buffer));//添加离线消息
    / ~  o1 a" i  K" E. u3 l( |
  119.                                 });
    ( V* r6 t) ~- ]3 A8 y7 S/ ^
  120.                             }
    0 J% }6 p0 y4 ^* h0 [, J* X! c
  121.                         }
    : g% w5 ]; P( w6 t9 Y! H1 `! V
  122.                         catch (Exception exs)
    5 q+ q( A. @+ c% z1 W
  123.                         {# _9 J0 H4 H  b& L
  124.                             //消息转发异常处理,本次消息忽略 继续监听接下来的消息
    " ~- `6 Y0 M$ R, U: F& O( D" d+ e- o
  125.                         }
    & @3 l# |7 y; _  a0 Q
  126.                         #endregion' d& o3 i& ^0 ?4 W" u
  127.                     }
    4 w& {7 n- V6 a. G
  128.                     else
    : T3 g  t: p: e! s; O% H/ G
  129.                     {
    4 x  @  g1 D$ [0 m( r" R
  130.                         break;( v( ?" ^5 q6 C1 I7 A+ Q
  131.                     }3 a- O2 [# z4 b' |
  132.                 }//while end
    1 n' d5 O% s) X
  133.             }
      J+ C. C% v+ \1 t  r% A0 u; Q8 f
  134.             catch (Exception ex): _% d0 j, \2 B3 M, o
  135.             {5 M* z5 r0 @2 T. l$ Z
  136.                 //整体异常处理
    9 h; q0 I% t! Y9 o( X$ n
  137.                 if (CONNECT_POOL.ContainsKey(user)) CONNECT_POOL.Remove(user);% l' D1 _  }- {# x
  138.             }
    1 R- j- ]) G' D1 ^; e
  139.         }. Q  a  k0 a6 d) F4 v
  140. ) V4 a1 I' C4 |" i4 N) q$ Q

  141. + Z- J" i9 S! I  @9 x% w
  142.         public bool IsReusable! H3 B. D8 M, B% h. L
  143.         {
    * v! O" F7 P( d$ `3 n$ R5 L4 E5 V
  144.             get, R* m5 |1 @# R0 w+ S( s
  145.             {
      O; K  v! b! j" t- \# k8 `
  146.                 return false;" m# h" F) l9 P* N3 I4 g
  147.             }
    8 m/ C( f# c+ ?$ P2 [7 D' K+ o
  148.         }# Z( J$ w# p: p" b6 c7 N
  149.     }* F2 k3 n: f% c# c+ q
  150. }
复制代码
4.运行看是否报错,若没错将我们的服务器网站发布到IIS(支持WebSocket的IIS上,win7的系统时不可以的)上
点击“生成”->"发布........",以文件系统的方式发布,目标位置为我们创建的IIS网站对应的物理路径
/ c) V+ |# F7 G
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享分享 支持支持 反对反对
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

GMT+8, 2024-12-23 01:25 , Processed in 0.140156 second(s), 22 queries .

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