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

QQ登录

只需一步,快速开始

 找回密码
 立即注册

QQ登录

只需一步,快速开始

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

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

[复制链接]
跳转到指定楼层
楼主
发表于 2018-11-7 00:43:37 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
服务器端代码编写
1.新建一个ASP.net Web MVC5项目
3 o) d1 @& E: ?* [
2.新建一个“一般处理程序”
3.Handler1.ashx代码如下:
  1. using System;
      B; X, C* Z; r
  2. using System.Collections.Generic;/ `4 U* n& N4 A- H7 e: F& F( S; |
  3. using System.Linq;
    2 e9 Z9 s  ?! d0 o1 R9 D3 F
  4. using System.Net.WebSockets;
    / |, S( f+ _  o) f# v. Z
  5. using System.Text;
    5 ^' w, ?* R3 Q. G, D
  6. using System.Threading;
    ; }9 }& J; z4 m  I
  7. using System.Threading.Tasks;
    2 `3 V. [6 \2 Z5 R  ]$ c
  8. using System.Web;
    * I* J3 f7 h3 y3 O3 \
  9. using System.Web.WebSockets;7 j  {7 m" d7 H7 V% m% R4 ]: I

  10. 0 m/ {4 d8 a, I( L
  11. + `4 `9 c/ ~2 l( z
  12. namespace WebApplicationWebsocketHandler- m/ x8 M0 A; O
  13. {
    ! a7 ^' S2 Z! r9 u: L' C
  14.     /// <summary>  X. N% A3 @4 W( ~% U6 A+ N
  15.     /// 离线消息
    . w5 O8 J7 T% V# B) f
  16.     /// </summary>
    7 u, l% {% L  L: ?9 X
  17.     public class MessageInfo  B6 h1 F( I8 G, R6 W$ c
  18.     {0 a3 S( F3 e  B: b
  19.         public MessageInfo(DateTime _MsgTime, ArraySegment<byte> _MsgContent)+ r$ X- ^) Q5 v+ |: ?/ I3 |  g- S
  20.         {
    / |/ C  k) |/ m* }7 d
  21.             MsgTime = _MsgTime;
    6 U# H# O: W! V. X4 A4 L+ |' s
  22.             MsgContent = _MsgContent;: B' c1 M+ b; x3 h2 y
  23.         }
    . d: X; l5 l; E5 R# g
  24.         public DateTime MsgTime { get; set; }
    - d( J* y' K: B, r3 z8 U4 p
  25.         public ArraySegment<byte> MsgContent { get; set; }
    0 Q9 [8 s  v- q4 `! J2 w
  26.     }
    ) s8 h, m1 v# G* q
  27. 4 G* @  c# Q- b6 V& ?
  28. . n" g6 ~. s# ]) r  K
  29. 9 m/ G8 `5 _$ q

  30. 0 ?/ h# i3 |, K" H
  31.     /// <summary>; j1 f/ @0 p2 W& v" Q! @# m
  32.     /// Handler1 的摘要说明- @6 r% I8 B# B# P# H
  33.     /// </summary>  L  w% {* D7 {
  34.     public class Handler1 : IHttpHandler
    ; j( Q0 ^: a2 g8 K# _7 {
  35.     {9 ?6 z1 P3 y0 D6 u# i7 \" `
  36.         private static Dictionary<string, WebSocket> CONNECT_POOL = new Dictionary<string, WebSocket>();//用户连接池, r& Q2 r' |' X9 o: p" w+ X% N
  37.         private static Dictionary<string, List<MessageInfo>> MESSAGE_POOL = new Dictionary<string, List<MessageInfo>>();//离线消息池
    . h; o: m) @# N$ b! B/ B# b$ B
  38.         public void ProcessRequest(HttpContext context); k- K; Q4 o6 h' N4 x! X
  39.         {$ ~1 `$ S# }. h* n2 r" \
  40.             //context.Response.ContentType = "text/plain";8 c0 {* G2 g- q
  41.             //context.Response.Write("Hello World");
    8 q4 c5 L3 P2 d. o5 l# G
  42.             if (context.IsWebSocketRequest)
    ) V4 ^# {* _  c3 n7 v6 h5 W; U
  43.             {3 a1 k) R8 B" X0 `/ S. y& o2 z9 M* x+ z
  44.                 context.AcceptWebSocketRequest(ProcessChat);
    # A, ~: }8 t7 q3 W
  45.             }
    $ u2 h- i: G+ x% a& V
  46.         }
    , w; |8 j" ?" l9 d

  47. & r: a9 L- n2 N, G; Q, s
  48.         private async Task ProcessChat(AspNetWebSocketContext context)
    ' a0 h  s2 l. w' H
  49.         {8 V6 t. m# B" j+ q7 R! N9 k
  50.             WebSocket socket = context.WebSocket;8 f5 f; V/ P5 g7 S; d
  51.             string user = context.QueryString["user"].ToString();
    ! l, r2 m4 @  B. J/ B" n

  52. 2 h' G. E5 ]& s
  53.             try8 u8 Z  y: u+ I5 ]5 C6 X1 z5 G7 V, C
  54.             {
    " d: j2 y' C4 t2 i/ v0 A  A) v; B
  55.                 #region 用户添加连接池
    2 Y4 m; P1 X, \3 I- c. |. C
  56.                 //第一次open时,添加到连接池中2 l/ d/ c  X; ~# Z8 m; G3 J
  57.                 if (!CONNECT_POOL.ContainsKey(user))
    2 y8 y1 y; E. `
  58.                     CONNECT_POOL.Add(user, socket);//不存在,添加/ S7 B/ X! @6 L' m4 b" B, v
  59.                 else& s# o# W% z' i# w; b! S" a# j1 M
  60.                     if (socket != CONNECT_POOL[user])//当前对象不一致,更新
    ; E* d8 r0 a( M
  61.                         CONNECT_POOL[user] = socket;2 ?2 r6 N' W$ K6 L
  62.                 #endregion  t' c/ l! {$ p

  63. % u7 X3 }- y0 U' j/ F3 Q  Q, i
  64.                 #region 离线消息处理
    6 Q+ m$ t0 u+ N5 D  B
  65.                 if (MESSAGE_POOL.ContainsKey(user))
    3 e( q  t; q+ \, M) S) ?
  66.                 {7 [% ~) N5 r. ^
  67.                     List<MessageInfo> msgs = MESSAGE_POOL[user];
    6 I0 R- t! E6 e  r( ]$ t
  68.                     foreach (MessageInfo item in msgs). a0 p8 m9 J3 x* h" y
  69.                     {
    9 }  O& L. h/ T6 z5 F& m
  70.                         await socket.SendAsync(item.MsgContent, WebSocketMessageType.Text, true, CancellationToken.None);
    4 J; o* R& @& f4 ?! a
  71.                     }
    : A! \9 e2 c! N8 U5 |# A
  72.                     MESSAGE_POOL.Remove(user);//移除离线消息
    - D0 p* m* h* O
  73.                 }8 M( W$ D1 {7 Q! Q! |9 m
  74.                 #endregion+ h' p/ Y: |) L  o

  75. 6 N) |# x' ]# R2 C- M# B" E
  76.                 string descUser = string.Empty;//目的用户
    8 D+ H  X( R  Z; r
  77.                 while (true). S  z4 f- O; ~5 i9 E
  78.                 {
    8 O9 r  C0 S4 [/ ]. G! }8 @
  79.                     if (socket.State == WebSocketState.Open). K1 K  A, C3 {$ m' G! A: m
  80.                     {/ f, F' O) d+ l9 r0 N8 F" F0 T; `
  81.                         ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[2048]);
    0 @2 V: R# x* H, s# S
  82.                         WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None);2 m0 X  ~( p3 q# o* V

  83. 8 _/ S. g, X; ]: w
  84.                         #region 消息处理(字符截取、消息转发)
    7 n1 ]4 X* _) C$ A' X5 Z9 }
  85.                         try
    # o3 y1 m% l, w" J3 G! r6 p
  86.                         {2 B* A" E* s8 A; B' E: j. w
  87.                             #region 关闭Socket处理,删除连接池( G/ I$ p+ c5 K, E
  88.                             if (socket.State != WebSocketState.Open)//连接关闭
    . K# V( R- o* }6 Y# E
  89.                             {+ v2 b. h6 h' J8 o& r2 p- T/ \
  90.                                 if (CONNECT_POOL.ContainsKey(user)) CONNECT_POOL.Remove(user);//删除连接池
    2 m7 B* m) X! R4 X. S% X
  91.                                 break;
    : H* f6 u* |0 q" N+ p6 S) T8 p
  92.                             }3 c: Q& N8 Z- G2 \3 G3 f, k
  93.                             #endregion/ t: U2 O* A* |
  94. ; {( ?/ Q& x# |+ S0 b% g
  95.                             string userMsg = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);//发送过来的消息$ x9 Y+ N: n* G: v, ^9 H5 T6 g
  96.                             string[] msgList = userMsg.Split('|');
    % W9 d  X) T' F3 V
  97.                             if (msgList.Length == 2)
    : b% y* V9 a; Y* L3 E: j
  98.                             {
    / j4 t* G% L& e1 O9 y/ h+ w9 ]
  99.                                 if (msgList[0].Trim().Length > 0)( Z) X( F4 W- u
  100.                                     descUser = msgList[0].Trim();//记录消息目的用户1 h( l+ d# G, y. {
  101.                                 buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(msgList[1]));- e% _2 F7 H0 M) P: P& f
  102.                             }) s& c* X; x! F6 e9 N) F
  103.                             else* n' W, O- G1 T% M4 Y) U) l
  104.                                 buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(userMsg));
    3 G% w* Y* D- u  D+ U8 v6 y8 C. W
  105. 0 g1 k+ \7 P. u4 c2 ]4 I; Q3 Y$ `
  106.                             if (CONNECT_POOL.ContainsKey(descUser))//判断客户端是否在线
    7 W8 L) b: x; }3 y
  107.                             {
    ) b. O1 J# \$ E! I& ^5 C/ i  o
  108.                                 WebSocket destSocket = CONNECT_POOL[descUser];//目的客户端
    " y# J- H8 k7 W5 [1 s
  109.                                 if (destSocket != null && destSocket.State == WebSocketState.Open)
    5 K. q9 p; |1 A$ m8 u/ D! ~
  110.                                     await destSocket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);1 B2 y& l% D6 }9 _7 y( d
  111.                             }
    " I5 C3 Q+ M0 b. o
  112.                             else4 n6 l' E, M0 l% l3 ~
  113.                             {
    6 g% f( g* N$ q6 O0 h
  114.                                 Task.Run(() =>+ Y) H6 e; S4 E/ [
  115.                                 {8 h$ c6 I% o+ A0 ~
  116.                                     if (!MESSAGE_POOL.ContainsKey(descUser))//将用户添加至离线消息池中
    9 C' A; T9 X9 i+ J
  117.                                         MESSAGE_POOL.Add(descUser, new List<MessageInfo>());  v- p) [, f9 S% }5 t
  118.                                     MESSAGE_POOL[descUser].Add(new MessageInfo(DateTime.Now, buffer));//添加离线消息& O! N* C! L7 y
  119.                                 });4 T) A, k, m( H" W1 q9 X1 \
  120.                             }
    ! T  z9 A; x9 e. a
  121.                         }
    6 ~- I: ~, d* ^/ T) {. a
  122.                         catch (Exception exs)7 F' L3 p2 _% B* U
  123.                         {! A3 s3 t. J; z+ g' D* }/ u
  124.                             //消息转发异常处理,本次消息忽略 继续监听接下来的消息
    0 t2 o- I/ T) V6 f( n6 |( t* j  T
  125.                         }, C, y  C$ i. P$ {* Q- P
  126.                         #endregion0 {5 A7 t4 @: v
  127.                     }
    2 K; o- _4 P8 x
  128.                     else. V* V8 ~/ k0 x* p: ~
  129.                     {
    ( s1 q! Z5 p: M) q  F8 k) K! t
  130.                         break;  L) I6 A9 `) ?3 \3 g  |
  131.                     }3 ^9 u0 S8 K: o" b4 }# M4 c
  132.                 }//while end
    : R& W3 J' g; i- x! V
  133.             }- G1 d, X! \. _7 v
  134.             catch (Exception ex)
    & H# R+ |% c' e$ h8 G* ?2 V$ w- i. h, v
  135.             {
    - b0 N- c' [. P8 S+ [$ K8 ^
  136.                 //整体异常处理
    # {7 Z: f7 x6 A, r$ u& g7 W
  137.                 if (CONNECT_POOL.ContainsKey(user)) CONNECT_POOL.Remove(user);
    6 h1 z: G& ]& M  q6 |% o
  138.             }
    9 v* m; ^" b( B# F8 H  u# i  h) y
  139.         }
    5 ^/ Z' u# @( ?# P3 a

  140. * i* k( u# Y; J) }  j* N! l/ U

  141. : }& ^7 i/ u, B. {
  142.         public bool IsReusable
    8 A% y* Y3 l* x# A6 `
  143.         {" e% Y4 v/ R+ S6 k
  144.             get7 y/ y' Y" M0 n+ I% f% P
  145.             {
    / e$ g5 R/ o' E* n
  146.                 return false;. i7 A+ @; v4 L
  147.             }  U1 {% v4 Y  J% f0 {; W( h
  148.         }7 m8 @. ]" J( o# ?" E
  149.     }
    3 Z" d" O7 T; U% n# h1 L
  150. }
复制代码
4.运行看是否报错,若没错将我们的服务器网站发布到IIS(支持WebSocket的IIS上,win7的系统时不可以的)上
点击“生成”->"发布........",以文件系统的方式发布,目标位置为我们创建的IIS网站对应的物理路径

( H4 i5 `4 l( C  }8 [' [" A3 A
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享分享 支持支持 反对反对
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

GMT+8, 2024-12-22 20:56 , Processed in 0.133330 second(s), 23 queries .

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