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

QQ登录

只需一步,快速开始

 找回密码
 立即注册

QQ登录

只需一步,快速开始

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

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

[复制链接]
跳转到指定楼层
楼主
发表于 2018-11-7 00:43:37 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
服务器端代码编写
1.新建一个ASP.net Web MVC5项目
0 o" Y4 I. W" i0 ?  I# }3 W- K' s. e4 e, t
2.新建一个“一般处理程序”
3.Handler1.ashx代码如下:
  1. using System;
    9 e8 a: t& q" Y
  2. using System.Collections.Generic;
    2 O* Q9 [1 i9 a6 h3 U% T
  3. using System.Linq;7 z3 f" v4 j! W$ `, J
  4. using System.Net.WebSockets;
    ) H% s. y) W/ i$ h! j9 S9 ]  g
  5. using System.Text;
    4 _4 h/ d$ i4 }* f& g4 W4 [5 L
  6. using System.Threading;9 Z4 Y7 p5 m0 f8 i
  7. using System.Threading.Tasks;
    3 v, F6 P9 j( X, b3 J% N
  8. using System.Web;9 m! B1 n7 q5 Y+ A2 M. T, Q9 N
  9. using System.Web.WebSockets;% B3 P5 v5 A; \- h* p
  10. 6 A! c2 i; b' ~" S

  11. / E' i. \8 p9 t+ L
  12. namespace WebApplicationWebsocketHandler5 _% _* S3 }2 m# u
  13. {1 \; W0 l) p7 ?% ]8 M) J
  14.     /// <summary># Y- [$ K2 m8 z3 L  v/ r2 X
  15.     /// 离线消息" k" O) o, k' @0 N' P- f5 C6 c4 z
  16.     /// </summary>8 C6 D' B$ a  Q& U
  17.     public class MessageInfo
    ! b$ ^- o8 b$ E  U, w5 \
  18.     {# B0 h, R) J5 I0 K! j( n5 F, N
  19.         public MessageInfo(DateTime _MsgTime, ArraySegment<byte> _MsgContent)
    1 H  x6 S- W# G, H* x0 Y, F- |
  20.         {) T% S$ y% G9 r' U5 n2 o; Y) H
  21.             MsgTime = _MsgTime;6 n' D# |& k  H  V9 J4 f# B* L
  22.             MsgContent = _MsgContent;+ k$ y; X) k0 `
  23.         }+ e% q8 k0 I- f! J5 m
  24.         public DateTime MsgTime { get; set; }* [  V/ G$ I& r, J
  25.         public ArraySegment<byte> MsgContent { get; set; }( j9 p: b  X$ i! {3 n
  26.     }
    % h$ u; r$ F2 X) Z  @1 N
  27. ! d1 B& \, q/ Q- F; G
  28. $ B" e& m; |9 L/ A2 m

  29. / Y8 w: v0 `2 d* S9 J0 t

  30. ( C. i$ ?, c* @5 d- U+ _2 n+ j1 Q
  31.     /// <summary>& z: V; C( V% p) k9 X) ?
  32.     /// Handler1 的摘要说明/ T0 C" P. X9 a
  33.     /// </summary>
    $ ~% R. e( C4 Y( y( l" V! D- _
  34.     public class Handler1 : IHttpHandler
    ! P2 \' G9 u0 r! R$ E" s/ J
  35.     {$ v& y8 u4 Y$ v' ~8 |& t- U
  36.         private static Dictionary<string, WebSocket> CONNECT_POOL = new Dictionary<string, WebSocket>();//用户连接池
      `8 j# n1 m* k- A. U1 a  Z
  37.         private static Dictionary<string, List<MessageInfo>> MESSAGE_POOL = new Dictionary<string, List<MessageInfo>>();//离线消息池
    , w0 I4 t( o4 g
  38.         public void ProcessRequest(HttpContext context), s, Z( Q7 b6 y+ u5 u3 K; i2 p
  39.         {
    # l) f% J6 U0 N9 \
  40.             //context.Response.ContentType = "text/plain";; A2 o1 E  t6 o& L+ q
  41.             //context.Response.Write("Hello World");4 d0 ?& {4 Y5 o' e
  42.             if (context.IsWebSocketRequest)
    - w# ~; h& z5 j9 u9 ]2 T
  43.             {
    # k. `% o4 [$ a8 O' P5 ?8 E5 y! z
  44.                 context.AcceptWebSocketRequest(ProcessChat);; B4 o3 Z; G6 J4 W' U5 ^
  45.             } 8 I# Z1 t' J. `$ G% L' U0 w: {
  46.         }% |4 Q% o7 F! [# h! u
  47. 9 C  Q' a4 l% n0 @
  48.         private async Task ProcessChat(AspNetWebSocketContext context)
    3 u; _$ v% P1 S& ]% W  N6 r
  49.         {3 x9 E3 f0 P* j8 o1 w% I
  50.             WebSocket socket = context.WebSocket;# ^9 M  i9 [  V5 _3 K- z/ P1 |2 ?
  51.             string user = context.QueryString["user"].ToString();! C0 ]' X. z! T1 [  j- [  l0 R( {
  52. - W! n5 r) ~+ t! e4 z+ Q
  53.             try& U4 v3 N4 U) G! H3 s& Y; R1 X5 a$ Z
  54.             {
    # a, G: B! R7 f. k
  55.                 #region 用户添加连接池& y  C5 k2 p3 e9 C. K; n3 y, Q
  56.                 //第一次open时,添加到连接池中
    2 H- S5 \( [9 {9 v
  57.                 if (!CONNECT_POOL.ContainsKey(user))
    : W# D7 s! h) _9 E
  58.                     CONNECT_POOL.Add(user, socket);//不存在,添加
    7 `8 k9 @; Y4 I, y
  59.                 else' Q3 Z5 [" A+ r$ ^# u
  60.                     if (socket != CONNECT_POOL[user])//当前对象不一致,更新
    4 _) k5 h9 [+ N" e/ r% e8 L
  61.                         CONNECT_POOL[user] = socket;
    + O( G: E6 l3 t2 p* N
  62.                 #endregion
    ; ~% s! D9 m. P% m* Q" j  g; r

  63. & d' N+ v4 v$ G' }4 m
  64.                 #region 离线消息处理
    & e- W; c0 N6 K# m* ^
  65.                 if (MESSAGE_POOL.ContainsKey(user))
    # h. E$ H& ^6 }# Z1 d1 j
  66.                 {/ @  a4 c) B( s& \' ?: [3 r1 d
  67.                     List<MessageInfo> msgs = MESSAGE_POOL[user];
    # U! V% N" N" e/ I2 k
  68.                     foreach (MessageInfo item in msgs)
    2 ^  t  p  `$ l2 h
  69.                     {, @8 g# ~3 K% t; P6 }, m! \- j( z; |
  70.                         await socket.SendAsync(item.MsgContent, WebSocketMessageType.Text, true, CancellationToken.None);
    9 y) i1 r5 Y! O4 s0 U
  71.                     }4 T+ @7 U4 h0 i8 w
  72.                     MESSAGE_POOL.Remove(user);//移除离线消息8 i3 A8 T- Y5 L$ ]2 |
  73.                 }( I( i( n2 ], l/ a  F* B& j
  74.                 #endregion
    : Q, U, _3 d! M4 ?! y1 k
  75. $ E/ |* H+ h4 t6 y, J% Y
  76.                 string descUser = string.Empty;//目的用户' R6 k6 A7 }& C  B
  77.                 while (true)
    & i6 q4 Z3 s$ ^% n
  78.                 {! I$ X/ J1 x" h9 G, l: T5 C
  79.                     if (socket.State == WebSocketState.Open)
    0 j* I; |: i$ J3 R/ a
  80.                     {2 t! L4 ]( H5 Y/ c" _7 O: r- n
  81.                         ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[2048]);5 R4 G$ K3 s" ^% ?* N4 i1 a7 e# ]' Z
  82.                         WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None);1 a1 ]- e0 b2 a4 y. L2 H

  83. , J( }' V. }, p+ J4 v0 d7 `7 e2 j4 N
  84.                         #region 消息处理(字符截取、消息转发)4 ?& V, b: M& r1 y  J  {# U
  85.                         try& Q% H3 m9 Y0 b/ a4 M
  86.                         {7 x1 B: R* f9 v/ I0 d& B
  87.                             #region 关闭Socket处理,删除连接池$ m. i0 R3 Y7 ^  C( f- F
  88.                             if (socket.State != WebSocketState.Open)//连接关闭
    $ r6 r. H( K1 G; u
  89.                             {
    & R- V" V6 e. V2 K
  90.                                 if (CONNECT_POOL.ContainsKey(user)) CONNECT_POOL.Remove(user);//删除连接池' A' T% n* Z/ Y) x9 F
  91.                                 break;
    " @3 Y7 e. E6 S  K- }  g2 H# P, C
  92.                             }
    $ Y  Z4 u8 P- k* m( P) d
  93.                             #endregion4 K' e, [. m# S/ O& w

  94. / ^& l3 f! B& k" o7 |
  95.                             string userMsg = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);//发送过来的消息7 \& x% }6 g$ W
  96.                             string[] msgList = userMsg.Split('|');
    5 W( x7 Y8 d2 j! x8 }4 f
  97.                             if (msgList.Length == 2)% C3 \3 y5 s1 I
  98.                             {* E/ G2 E- I3 [
  99.                                 if (msgList[0].Trim().Length > 0)6 \  H8 Z( |6 K0 r
  100.                                     descUser = msgList[0].Trim();//记录消息目的用户
    ! D$ {* g) y# ~. \
  101.                                 buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(msgList[1]));% x1 }# f' b, f+ s
  102.                             }; S% b7 p7 ^  @, q# B" t
  103.                             else1 Z/ Q2 Z3 E" K3 {
  104.                                 buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(userMsg));4 X- s+ r6 x1 B! {
  105. # N: A, C/ ^2 o
  106.                             if (CONNECT_POOL.ContainsKey(descUser))//判断客户端是否在线0 F* l, c' U/ C! ~2 v; r
  107.                             {
    " F) h. f( ^# M3 o* J  r$ h
  108.                                 WebSocket destSocket = CONNECT_POOL[descUser];//目的客户端
    7 }9 R. K. O; G' J
  109.                                 if (destSocket != null && destSocket.State == WebSocketState.Open)6 C8 O" ]5 }& R8 L
  110.                                     await destSocket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
    / h3 b7 U+ X# @4 X
  111.                             }* q& C0 H5 I( ~0 Y  F' x+ ?
  112.                             else- U, r' ?: `5 J7 w% G  r
  113.                             {
    " H" i; e/ ~3 f- x
  114.                                 Task.Run(() =>! p9 Y/ W4 w7 v* D3 O
  115.                                 {6 ]; P/ C0 \- ?, U
  116.                                     if (!MESSAGE_POOL.ContainsKey(descUser))//将用户添加至离线消息池中. f  }! J" q7 A) W% p" f# F8 M
  117.                                         MESSAGE_POOL.Add(descUser, new List<MessageInfo>());) Q9 d+ l' Z  n- r  ^. x
  118.                                     MESSAGE_POOL[descUser].Add(new MessageInfo(DateTime.Now, buffer));//添加离线消息
    " P) C; i$ N1 k8 k& Q
  119.                                 });
    $ d, H2 Y3 ?' R" @' G% }
  120.                             }
    ( W: q0 ]; y7 K' {4 x3 z# x& |
  121.                         }
    ; d" N/ P$ q* Y3 X: ^
  122.                         catch (Exception exs)' \$ ]. e* u  E  Z7 I- `
  123.                         {
    . o$ a1 \7 R% y% ]- a
  124.                             //消息转发异常处理,本次消息忽略 继续监听接下来的消息
    % K2 \9 K. G$ i  @
  125.                         }* t- Y$ d# f1 _3 A
  126.                         #endregion
    ( C# f8 s9 S# ]: m1 @$ C& h
  127.                     }
    ; `& c+ i$ T  V& c3 ?( N9 O4 B
  128.                     else
    ! N: V5 ?% N+ r" g4 k2 h- J
  129.                     {
    & u" D! T2 u. Y  h& A
  130.                         break;: Z5 w+ P& k! E5 K
  131.                     }1 o3 t4 E& \, e( ?, B
  132.                 }//while end2 E# c8 y% B2 S
  133.             }, K7 G1 X8 Z/ U9 t. t! q
  134.             catch (Exception ex)
    " s6 E, ~6 A* z  o  R9 w
  135.             {
    * l! {& k/ q. L. f$ K$ Y
  136.                 //整体异常处理7 y$ I) |/ p- y8 o0 X3 D8 D( x* y+ K
  137.                 if (CONNECT_POOL.ContainsKey(user)) CONNECT_POOL.Remove(user);
    - ^6 r5 M/ O( H0 W6 b0 |# S4 H
  138.             }1 R1 ~5 b# `# r; s, I6 K
  139.         }
    ' L, A! t3 H3 {9 P# `0 w( Y$ m

  140. ) g; ^& O. z. R( `

  141. 3 `1 x4 p6 M0 t
  142.         public bool IsReusable
    ; |( u6 Q( z2 }% g: b
  143.         {+ a0 N: ^3 g$ P2 l: Z+ _' i
  144.             get. s; C' d3 v, o5 r( p
  145.             {' e' C, U  j: c5 s7 n! u- V! D
  146.                 return false;
    5 Y" ]5 q# t& f/ D$ X
  147.             }# I! I! V, S* P( m1 z& c* [
  148.         }
      W5 J5 r- y2 Y  w3 j
  149.     }, B1 G9 T  |$ Y4 |
  150. }
复制代码
4.运行看是否报错,若没错将我们的服务器网站发布到IIS(支持WebSocket的IIS上,win7的系统时不可以的)上
点击“生成”->"发布........",以文件系统的方式发布,目标位置为我们创建的IIS网站对应的物理路径
9 m( Y2 @2 m% Q
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享分享 支持支持 反对反对
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

GMT+8, 2024-4-28 23:36 , Processed in 0.133658 second(s), 24 queries .

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