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

QQ登录

只需一步,快速开始

 找回密码
 立即注册

QQ登录

只需一步,快速开始

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

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

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

# V% w9 _# \7 H* Q; ^# `
2.新建一个“一般处理程序”
3.Handler1.ashx代码如下:
  1. using System;5 P- k1 ]" o0 A* s7 U) u  V8 l9 e) c
  2. using System.Collections.Generic;8 d+ j0 q$ `" b3 d0 z" w
  3. using System.Linq;2 l% I1 ^: Q8 X. e/ Z  ~% q
  4. using System.Net.WebSockets;8 y1 c+ l9 @3 {
  5. using System.Text;
    , p- N/ k( G0 W5 `3 Y
  6. using System.Threading;
    0 A- ?, {) E$ g, Z7 `" S
  7. using System.Threading.Tasks;
    8 R7 P! C2 n( Z0 L; a* r
  8. using System.Web;
    7 G2 c/ K; \/ X+ P
  9. using System.Web.WebSockets;
    $ s2 k% T& Y0 u5 |5 h
  10. ' J" U  f8 S, }7 f8 \: T/ f% M7 H& V

  11.   [* Q. q: `3 ^7 I+ V0 L( [
  12. namespace WebApplicationWebsocketHandler
    ! V" U8 _8 s. g2 F  x6 t% p
  13. {- m2 L' Y. O7 \  P2 X6 J
  14.     /// <summary>
    9 L) R8 [3 k& u& Q9 c% g
  15.     /// 离线消息
    7 O4 r2 R3 q0 U$ V
  16.     /// </summary>/ a7 j2 ~, b" O! i; e5 Q
  17.     public class MessageInfo1 }1 k* F0 J3 z& }) @1 e# m7 z
  18.     {
      y$ p$ f% O. U  r
  19.         public MessageInfo(DateTime _MsgTime, ArraySegment<byte> _MsgContent)
    & y. Q* _. |, b3 L
  20.         {6 {8 v5 ~0 d% ~( x# _6 r8 k
  21.             MsgTime = _MsgTime;2 W7 E( C/ e  Q: ?+ t
  22.             MsgContent = _MsgContent;. [$ y5 ?' J! a: ?, h
  23.         }
    8 _  N7 X- ]; y% p# f; t. X
  24.         public DateTime MsgTime { get; set; }
    5 s) ]! C* s4 i7 E9 k
  25.         public ArraySegment<byte> MsgContent { get; set; }
    " n# h* h7 I$ w! a3 u
  26.     }/ |2 i1 ^, m$ X/ {' E
  27. 4 t" _. s' u& r0 W

  28. 0 i* p1 h9 @; I- p+ ?5 l- i
  29. 6 ~2 h  H/ [5 Z- ^$ p' n
  30. 6 b7 T# h+ r8 a% l7 F
  31.     /// <summary>+ b. G# e% d, g- c( N0 s0 B+ W" d
  32.     /// Handler1 的摘要说明/ I6 R" B4 O% q( G* O% {" E
  33.     /// </summary>, @3 n# R; d- l1 V; G
  34.     public class Handler1 : IHttpHandler
    / F; H9 I* _( S, a. t* u
  35.     {
    ) w7 C+ _; v! F! y
  36.         private static Dictionary<string, WebSocket> CONNECT_POOL = new Dictionary<string, WebSocket>();//用户连接池
    1 A3 K( X+ _7 j6 f- L2 A
  37.         private static Dictionary<string, List<MessageInfo>> MESSAGE_POOL = new Dictionary<string, List<MessageInfo>>();//离线消息池, F* l6 W. ^" Q6 {$ |& G$ V3 r( p9 H: L
  38.         public void ProcessRequest(HttpContext context)
    3 z5 s, ^6 p! R3 V# w' B+ [# I
  39.         {
    * L, ^2 Y3 f4 L6 S. L
  40.             //context.Response.ContentType = "text/plain";! t: U$ V( F! ]8 i
  41.             //context.Response.Write("Hello World");
    , b7 P" M8 l, F/ k& R7 }
  42.             if (context.IsWebSocketRequest)7 y9 k8 i2 m, T7 |* t
  43.             {4 A/ i* T& w. Q" R8 L+ I
  44.                 context.AcceptWebSocketRequest(ProcessChat);
    % r% h) Y# h: `; I5 }; Y
  45.             } 0 c( l2 Y1 o5 {: n& X- o" o
  46.         }4 x( Q/ b" a8 D, P- X

  47. ) `" E: h# @6 X0 D* O6 A
  48.         private async Task ProcessChat(AspNetWebSocketContext context)
    4 t( d5 p. S# m0 L
  49.         {
    ) Y' d5 t: Y# d, k' A
  50.             WebSocket socket = context.WebSocket;0 T/ }! D; j" y* w0 X$ y
  51.             string user = context.QueryString["user"].ToString();5 n' y. `: }+ J  ]
  52. 9 Q5 @9 [4 R, [8 h
  53.             try
    - j6 b6 R. g6 t2 b' I/ Q6 g
  54.             {: [( T+ l) R& p& E, Q/ _
  55.                 #region 用户添加连接池
    " m: w& }  T# c2 j, v- I
  56.                 //第一次open时,添加到连接池中- L' M: @$ B. H" `2 H
  57.                 if (!CONNECT_POOL.ContainsKey(user))
    6 o7 t& W+ d7 l7 T. e* M& Q- {
  58.                     CONNECT_POOL.Add(user, socket);//不存在,添加
      s! t+ b" M; f" S. l! Z
  59.                 else
    . H# q1 }$ H+ v% {# Y6 n
  60.                     if (socket != CONNECT_POOL[user])//当前对象不一致,更新( P0 ^# q) g! }8 ]1 F: u& F2 U
  61.                         CONNECT_POOL[user] = socket;
    ( a# _8 S2 t4 }$ E# F
  62.                 #endregion
    ' a/ d! q4 C1 s
  63. ) H9 w% }9 q' s. W: r: M
  64.                 #region 离线消息处理( I0 I; N, J% N% F! z7 e& b$ A3 \
  65.                 if (MESSAGE_POOL.ContainsKey(user))
    & \7 ]- N( b% p. d+ c9 ?1 c
  66.                 {+ g: o* i3 C2 o/ H. x2 N6 [% l
  67.                     List<MessageInfo> msgs = MESSAGE_POOL[user];  Z/ R! Y3 s' [* r. a1 k2 E
  68.                     foreach (MessageInfo item in msgs)
    % ]3 v+ Y4 i( n: g
  69.                     {  }$ K% e' P. Z; z3 t! ]) {  G" ?
  70.                         await socket.SendAsync(item.MsgContent, WebSocketMessageType.Text, true, CancellationToken.None);
    * \: {4 y; r2 U- ]  B) X: v
  71.                     }; L, w! f- h% T* q
  72.                     MESSAGE_POOL.Remove(user);//移除离线消息0 m7 u7 Z' [6 `3 D7 j
  73.                 }1 t/ n; B" l) J: S) X, h! R; }
  74.                 #endregion1 s  N/ _! ^& m, g

  75. 1 k5 A- u( X4 l: a
  76.                 string descUser = string.Empty;//目的用户6 N- t* S2 r4 _, e3 w( ~
  77.                 while (true)
    5 {4 D$ B& |' J: }3 V0 W" Y/ l
  78.                 {8 [' e' Y  F+ r4 V8 V
  79.                     if (socket.State == WebSocketState.Open)
    . y7 T; G: f; f* {  U$ q; u+ ?  S5 a
  80.                     {/ ]; D% S* h# K3 L) x5 G
  81.                         ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[2048]);8 P7 k, c, q: r% q) M6 N; Y
  82.                         WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None);
    $ Q& X, F/ m9 n" \1 n

  83. ) c) g% P. e  x& _1 N- y
  84.                         #region 消息处理(字符截取、消息转发)8 t7 k4 a' [& b
  85.                         try& A) o! [! u1 N8 w% l$ q
  86.                         {
    7 y7 v) }: c7 I9 w3 h9 [
  87.                             #region 关闭Socket处理,删除连接池
    ' {& ^8 y& `. m
  88.                             if (socket.State != WebSocketState.Open)//连接关闭$ P+ I! W* }8 g# U4 K
  89.                             {/ ?& w1 m4 F" _$ l
  90.                                 if (CONNECT_POOL.ContainsKey(user)) CONNECT_POOL.Remove(user);//删除连接池
    . Q3 W' w: w  d5 V8 b" G3 ]
  91.                                 break;- @" E7 L3 V: ]& |' F2 [: O5 y
  92.                             }
    8 N, T- \- h/ C5 |
  93.                             #endregion, F' `& D6 D- B6 d6 S0 }$ H

  94. ; }6 U6 j* m2 s6 e( ?4 v
  95.                             string userMsg = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);//发送过来的消息$ n' D4 j7 M2 `
  96.                             string[] msgList = userMsg.Split('|');
    6 e; P2 T; l4 p7 Y4 h
  97.                             if (msgList.Length == 2)
      u& ?- u$ k) B0 f
  98.                             {
    3 {) E  N+ K* x" m' l1 ^
  99.                                 if (msgList[0].Trim().Length > 0)5 ]3 L* @. K# h
  100.                                     descUser = msgList[0].Trim();//记录消息目的用户
    ( n! ]# c3 Y8 U5 y, u* z/ l
  101.                                 buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(msgList[1]));3 Z! A0 }7 I4 w3 j& g2 ~7 ~) l
  102.                             }8 }9 K& o. X6 Q! J* v# F9 m" [
  103.                             else
    ) t' A1 r6 B7 U. M3 H
  104.                                 buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(userMsg));
    * a; m9 t$ [" l! Q% W

  105. ' W2 w  j8 J, R' V% B/ u. D" y
  106.                             if (CONNECT_POOL.ContainsKey(descUser))//判断客户端是否在线$ d# T, w) ^- N
  107.                             {/ {8 W8 \3 C! F; T8 N7 w
  108.                                 WebSocket destSocket = CONNECT_POOL[descUser];//目的客户端
    5 L/ ^( ^: p: U& V2 w+ f( n
  109.                                 if (destSocket != null && destSocket.State == WebSocketState.Open)1 A! t: m6 O4 E# Y, M! ^: k
  110.                                     await destSocket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
    # [+ }( n6 [; k$ c5 X
  111.                             }
    ' h4 f# A! e1 z/ n9 X$ V
  112.                             else, w  j- u0 y8 V/ W
  113.                             {4 P: e7 J% G( j
  114.                                 Task.Run(() =>& x7 m  m0 o0 ?8 r
  115.                                 {0 g3 Z6 X1 W+ o7 m
  116.                                     if (!MESSAGE_POOL.ContainsKey(descUser))//将用户添加至离线消息池中
    , |' [$ o5 Q. O, J
  117.                                         MESSAGE_POOL.Add(descUser, new List<MessageInfo>());4 K8 D9 S7 h$ v  O' O# ^
  118.                                     MESSAGE_POOL[descUser].Add(new MessageInfo(DateTime.Now, buffer));//添加离线消息! V6 g* }& `$ S/ V6 ?! g* o; a" F
  119.                                 });
    3 K/ M) E# m( M+ l
  120.                             }
    3 L4 ^" D1 w6 g( u
  121.                         }
    1 X& D9 |5 _# D' r
  122.                         catch (Exception exs)& J) y/ w% ^& q1 }7 c7 B1 u: ?
  123.                         {
    6 x0 T* Z* F+ W1 N  s) E0 D& K
  124.                             //消息转发异常处理,本次消息忽略 继续监听接下来的消息( J1 E# t5 D1 K% V+ }# T3 m$ u
  125.                         }
    ' ?7 y: V* V" w( Z/ d. E! D
  126.                         #endregion
    , ~! i) g* s! X: ^
  127.                     }4 s: s' l1 u* g
  128.                     else
      |# h# L. O9 u  A5 f+ {  n
  129.                     {' k- U7 n$ [* P' d
  130.                         break;6 h9 ]7 k0 i6 Z5 @
  131.                     }) }* o/ v# m$ w& U0 X  N
  132.                 }//while end7 P1 T% E0 j' @/ o+ k, n+ U$ s: e
  133.             }/ Y* x; T2 t: B4 R
  134.             catch (Exception ex)6 b; o5 `2 L1 u) ?  A! I2 ]
  135.             {! C, v  q& r0 j! q: i6 v0 H
  136.                 //整体异常处理
    . F& p4 L/ U+ M! I! z
  137.                 if (CONNECT_POOL.ContainsKey(user)) CONNECT_POOL.Remove(user);6 n/ U3 Q; b, }4 j7 C! ^
  138.             }* J1 S( [& h% J' W9 G/ H# F  s) w! _% ]
  139.         }/ b0 ]: X. J8 p; e1 V2 h

  140. 9 B$ F, c; J) W1 K9 ~' S

  141.   G, O6 V' X7 N* y7 m% A
  142.         public bool IsReusable( q) H8 [8 y! L. \2 e% x6 q
  143.         {1 f6 y# [3 b" {1 R. f0 G2 {$ G5 T
  144.             get, L" j  c3 k5 B' F0 t0 |- u1 _
  145.             {0 b' E- @) G) u
  146.                 return false;) H- q, U: f  _  x. o" N. E
  147.             }
    ) W; Y1 W$ u+ W" [: Z! O
  148.         }; B" u8 S4 D2 t% U: I
  149.     }
    , C2 X( E: B$ F+ Z& ~% Z
  150. }
复制代码
4.运行看是否报错,若没错将我们的服务器网站发布到IIS(支持WebSocket的IIS上,win7的系统时不可以的)上
点击“生成”->"发布........",以文件系统的方式发布,目标位置为我们创建的IIS网站对应的物理路径

0 Q! N! E" L1 Q# @- Z
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享分享 支持支持 反对反对
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

GMT+8, 2024-5-18 23:03 , Processed in 0.117232 second(s), 22 queries .

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