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

QQ登录

只需一步,快速开始

 找回密码
 立即注册

QQ登录

只需一步,快速开始

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

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

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

+ }/ v& l* m- o9 ], _  ]
2.新建一个“一般处理程序”
3.Handler1.ashx代码如下:
  1. using System;
    ) Q3 \9 N# w5 V7 t9 b0 H
  2. using System.Collections.Generic;- Z7 }: c! p  Y8 N% h# Q% U
  3. using System.Linq;
    8 z! ~0 F: d; V0 V" _" m" D6 f0 h
  4. using System.Net.WebSockets;
    1 v% b7 A3 M  p! Z- ^
  5. using System.Text;
    1 O+ n4 l& B, k& H7 |' m
  6. using System.Threading;+ }6 s8 w3 f6 T, e
  7. using System.Threading.Tasks;
    : z+ f# L4 X* N8 ], A( b, [
  8. using System.Web;$ l& a4 O2 D2 e4 k
  9. using System.Web.WebSockets;+ C; s& M& c$ p. P7 }5 Y
  10. 7 z! _  L8 ?6 l5 X9 [* V

  11.   H/ D5 p3 {8 d9 Z2 x
  12. namespace WebApplicationWebsocketHandler0 ^; j! a# w' i; r. {$ e6 N
  13. {
    ( s, T! ~( g3 f5 M
  14.     /// <summary>% q* }0 h5 \* y$ w  w' `
  15.     /// 离线消息
      s  B# Y* g9 }5 w  ~% [
  16.     /// </summary>  c' O, [. T- h: p. P
  17.     public class MessageInfo3 |6 A1 a5 d5 ]3 m. b: y* ]
  18.     {+ [: c4 p5 }  Z5 ?; G% N
  19.         public MessageInfo(DateTime _MsgTime, ArraySegment<byte> _MsgContent)" t% \% {8 I- |/ y3 f# f9 J* E4 f2 ~4 [
  20.         {4 N& |1 R* z2 R+ @" ^) b6 z
  21.             MsgTime = _MsgTime;9 L8 o6 C3 l3 c5 }" l4 \
  22.             MsgContent = _MsgContent;
    6 s( N6 r7 y, U; ]; z$ h
  23.         }9 N4 N2 `0 z# e) x/ p! R
  24.         public DateTime MsgTime { get; set; }- U9 `; ^9 y! m/ `" l# b$ e
  25.         public ArraySegment<byte> MsgContent { get; set; }7 l  d" Y" P* W" x
  26.     }
    : m. j" J- @  U/ z( w" J8 D

  27. 3 I" z) F3 b4 M+ S) G! t

  28. ( ]  R+ F, {/ ~; G9 D; Y
  29.   W7 U, U% @9 J

  30. 9 M* M' W# G/ V: Z+ j7 ]9 [8 O+ G
  31.     /// <summary>
    $ a2 j/ i5 v$ X) S* g. w
  32.     /// Handler1 的摘要说明
    6 @0 K- {& T4 v) G6 f. z
  33.     /// </summary>
    2 R* a9 f2 [  \3 w
  34.     public class Handler1 : IHttpHandler
    $ {6 _# T1 `5 B2 h! E
  35.     {& K" C4 f# ?! P
  36.         private static Dictionary<string, WebSocket> CONNECT_POOL = new Dictionary<string, WebSocket>();//用户连接池$ y2 ^: E+ i, x3 d
  37.         private static Dictionary<string, List<MessageInfo>> MESSAGE_POOL = new Dictionary<string, List<MessageInfo>>();//离线消息池
    % U. q8 t7 m( z
  38.         public void ProcessRequest(HttpContext context)0 _2 k$ p: {  q) I  S
  39.         {- \, }& `& Z3 d: ?5 r# F9 [/ `
  40.             //context.Response.ContentType = "text/plain";$ ^% j, i% X. k* F2 [
  41.             //context.Response.Write("Hello World");! Y5 o) f' w0 q% j" V! `
  42.             if (context.IsWebSocketRequest)+ e& s9 {$ R  X& f  h6 w8 f7 |7 b
  43.             {
    1 N9 G' ?& F: ]  U7 I! Z" O
  44.                 context.AcceptWebSocketRequest(ProcessChat);/ @& G" l1 f7 b; l6 y
  45.             }
    * f% W! d" N. F/ u
  46.         }+ T8 }* y$ F& h" H' ^+ j, {' i! L

  47. 3 z3 o; C1 |' m$ e! Z
  48.         private async Task ProcessChat(AspNetWebSocketContext context)
    3 u& g% l* Z7 T3 d
  49.         {
    + s  u0 j# R% z* S6 E% b' G/ L8 \
  50.             WebSocket socket = context.WebSocket;; _  Y, J( A6 M' M7 Q
  51.             string user = context.QueryString["user"].ToString();
    ; h& j9 A3 a9 q/ M% W( I; [0 q

  52. + R  |# z7 K) n" V. ]7 ?2 ^
  53.             try
    $ c) s  @8 i3 v# a" T& u3 S
  54.             {6 C3 y7 B- J/ ]+ b* r- ]- _$ p
  55.                 #region 用户添加连接池
    & i- C1 _. {3 H
  56.                 //第一次open时,添加到连接池中
    3 N( o, J# P5 F; S) Y8 O2 B
  57.                 if (!CONNECT_POOL.ContainsKey(user))
    " J' B; f, H; t) z7 T/ x, |7 v
  58.                     CONNECT_POOL.Add(user, socket);//不存在,添加+ ~: `( {$ D1 T4 R% v* ?
  59.                 else! P' y! R( w0 n3 A0 n, j  Y: Y
  60.                     if (socket != CONNECT_POOL[user])//当前对象不一致,更新6 H  T  y' N! v/ _, G
  61.                         CONNECT_POOL[user] = socket;! ?, u+ ^* ?. @$ a, y" M9 h" [) o
  62.                 #endregion5 S& v, ~2 F7 M0 Y' x! b

  63. , d. M4 M- R; o; K5 U
  64.                 #region 离线消息处理3 C) `" S5 u4 X' v4 k* G
  65.                 if (MESSAGE_POOL.ContainsKey(user))% ]7 {9 r1 ?' r# ?9 H8 j5 e
  66.                 {2 c) D. [6 G, n1 `( `! u) Z
  67.                     List<MessageInfo> msgs = MESSAGE_POOL[user];0 j& L6 Y# W8 j% x8 @; ]1 g
  68.                     foreach (MessageInfo item in msgs)
    . y7 \0 V" O# H8 ]3 W
  69.                     {
    * K' s' h$ ~: H6 W, p) l
  70.                         await socket.SendAsync(item.MsgContent, WebSocketMessageType.Text, true, CancellationToken.None);2 R: q6 V7 m: J5 g7 T+ a. R* d
  71.                     }
    ! F$ W1 \. M, ~3 ]' @
  72.                     MESSAGE_POOL.Remove(user);//移除离线消息# h9 A3 |5 o- |7 |2 n
  73.                 }
      ?* S% _6 P7 k, M) c
  74.                 #endregion/ e8 I( n; Q) A0 J

  75. " t% D: a) B6 N! ]8 W( ]
  76.                 string descUser = string.Empty;//目的用户# H! S6 Q& G6 u
  77.                 while (true)8 H  N, b+ O( |2 h/ i
  78.                 {
    7 T0 v# S3 j# Q% k/ D( c
  79.                     if (socket.State == WebSocketState.Open)' b- k9 I, X6 y0 z5 b
  80.                     {1 H" ~6 r$ _: o$ \* W, y+ L3 {
  81.                         ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[2048]);0 c' N$ `$ b4 C
  82.                         WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None);! `% l" Y: i2 F! g$ D# x

  83. % |$ j3 s! ~( \1 m6 n/ s
  84.                         #region 消息处理(字符截取、消息转发)+ o6 o9 p  t) r5 @6 G% I0 }
  85.                         try
      b, v/ z. k. s% L. t$ B6 W
  86.                         {- ~: \6 T6 l5 J. Y9 Z$ c) N5 P# n
  87.                             #region 关闭Socket处理,删除连接池
    % T, q0 }, U- |7 k) e1 s
  88.                             if (socket.State != WebSocketState.Open)//连接关闭
    " G: v, q; Q' q; g) w$ q  P, C
  89.                             {- V9 v- l& ^  B2 i
  90.                                 if (CONNECT_POOL.ContainsKey(user)) CONNECT_POOL.Remove(user);//删除连接池- ~' z$ R2 {" M3 |4 y8 R2 `
  91.                                 break;, H& x3 O) O1 g9 @& I
  92.                             }$ h$ `# F" o, w  Y" p) e# c* E( e
  93.                             #endregion( Y& F: q+ N( W, T  j; u

  94. % t+ z9 M6 j5 z1 ~  M& e
  95.                             string userMsg = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);//发送过来的消息3 l0 O, a6 S9 u7 q! H6 |1 H
  96.                             string[] msgList = userMsg.Split('|');3 ^' ]+ z9 e: _: v  s1 {
  97.                             if (msgList.Length == 2)2 R" h) l  e6 r
  98.                             {6 c) f. l3 V& N* I
  99.                                 if (msgList[0].Trim().Length > 0)
    4 s0 r9 P1 W1 d+ u; h
  100.                                     descUser = msgList[0].Trim();//记录消息目的用户+ }- `8 a, A' E+ O) b5 @+ e8 B
  101.                                 buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(msgList[1]));
    + ~" `1 U3 \  R2 I2 F
  102.                             }
    9 ]4 |" V# x, ]5 x9 F  R
  103.                             else
    $ Z- l: h; s+ v6 n1 ]0 K: T' d. G
  104.                                 buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(userMsg));
    / m, H6 }8 Y6 B- Y

  105. ) Q$ U0 x+ _& g2 w
  106.                             if (CONNECT_POOL.ContainsKey(descUser))//判断客户端是否在线
    9 Q. c3 ]' E- a; z: g# D: Q
  107.                             {& g. Z/ E+ y7 Q
  108.                                 WebSocket destSocket = CONNECT_POOL[descUser];//目的客户端% {) L) R6 Q# E4 z1 Q  [
  109.                                 if (destSocket != null && destSocket.State == WebSocketState.Open)
    4 T- ?6 M$ m- S# E5 w  m9 c# ?
  110.                                     await destSocket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);' }. I% |# B& k! B
  111.                             }7 V# J1 s& {# ~! N! G
  112.                             else) r6 F+ [8 c; @. |
  113.                             {
    * @9 W& S0 @3 O) [1 l* _8 W1 Q7 k
  114.                                 Task.Run(() =>6 [1 H. z5 w) ?* v9 I5 f: _
  115.                                 {
    8 h9 G9 y3 v- ?) e
  116.                                     if (!MESSAGE_POOL.ContainsKey(descUser))//将用户添加至离线消息池中
    & M, Z4 w: V+ S/ D
  117.                                         MESSAGE_POOL.Add(descUser, new List<MessageInfo>());
    1 V9 t2 r8 O& }1 M8 S: [+ _
  118.                                     MESSAGE_POOL[descUser].Add(new MessageInfo(DateTime.Now, buffer));//添加离线消息! g9 [+ K! z# k: X$ m( V
  119.                                 });
    ; R# f2 k" G* f) C& z+ S
  120.                             }
    ! P) P. \0 \# |7 ^
  121.                         }
    + T/ i) c8 {1 f: n) n
  122.                         catch (Exception exs)2 U9 {+ D/ f! d8 k2 i
  123.                         {
    ; _3 A3 C/ l  D' C6 Y# g
  124.                             //消息转发异常处理,本次消息忽略 继续监听接下来的消息4 M, e; Y  y, K, i9 P3 K, Y$ E) f
  125.                         }) d: o/ }" u9 a& \1 C
  126.                         #endregion# h% l0 y8 e) a7 L3 r) R
  127.                     }, H+ m8 N2 e& P
  128.                     else* d) Q) q6 ~4 n$ @) ^1 r
  129.                     {
    + u- b$ w  t# P3 k/ A
  130.                         break;- y9 [5 {8 B  S3 Z
  131.                     }
    " Y" i6 h, k) t5 K' P
  132.                 }//while end
    4 o/ X' E9 _7 f) W8 q7 c
  133.             }* v3 \, U6 `4 k1 \1 I# _  k
  134.             catch (Exception ex)1 g5 v- U* I' _+ q; e6 h( A
  135.             {+ ^5 G: h6 g! i: \* w+ e
  136.                 //整体异常处理2 Z+ d/ i% N+ U5 f, ]; E0 Z+ |. J
  137.                 if (CONNECT_POOL.ContainsKey(user)) CONNECT_POOL.Remove(user);; N) S  t) I# v6 Y) _# P; f
  138.             }
    , b& F+ K& `; Y/ p
  139.         }6 E5 a1 q0 Z+ K, X) `

  140. ' p$ b8 o* I- w. D
  141. 5 }% J/ ^" T8 p( s0 T5 q
  142.         public bool IsReusable
    5 \7 M! L) W  u7 R# k: O  P9 \
  143.         {5 k) [* E: Y" j; E
  144.             get
    $ E0 u1 p6 r. R$ {# |# B
  145.             {
    ' A: C1 y7 R6 k6 {& S1 I
  146.                 return false;2 q9 c; }5 O& d% j# B
  147.             }1 G. V+ k( r  l9 x5 d, @; u
  148.         }; q. c  i5 q0 [) p% Y* I
  149.     }* K8 P6 H& k; N! C
  150. }
复制代码
4.运行看是否报错,若没错将我们的服务器网站发布到IIS(支持WebSocket的IIS上,win7的系统时不可以的)上
点击“生成”->"发布........",以文件系统的方式发布,目标位置为我们创建的IIS网站对应的物理路径
3 `/ @1 U. s: c" h' O0 i) K
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享分享 支持支持 反对反对
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

GMT+8, 2024-12-22 16:55 , Processed in 0.115109 second(s), 23 queries .

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