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

QQ登录

只需一步,快速开始

 找回密码
 立即注册

QQ登录

只需一步,快速开始

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

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

[复制链接]
跳转到指定楼层
楼主
发表于 2018-11-7 00:43:37 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
服务器端代码编写
1.新建一个ASP.net Web MVC5项目
; N3 c+ y6 g$ K  t" \
2.新建一个“一般处理程序”
3.Handler1.ashx代码如下:
  1. using System;
    + j( G! M8 B+ m3 t
  2. using System.Collections.Generic;
    4 E  \! }, Y" S' j# i8 M
  3. using System.Linq;/ R7 }  g. d9 z) r3 W9 A' Q9 k
  4. using System.Net.WebSockets;
    * U9 c) Y9 }/ Y% `9 F+ O8 d
  5. using System.Text;
    7 I, U% j- {  M0 E
  6. using System.Threading;
    - T( I" k! I) V( Q( q& w$ p6 @
  7. using System.Threading.Tasks;
    5 t& q: A/ V" Y4 m4 d* S+ |; B
  8. using System.Web;  o0 C( s# ?) _  J
  9. using System.Web.WebSockets;( u, ~2 h( h% ~1 n$ B
  10. 2 v: F% k$ T% F/ g2 o

  11. " u+ p0 o4 }& @" V( ^
  12. namespace WebApplicationWebsocketHandler3 C, P. J3 m6 Y7 e
  13. {, `( M+ L  l4 `
  14.     /// <summary>
    % p4 v  D! J- l0 o- _
  15.     /// 离线消息+ E4 B. o. h- V8 A2 u2 l
  16.     /// </summary>, A# X* r) J/ _
  17.     public class MessageInfo* y5 h0 V  k* V5 A; @
  18.     {  y0 H/ [* E# G) N1 [# A! n
  19.         public MessageInfo(DateTime _MsgTime, ArraySegment<byte> _MsgContent)4 j" r/ }4 T1 p4 `
  20.         {
    ( r  E% c( X9 \4 S$ w% F% n5 ^
  21.             MsgTime = _MsgTime;
    $ W, e0 M) d, b& y3 R$ h+ r& U
  22.             MsgContent = _MsgContent;
    8 k" M( l9 `+ W& [/ ]. A) E& G$ S
  23.         }" Z0 r/ b+ q6 R! P. x# _- M
  24.         public DateTime MsgTime { get; set; }
    ; m0 A0 k. Q6 B, {$ Q
  25.         public ArraySegment<byte> MsgContent { get; set; }& u0 J  G) `1 Y+ @
  26.     }
    4 z: {4 @4 p& n/ N4 y
  27. - |6 ^' l' W9 b, S6 r$ t0 U+ ]
  28. ' L% r' X$ l- Y  D( f: Z1 q. q

  29. ' S- |3 H" |, Z7 c5 G3 I. @

  30. 6 a5 f" H+ |/ C
  31.     /// <summary>8 d0 @4 A; T) F3 N* v# S' i$ s
  32.     /// Handler1 的摘要说明+ \0 x& \2 X9 l
  33.     /// </summary>
    5 p7 l/ T  A* x4 b' y3 u. p
  34.     public class Handler1 : IHttpHandler
    3 A, [$ V: ^) N) V3 Z4 W# h- k4 y
  35.     {& l2 {) M+ g$ L6 ^4 K& f
  36.         private static Dictionary<string, WebSocket> CONNECT_POOL = new Dictionary<string, WebSocket>();//用户连接池  l) P0 C$ V0 q  T% v1 w
  37.         private static Dictionary<string, List<MessageInfo>> MESSAGE_POOL = new Dictionary<string, List<MessageInfo>>();//离线消息池
      Y1 z& b* |% P0 L# Y4 k: a
  38.         public void ProcessRequest(HttpContext context)
    % G% A" L% y$ ]% @, u% K4 o8 X. i8 S
  39.         {) F- E3 _/ \$ a# W- K  K' K
  40.             //context.Response.ContentType = "text/plain";9 r- X& U( [+ q4 H; _( \
  41.             //context.Response.Write("Hello World");( U# U5 a) b2 \* w: F0 U! a- s. V0 p; S
  42.             if (context.IsWebSocketRequest)
    ; X, u" p7 Q( {
  43.             {
    : V5 w' z  f8 Z
  44.                 context.AcceptWebSocketRequest(ProcessChat);! t8 T' z# u) m
  45.             }
    8 S7 R* u0 [6 u- H4 I
  46.         }+ ^( t% j' _$ y  V

  47. - w1 I" V0 V% _
  48.         private async Task ProcessChat(AspNetWebSocketContext context)7 B" n( F2 J, [& c' Q/ h- a
  49.         {7 j# {1 v6 ]: y* B# K- R
  50.             WebSocket socket = context.WebSocket;
    5 q. S9 L+ U% r7 `4 S
  51.             string user = context.QueryString["user"].ToString();
    : ^, T( i6 ^2 U- Q9 B( m7 }
  52. " h$ ~6 ], h' e. C3 l+ p
  53.             try( H% j# z: y! Y8 w/ G" G
  54.             {
    * k2 d" ]( ~, X3 j7 I3 {& o
  55.                 #region 用户添加连接池
    - s3 Y$ D0 s7 z1 N, d7 T
  56.                 //第一次open时,添加到连接池中# U" W5 a) d7 x  Z
  57.                 if (!CONNECT_POOL.ContainsKey(user))
    " @8 N. K" C) J$ b: M- E/ V
  58.                     CONNECT_POOL.Add(user, socket);//不存在,添加) N1 b- u3 [, O
  59.                 else# j+ ~+ K4 y3 F4 u
  60.                     if (socket != CONNECT_POOL[user])//当前对象不一致,更新
    : e2 E; U7 r+ t% Q' n3 Q) ]8 c
  61.                         CONNECT_POOL[user] = socket;" C6 l: i1 U! n
  62.                 #endregion
    " y- A) k% j7 f6 ~6 Z+ d* B/ c
  63. ) m4 r* Y) J; `1 ?' [$ v( \
  64.                 #region 离线消息处理1 z& }# f' D0 i
  65.                 if (MESSAGE_POOL.ContainsKey(user))( P7 x6 K0 @7 i6 t' j
  66.                 {
    $ u, q7 i* H. t
  67.                     List<MessageInfo> msgs = MESSAGE_POOL[user];5 O% z) _3 X0 l9 n
  68.                     foreach (MessageInfo item in msgs)% P) y4 V9 l" l+ V2 x
  69.                     {
    + L" y# P0 \0 D! x3 y) b! H- C
  70.                         await socket.SendAsync(item.MsgContent, WebSocketMessageType.Text, true, CancellationToken.None);/ I1 \9 \) ]7 d% K% s
  71.                     }' O0 N# a0 c8 U8 ~# e
  72.                     MESSAGE_POOL.Remove(user);//移除离线消息
    ) L! y3 N4 j! h% u2 T; G
  73.                 }( A% t+ L% c9 ~  R
  74.                 #endregion
    9 _* P- H4 k) F8 A' }9 E
  75. / t9 |, A0 L  |1 P/ ?) P8 }
  76.                 string descUser = string.Empty;//目的用户
    % \) q, h8 @4 q
  77.                 while (true)  L8 P: i! B* h1 S! q& w, Z! J
  78.                 {
    ) r* p: {. c# N. l; n! K
  79.                     if (socket.State == WebSocketState.Open)) Y# m; m  M. R' H  Q
  80.                     {
    ) V# p( i- k) t
  81.                         ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[2048]);! \9 x( q* ?0 L8 E, T) Q8 n
  82.                         WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None);( E: ]- w; c/ h% H. I) e$ D' o
  83. ' S9 w! S! D. v1 I
  84.                         #region 消息处理(字符截取、消息转发)
    . S, e) N# `1 O, _
  85.                         try' g* y6 g( e; l7 q% f4 S9 d! g
  86.                         {
    7 J' g/ \( b; E8 e2 U4 S
  87.                             #region 关闭Socket处理,删除连接池
    $ y" s6 K! }. j+ |% s% r: d
  88.                             if (socket.State != WebSocketState.Open)//连接关闭
    1 c# x* A  W! A! Y( o3 V; M' _
  89.                             {
    1 C% @* ]# _# p% c& }
  90.                                 if (CONNECT_POOL.ContainsKey(user)) CONNECT_POOL.Remove(user);//删除连接池
    " I3 u* M( i: E" O
  91.                                 break;
    5 c$ y+ O7 P$ Z2 f; ~
  92.                             }
    : C) `0 t7 n& R4 ?+ b7 R
  93.                             #endregion
    * B* ^! F: G6 Y3 Z7 s, N& M

  94. + ]9 W' G' I4 d! X8 m0 a
  95.                             string userMsg = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);//发送过来的消息5 l, h( f' B0 Y  E+ I; T+ Y
  96.                             string[] msgList = userMsg.Split('|');( C& `2 t& w( b; c2 k; q
  97.                             if (msgList.Length == 2)
    & |  o9 E- I3 v0 m+ m4 \, c+ f
  98.                             {' i  t( W% |9 B5 o
  99.                                 if (msgList[0].Trim().Length > 0)
    0 p5 [3 B  u2 F4 r# N3 e
  100.                                     descUser = msgList[0].Trim();//记录消息目的用户3 @1 ?& `8 q/ I! T/ \( C. b" _
  101.                                 buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(msgList[1]));7 v. X: Y  S# F! M8 `
  102.                             }
    ; |5 e+ f8 |- d
  103.                             else# M) N& C2 W  H" U& N2 ~
  104.                                 buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(userMsg));2 z0 Z$ o2 l" F9 H

  105. / c8 U/ F6 E; p
  106.                             if (CONNECT_POOL.ContainsKey(descUser))//判断客户端是否在线
    , u; F$ a* J. ]8 L9 j1 b! L
  107.                             {0 p  l' F+ n" k4 G( s; a
  108.                                 WebSocket destSocket = CONNECT_POOL[descUser];//目的客户端- x5 [1 L, l5 E3 b1 W$ P0 ?, b
  109.                                 if (destSocket != null && destSocket.State == WebSocketState.Open)9 n$ l9 Y& p1 L
  110.                                     await destSocket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
    ; h8 `1 z8 g3 v5 L4 o
  111.                             }1 v& ]$ X* h* m9 q& o7 N$ q
  112.                             else
    / T4 M8 e2 ^' W1 ^% Z: t  O5 U
  113.                             {
    5 ~& K9 W/ z0 @$ R/ K
  114.                                 Task.Run(() =>+ k, F8 h) V3 O+ D  P
  115.                                 {
    ) n& k" l( @; y4 g) h2 M
  116.                                     if (!MESSAGE_POOL.ContainsKey(descUser))//将用户添加至离线消息池中6 z- |( Q9 p- b; B- D' Q. r1 F1 B
  117.                                         MESSAGE_POOL.Add(descUser, new List<MessageInfo>());; ~1 `  h3 Q, p- q( r% H
  118.                                     MESSAGE_POOL[descUser].Add(new MessageInfo(DateTime.Now, buffer));//添加离线消息
    - B! M: k8 ~  {  D! Q6 V4 a% w
  119.                                 });3 [4 d# J* ?" m5 b6 o1 ~
  120.                             }9 G1 {3 b# p" Z5 H& y: X
  121.                         }
    # `) T5 O- |1 \; ?" y! k
  122.                         catch (Exception exs)
    - S. P8 ?+ D+ S( x+ T+ M" U. w4 m
  123.                         {  ]7 o+ j& a) m, P3 h
  124.                             //消息转发异常处理,本次消息忽略 继续监听接下来的消息4 }& a$ P$ x: q
  125.                         }: Y- {& r3 V  l( C
  126.                         #endregion
    . C: ~, Y, h- U# e
  127.                     }
    " U* E8 a! s$ c; ?" q2 K% E
  128.                     else
    5 q) k" |  u4 F* }4 L/ v# {
  129.                     {
    7 Q& R. S8 M9 ~+ n! Y) l3 N
  130.                         break;, U5 h9 x8 i2 A! S
  131.                     }
    3 \5 B; o- z' E# u
  132.                 }//while end
    / q5 A+ f! ~8 w! c$ a
  133.             }4 [$ M" M0 e8 y) B
  134.             catch (Exception ex): k9 X0 x: J  s2 e- G
  135.             {( C0 l) G$ }4 H: _! y1 M
  136.                 //整体异常处理1 J* e+ N$ t7 ~7 P3 t5 r2 ?+ c' m
  137.                 if (CONNECT_POOL.ContainsKey(user)) CONNECT_POOL.Remove(user);
    6 G- O3 i- R: V  s  b& i' f' e# k
  138.             }
    ( |7 E+ p+ T0 {  i( y' j5 F. C
  139.         }
    6 D! H8 z2 q1 M
  140. 5 j! {& W/ w# R8 x5 Z4 J

  141. - c$ y2 ]& P! J1 u7 w
  142.         public bool IsReusable
    ) j& ^$ j# l+ K. U- D! S& u
  143.         {3 d8 \/ J; Z- |, p+ }
  144.             get( D$ A% Y2 G4 C2 n. \5 {+ @0 F1 A
  145.             {# k  |; X! L* d3 R1 U
  146.                 return false;
    ' V, _* j: W0 ~) P: E9 ^% C
  147.             }7 ^3 [( T6 f* g1 G) A4 K- w1 p
  148.         }
    . @" L" M& M4 Z( k( v
  149.     }% y2 @6 i- b. \/ k, S
  150. }
复制代码
4.运行看是否报错,若没错将我们的服务器网站发布到IIS(支持WebSocket的IIS上,win7的系统时不可以的)上
点击“生成”->"发布........",以文件系统的方式发布,目标位置为我们创建的IIS网站对应的物理路径

* c. g  V) M% b0 R" h* [
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享分享 支持支持 反对反对
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

GMT+8, 2024-12-22 16:43 , Processed in 0.144617 second(s), 22 queries .

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