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

QQ登录

只需一步,快速开始

 找回密码
 立即注册

QQ登录

只需一步,快速开始

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

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

[复制链接]
跳转到指定楼层
楼主
发表于 2018-11-7 00:43:37 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
服务器端代码编写
1.新建一个ASP.net Web MVC5项目
+ D3 f. v* a" V
2.新建一个“一般处理程序”
3.Handler1.ashx代码如下:
  1. using System;! {) ~! U8 d9 I5 ~2 u
  2. using System.Collections.Generic;" L" T. _9 A$ T( i6 r5 }5 m5 p
  3. using System.Linq;
    / t; |  c+ M) ]
  4. using System.Net.WebSockets;9 y" Q" i5 F2 J0 Z8 m
  5. using System.Text;
    - L. o8 P3 n$ X% R  H6 d7 v: f
  6. using System.Threading;( K0 d3 s9 M" o, M% r
  7. using System.Threading.Tasks;3 P& l& W0 y. h+ a
  8. using System.Web;, ^: W5 `9 d; B. l0 f0 k+ q: y
  9. using System.Web.WebSockets;
    % m* V& d0 ?9 ?2 o+ U0 \5 z; O
  10. + e4 {9 ]: W+ W) `, O: r

  11. ' Y4 X; ]5 H( d6 x# U) a
  12. namespace WebApplicationWebsocketHandler
    " _. C8 G% i5 @
  13. {
    2 _" e) [4 [3 H
  14.     /// <summary>
    . j% m+ U. g3 i, u! K! O& a2 g
  15.     /// 离线消息
    % c' V# l; o9 Y8 j" Y4 J( o* D* H+ B
  16.     /// </summary>
    ) N: x: T! c3 B& Z; i" j9 Q" W
  17.     public class MessageInfo% `" Y1 T0 A5 ]+ j4 J. q
  18.     {7 T, z9 R) Z" i) Y! B
  19.         public MessageInfo(DateTime _MsgTime, ArraySegment<byte> _MsgContent)* M4 n. q( Z0 t
  20.         {# {5 r- V- s) R% {
  21.             MsgTime = _MsgTime;
      N* a9 w& r- {- z
  22.             MsgContent = _MsgContent;/ J4 P* R7 _, |: K, t$ u: H
  23.         }: d0 r. V& P3 P+ u
  24.         public DateTime MsgTime { get; set; }) l) B! p  t2 q6 f! D% m; l
  25.         public ArraySegment<byte> MsgContent { get; set; }. t* A; T0 n; |3 u
  26.     }
    # K: h8 v1 ?* K2 n9 C6 V
  27. 5 c2 {, `! D$ T7 {+ R' r2 T8 C8 H

  28. # M; Q* K% O6 |& R! W
  29.   n6 @( e6 ^% S3 }3 U) ?$ G4 D
  30. + a1 ?& q4 |$ x7 [9 V
  31.     /// <summary>2 c$ i) i$ T4 L9 P
  32.     /// Handler1 的摘要说明
    ) k3 Z5 C8 Y7 h0 Z
  33.     /// </summary>$ b; W' q" {  S$ {4 \& x$ l( o
  34.     public class Handler1 : IHttpHandler
    3 Z/ U) K; B& ?: Q! `( _
  35.     {
    - ?. q8 _. i! X7 g
  36.         private static Dictionary<string, WebSocket> CONNECT_POOL = new Dictionary<string, WebSocket>();//用户连接池
    ! H2 }( V, U* T& @
  37.         private static Dictionary<string, List<MessageInfo>> MESSAGE_POOL = new Dictionary<string, List<MessageInfo>>();//离线消息池8 Q0 b7 R1 m+ N3 S; e% F
  38.         public void ProcessRequest(HttpContext context)
    - E! v5 u' U3 a, [
  39.         {) T& j& y. ?$ k9 E5 `
  40.             //context.Response.ContentType = "text/plain";: J0 a4 A! ?4 G
  41.             //context.Response.Write("Hello World");
    2 t% b" i) j" Q- b
  42.             if (context.IsWebSocketRequest)
    - r* v  @5 L& X) x# w
  43.             {
    % `( v' d! n" Q9 R& f/ s
  44.                 context.AcceptWebSocketRequest(ProcessChat);
      t7 u3 K( O% i  X# j
  45.             } 1 |- Q# ]# v2 m8 Y0 z( C+ ]# }
  46.         }
    * Q( U( A3 w: ?* ]7 J

  47. 0 `& B3 g3 J1 h. i& B% Q
  48.         private async Task ProcessChat(AspNetWebSocketContext context)! E0 I. ^6 E5 q$ Z$ @- i
  49.         {2 d- o4 i; z2 s+ B" [* O
  50.             WebSocket socket = context.WebSocket;
    : d/ @3 Y- f+ p, c9 y" {, i8 Q
  51.             string user = context.QueryString["user"].ToString();
    * @' M' B% h  A* Z. p5 B

  52. 5 b9 R0 B7 X/ H2 G9 Q  j
  53.             try
    ! U. X! Y4 }4 J2 T
  54.             {( e% X' f3 p3 `% [" o
  55.                 #region 用户添加连接池, d- V# R2 x( U
  56.                 //第一次open时,添加到连接池中
    7 G* R* D% ]3 B; z+ Z% _
  57.                 if (!CONNECT_POOL.ContainsKey(user))- e' Z2 k% t4 z. d$ w2 E
  58.                     CONNECT_POOL.Add(user, socket);//不存在,添加  x% Q! D  e& X+ d2 w( e
  59.                 else' W9 B" C0 ^) V8 T# q3 I- n$ _2 g
  60.                     if (socket != CONNECT_POOL[user])//当前对象不一致,更新2 Z) S( R4 ?4 Q! G
  61.                         CONNECT_POOL[user] = socket;
    1 m( x5 p8 Y: z1 t" W6 S" g; s# h
  62.                 #endregion
    4 i: Y- e# ~0 l% N- W) t
  63. ; E& Y9 S' W  P3 m* B
  64.                 #region 离线消息处理
    : P8 n" z2 I; _% Q8 c
  65.                 if (MESSAGE_POOL.ContainsKey(user))
    2 a7 @4 S+ Q+ H7 S/ x
  66.                 {
    , ~6 _. V# L9 Z
  67.                     List<MessageInfo> msgs = MESSAGE_POOL[user];2 u! x' \% l7 u5 G9 d$ n
  68.                     foreach (MessageInfo item in msgs)
    ! j" m* p$ K2 L
  69.                     {" Z6 a* }; [+ u/ c& F. ^
  70.                         await socket.SendAsync(item.MsgContent, WebSocketMessageType.Text, true, CancellationToken.None);1 v, }# Q" i2 f* u3 x9 V
  71.                     }
    : B4 A* \, i0 G1 g% y
  72.                     MESSAGE_POOL.Remove(user);//移除离线消息' ^4 S1 i" S. s, B( z
  73.                 }7 t( c' k: f$ m4 o
  74.                 #endregion
    + s! y% k6 P. W" x  Z" j! t7 D
  75. , G6 l0 |6 H. @5 ?% }3 w
  76.                 string descUser = string.Empty;//目的用户
    - W' a: l6 i$ e$ L: S! g
  77.                 while (true)
    : m" |/ S7 s6 O2 N/ C4 \
  78.                 {; w6 O3 B$ l# _
  79.                     if (socket.State == WebSocketState.Open)
    + C& S  N5 z: ~) d; l
  80.                     {( r, n, |1 m* I9 T! f
  81.                         ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[2048]);6 n, R  @3 [0 T% X* U( s4 P+ F$ ?
  82.                         WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None);6 J7 L2 L8 K+ n+ g+ e$ B

  83. 6 j9 q: U9 f8 b  F; X! b
  84.                         #region 消息处理(字符截取、消息转发)
    . W# `6 g9 A2 z0 w
  85.                         try0 t3 y5 X. y1 a  y1 Q% ]
  86.                         {1 c7 _; I; o( p
  87.                             #region 关闭Socket处理,删除连接池
    7 [* X' x1 X3 A5 ~6 X! U) u. M
  88.                             if (socket.State != WebSocketState.Open)//连接关闭
    0 {) p4 K5 X  Q! w
  89.                             {
    . T! I3 Y" j  _# ]  ^
  90.                                 if (CONNECT_POOL.ContainsKey(user)) CONNECT_POOL.Remove(user);//删除连接池8 X# B1 c( f" Q) E" c  Q# ]) F% ?
  91.                                 break;& s3 A1 t. I6 u* B
  92.                             }/ ~( V  G7 Z* ~) H% j
  93.                             #endregion
    , T1 x/ c  l3 w* i  d, u6 j0 L
  94. 9 L3 o. Z, _2 z6 d+ n4 s$ o; z
  95.                             string userMsg = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);//发送过来的消息
    . t& z! o, L2 T5 x
  96.                             string[] msgList = userMsg.Split('|');* y8 z0 P9 O2 c+ j5 V, V5 P
  97.                             if (msgList.Length == 2)
    7 A( g- y" k8 H9 N8 ?3 f
  98.                             {& Y! u7 }0 ~: S$ B/ E* E' j
  99.                                 if (msgList[0].Trim().Length > 0)
    " D8 S. c( \/ O) ?" s3 E; J
  100.                                     descUser = msgList[0].Trim();//记录消息目的用户6 B+ d8 E! S  c/ U! n
  101.                                 buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(msgList[1]));
    $ O# i. h9 [( O" l  o( [
  102.                             }5 P' B  }4 T6 m3 u3 r
  103.                             else- P: Q$ @- {7 k% o5 F/ [
  104.                                 buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(userMsg));* W1 k# i/ ]' l' k  M; `
  105. : C8 \, P3 D! M$ n  d3 \6 l( d
  106.                             if (CONNECT_POOL.ContainsKey(descUser))//判断客户端是否在线
    . w/ Y5 c) J+ O
  107.                             {
    0 w* Q4 y! i2 O' X6 i. I
  108.                                 WebSocket destSocket = CONNECT_POOL[descUser];//目的客户端
    : `8 z5 Y0 \: M, r
  109.                                 if (destSocket != null && destSocket.State == WebSocketState.Open)
    ) W! b2 i7 s8 X* S
  110.                                     await destSocket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
    $ T# U3 E5 `' ?& a$ l  S
  111.                             }
    ' B9 C. W* n' ?) Y4 n0 @
  112.                             else
    ; ]' S$ C# t4 W3 V. j9 u4 B% f
  113.                             {
    5 }' u3 P5 p2 O2 Q& Y2 g, H8 v
  114.                                 Task.Run(() =>
    , a  J$ b0 c1 C, i" Z/ [
  115.                                 {
    5 p. |0 p! t# l
  116.                                     if (!MESSAGE_POOL.ContainsKey(descUser))//将用户添加至离线消息池中
    1 C. \, b' }- O2 ^( N  |, m
  117.                                         MESSAGE_POOL.Add(descUser, new List<MessageInfo>());! y/ m7 f: j& O; _- @, V- W
  118.                                     MESSAGE_POOL[descUser].Add(new MessageInfo(DateTime.Now, buffer));//添加离线消息6 @0 \# a" Y) J8 E" f$ F
  119.                                 });
    8 S2 D2 @" r# }2 G+ f1 c/ L
  120.                             }
    ; O) [1 h1 M! m; v; X
  121.                         }0 F2 u# g. `" F
  122.                         catch (Exception exs). D# e# H3 _9 s. G: N
  123.                         {2 f; K9 b" ^; \3 }4 y4 C& \# n
  124.                             //消息转发异常处理,本次消息忽略 继续监听接下来的消息+ S. m# o! }+ d& o! q% [, V$ y
  125.                         }
    0 e* L$ U3 _1 N. c" \! y
  126.                         #endregion
    & A- g+ j+ k0 Y6 F, O$ U4 T
  127.                     }
    0 W; X1 P9 T4 @/ d; N6 }
  128.                     else
    % R% q3 i9 G" c1 |0 _
  129.                     {% D+ `5 X. N9 X4 l% \. {( M
  130.                         break;+ x& }% P/ G& Y; }" ]
  131.                     }
    , P) H& A3 L! R* `1 H) h
  132.                 }//while end; g6 v3 G+ e0 H/ S
  133.             }
    2 v' z4 m& ]9 q3 Q
  134.             catch (Exception ex)5 e+ j' g0 B7 u5 o
  135.             {/ z' x+ _! w) q: b( p2 |
  136.                 //整体异常处理
    " c2 N) F7 \4 K3 K5 U
  137.                 if (CONNECT_POOL.ContainsKey(user)) CONNECT_POOL.Remove(user);: B1 F7 a3 ?: a! s; o/ i
  138.             }
    5 k9 o: f& G7 t5 |2 q
  139.         }
      Z' K5 m0 e$ Y; T9 t( @! W
  140. / T& I& Y1 ^2 m" |

  141. ) X  t/ U, H. F( ]* R$ L& I7 @
  142.         public bool IsReusable
    4 `% ?* a  ?7 N0 B. v9 F; I$ ?
  143.         {) @3 q( }! f' |% S
  144.             get' Q) T; b4 P, o4 h8 X& A
  145.             {4 ?/ U9 F# g7 m8 E& ]  j
  146.                 return false;( ^! ~5 r$ q4 V% Y4 G
  147.             }* Q2 {5 n% w5 W
  148.         }
    3 x2 b* I2 H% g) g0 L+ K
  149.     }- P) s, Z3 @& A( }% [  @2 E+ s4 F, y
  150. }
复制代码
4.运行看是否报错,若没错将我们的服务器网站发布到IIS(支持WebSocket的IIS上,win7的系统时不可以的)上
点击“生成”->"发布........",以文件系统的方式发布,目标位置为我们创建的IIS网站对应的物理路径

% S: G$ A4 Y: u" T( T, h
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享分享 支持支持 反对反对
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

GMT+8, 2024-5-19 01:36 , Processed in 0.114329 second(s), 22 queries .

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