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

QQ登录

只需一步,快速开始

 找回密码
 立即注册

QQ登录

只需一步,快速开始

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

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

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

; |/ i7 ?- m( f+ P- R- E
2.新建一个“一般处理程序”
3.Handler1.ashx代码如下:
  1. using System;
    3 n3 G4 V5 D9 s! z: k
  2. using System.Collections.Generic;
    - R* w) M% w, e
  3. using System.Linq;
    ' m0 t/ ~+ C4 k& U
  4. using System.Net.WebSockets;; v: D* g% a/ u* p0 {* v
  5. using System.Text;) H( M" C4 ]! x1 K9 Y
  6. using System.Threading;
    ( @% ^, q1 t" u' g% u
  7. using System.Threading.Tasks;7 j; O* t+ k0 C1 {% k
  8. using System.Web;9 X5 d2 m9 j7 v
  9. using System.Web.WebSockets;
    1 ?  W0 i, W: `  ?- p' _

  10. ( b0 d! O  \6 a6 t2 B- [; s7 b
  11. 0 G& V; D. \2 G) \- C2 r7 B
  12. namespace WebApplicationWebsocketHandler3 r1 T8 I; [, X& ^6 z+ L3 X& a) V: \0 V
  13. {7 Z& a2 z! v1 u" w0 V; h6 M
  14.     /// <summary>; f2 p7 N& d: w5 H/ |  G
  15.     /// 离线消息
    . k  ]2 a& D6 g  e( c
  16.     /// </summary>
    0 R7 T- v3 I4 M, d0 U: p  C8 k
  17.     public class MessageInfo
    % q$ d$ }7 m$ p, |. t
  18.     {
    , D: `2 D" I. ~2 W* m8 O2 i, T
  19.         public MessageInfo(DateTime _MsgTime, ArraySegment<byte> _MsgContent)3 J% D2 m4 J; ?0 L# y( i0 M8 [
  20.         {
    9 T  X4 V5 q! x9 o9 ]! e$ P
  21.             MsgTime = _MsgTime;$ k, F* ~7 s9 d+ y4 k
  22.             MsgContent = _MsgContent;. Q7 j7 b5 y3 |
  23.         }
    ) u. V) w, F& u  Z& z8 W" F
  24.         public DateTime MsgTime { get; set; }9 H9 f2 u! T0 d8 S( Y/ \
  25.         public ArraySegment<byte> MsgContent { get; set; }
    3 n3 u1 K$ y- f, t# z) q3 J
  26.     }& Y6 r. @. ^6 I

  27. 6 q! P8 z5 s7 j; L

  28. : J+ r( ^) [0 U

  29. % d7 a) C9 C. j9 X
  30. 0 u- y! N- v/ x; W9 `: Y
  31.     /// <summary>1 X% a. m* f" G7 m, o7 W
  32.     /// Handler1 的摘要说明) f& v2 C* H/ }9 j0 d# B
  33.     /// </summary>* ~4 w$ D2 o/ F: j) ?5 ~
  34.     public class Handler1 : IHttpHandler- d8 i1 ?/ u1 w4 j' L1 h8 W; O3 B
  35.     {
    & g; G% r# l" D$ ^0 K* e
  36.         private static Dictionary<string, WebSocket> CONNECT_POOL = new Dictionary<string, WebSocket>();//用户连接池) R' X/ f4 Z' V+ T% W
  37.         private static Dictionary<string, List<MessageInfo>> MESSAGE_POOL = new Dictionary<string, List<MessageInfo>>();//离线消息池$ u8 Q* L' J7 \
  38.         public void ProcessRequest(HttpContext context)
    ' Z8 o, r! O* s5 r. r. u. A& B
  39.         {' ^$ z( t8 `. c
  40.             //context.Response.ContentType = "text/plain";
    % B7 Y! I, Z) S: s. {9 {
  41.             //context.Response.Write("Hello World");
    & V  v$ X; S% u( s4 _; g; u, F. S0 b
  42.             if (context.IsWebSocketRequest)
    ) r$ y/ `5 x, C$ M
  43.             {
    9 t2 h2 U- p9 x5 ^4 Y/ y5 n9 o& A3 q. O) C
  44.                 context.AcceptWebSocketRequest(ProcessChat);
    " _0 Z) b+ z6 C4 F" B9 O
  45.             }
    3 N2 e$ Z* P' u
  46.         }: F* ?1 J# X) N/ @8 D

  47. 6 U) h& K. l8 k( s
  48.         private async Task ProcessChat(AspNetWebSocketContext context)& Z1 b4 v# s# k  W$ Q* a
  49.         {
    ; p( U) R3 y+ }5 H' z" p; Z  y( t
  50.             WebSocket socket = context.WebSocket;  G7 P/ J1 Y+ O# c/ G( J- k7 ]
  51.             string user = context.QueryString["user"].ToString();4 j, H. V) p" ?# b$ n$ x9 S, l9 h

  52. ' s7 ^7 }  G: q% ^# ~' x4 i
  53.             try
    8 ?8 V# j. O. Z+ ?# O) ^: E
  54.             {
    + \: K2 d$ B. q6 ^6 a0 e
  55.                 #region 用户添加连接池
    + X; h) V  e# ?3 a0 A$ Z. ^  ?3 g
  56.                 //第一次open时,添加到连接池中2 r2 n; n, e5 p/ `
  57.                 if (!CONNECT_POOL.ContainsKey(user))
    . q* _8 R- Z' K2 x5 n  B3 }
  58.                     CONNECT_POOL.Add(user, socket);//不存在,添加
    # l& f1 m! J0 z, h8 v5 Y  R1 T" T% y
  59.                 else1 ?  {$ Q; E1 V" e  E- E
  60.                     if (socket != CONNECT_POOL[user])//当前对象不一致,更新5 `9 S. @) D1 O" J2 e
  61.                         CONNECT_POOL[user] = socket;. I  Z8 z- w3 J
  62.                 #endregion" W  u9 d! ~  G4 |6 @+ m8 @

  63. ) d! J# K7 g3 m* H7 w, c, |
  64.                 #region 离线消息处理" x! h8 N- X$ Y
  65.                 if (MESSAGE_POOL.ContainsKey(user))* K! K! }$ {- i  ^( B& T) _5 O/ N
  66.                 {6 Q6 q0 e0 d! c
  67.                     List<MessageInfo> msgs = MESSAGE_POOL[user];
    4 A1 t0 L9 R/ |( F; N
  68.                     foreach (MessageInfo item in msgs)
    1 E+ r- \4 x4 T1 _
  69.                     {4 l2 l  Y9 g: [* j! V. n
  70.                         await socket.SendAsync(item.MsgContent, WebSocketMessageType.Text, true, CancellationToken.None);3 f# U* `' N" p
  71.                     }& r+ K2 r( |0 t6 h) [- N6 S
  72.                     MESSAGE_POOL.Remove(user);//移除离线消息
    ! i; c1 q4 w7 {: Q0 b
  73.                 }: }0 G7 p$ _) ^9 X! e! O: U, O
  74.                 #endregion
    - G$ M7 G5 a* h

  75. ; g* Z6 f# [( d7 \3 @- h$ d) I; v+ l
  76.                 string descUser = string.Empty;//目的用户/ y* I$ r2 Y: \: v, L# k0 _& x
  77.                 while (true)& j: t+ f" {) C3 |$ Y
  78.                 {
    2 P2 R7 H+ }( K2 V; e+ G" P; [
  79.                     if (socket.State == WebSocketState.Open)
    5 C- A' Z# {0 Y
  80.                     {$ X8 A, h2 J. R$ B( P' j, w
  81.                         ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[2048]);
    : u$ j, E( B$ y$ L
  82.                         WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None);
    ( f. s, e+ U2 g% }

  83. % n3 r4 p" U2 o9 H: ]% A+ i
  84.                         #region 消息处理(字符截取、消息转发)
    2 _5 Q5 \% T1 x& _9 @( X# x9 M
  85.                         try
    # u1 i1 k4 ]* v
  86.                         {' U# i$ Y! S% a+ F1 q$ J+ g
  87.                             #region 关闭Socket处理,删除连接池' m" z. W7 B1 q9 y" V/ u- |& J% d
  88.                             if (socket.State != WebSocketState.Open)//连接关闭
    2 ?3 x: h0 n" {( d8 r  ]/ d
  89.                             {& H- X$ X* Q1 D8 I4 o& Y0 C
  90.                                 if (CONNECT_POOL.ContainsKey(user)) CONNECT_POOL.Remove(user);//删除连接池
    8 P+ \, w1 q* T
  91.                                 break;
    9 C" E, I& R, k- x3 N: x9 `/ J0 ?$ _
  92.                             }4 o" |8 G# s4 m5 J5 ]
  93.                             #endregion+ f7 m6 ~: e# @4 e& \: H
  94. 6 M. u- ^  s4 }( ~
  95.                             string userMsg = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);//发送过来的消息
    5 e5 Y, p3 b3 E) B
  96.                             string[] msgList = userMsg.Split('|');2 C( Q  C. C: E( v
  97.                             if (msgList.Length == 2)0 v  l* ?( b2 g8 N2 _; o1 x* `
  98.                             {
    / ~1 J: b3 F: `
  99.                                 if (msgList[0].Trim().Length > 0)) d9 I7 o9 R! _" ~) \% u& c1 c
  100.                                     descUser = msgList[0].Trim();//记录消息目的用户# J5 k' ?6 e: M
  101.                                 buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(msgList[1]));
    6 W* \, O  E' W. Q  f; h
  102.                             }0 S( N3 P) o) W2 i5 R5 H2 i! g, \
  103.                             else# {, b' ^+ ?0 ?" i3 L
  104.                                 buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(userMsg));# c4 f& J7 l6 x; i
  105. " v8 u/ j& z. K+ H; t
  106.                             if (CONNECT_POOL.ContainsKey(descUser))//判断客户端是否在线
    9 c# }" U4 y, i, e6 _6 I4 l8 A
  107.                             {. K; \# [. G) ]$ ^  P
  108.                                 WebSocket destSocket = CONNECT_POOL[descUser];//目的客户端
    5 T0 }# x: q4 g3 N" N- ?
  109.                                 if (destSocket != null && destSocket.State == WebSocketState.Open)
    ) l6 x; \. s2 I/ b8 ^$ g- L( g6 c9 r
  110.                                     await destSocket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
    ) a- a) L% f' j% j$ O2 i
  111.                             }
    - ~' q8 ^- R% e# q
  112.                             else
    * V$ {$ s( H. @4 J* e  M6 g
  113.                             {: O; _4 m4 ^1 y
  114.                                 Task.Run(() =>! j3 D+ D, l% t- ~
  115.                                 {6 a: f: G9 S3 d4 D+ `: f8 c) ^
  116.                                     if (!MESSAGE_POOL.ContainsKey(descUser))//将用户添加至离线消息池中
    7 x# h. w9 q' x
  117.                                         MESSAGE_POOL.Add(descUser, new List<MessageInfo>());
    # B6 g+ g: y; m+ _
  118.                                     MESSAGE_POOL[descUser].Add(new MessageInfo(DateTime.Now, buffer));//添加离线消息) F& S0 p4 q) m  _$ Y* `
  119.                                 });3 e$ b7 K1 C) J) Q$ e: i
  120.                             }
    , j9 q9 _& Y, p# [' T
  121.                         }
    , H7 b/ G8 `6 w% Z9 S. g4 ~
  122.                         catch (Exception exs)
    & i$ ?4 d+ B& h
  123.                         {2 {$ F6 z5 V8 I
  124.                             //消息转发异常处理,本次消息忽略 继续监听接下来的消息
    . M4 I* p9 p7 L% M8 a
  125.                         }
    , Q% q, A, H" B
  126.                         #endregion
    , Y7 k; C, l$ R* x+ {
  127.                     }
    1 D, {$ w! N( s" T  b
  128.                     else* u( F) I- `" |$ r5 c, w: d' b
  129.                     {1 U# y! j4 a; P  ~9 H. H
  130.                         break;
    - Z% \1 N: c  {) h4 [. ?- J
  131.                     }
    ' `6 V3 H- @5 Y
  132.                 }//while end
    ! ^# I. l( s+ r# Y2 m$ {, e( x8 @
  133.             }! ^2 L, z, Y; B7 _1 l9 N
  134.             catch (Exception ex)0 `9 C: T. ?3 b* P6 \. ?+ Y( i0 R' B
  135.             {
    " v' X# m' o6 K
  136.                 //整体异常处理/ c6 _$ a% E% M, o8 `
  137.                 if (CONNECT_POOL.ContainsKey(user)) CONNECT_POOL.Remove(user);7 f2 R* F* e6 |3 u$ E
  138.             }
    & M1 o% ]1 U/ O/ e/ L3 w/ e
  139.         }
    : g! v% h$ ]8 b% ~! ?
  140. " |6 R0 y' S* f
  141. 1 W, r, R/ O: y( Q  h  O
  142.         public bool IsReusable" x/ }0 G" V1 H* z2 H
  143.         {* }; _; ^6 S8 l8 r6 i
  144.             get$ H9 n9 L8 M! d( K# }
  145.             {
      `  ~" f, m4 Z4 R+ |1 U2 t+ k
  146.                 return false;# D1 [8 e) M; {9 o* f6 Q
  147.             }
    " K# s! W% R  ~) U2 Z2 U* N5 U
  148.         }
    ( D# p5 u: `. s4 e2 ]. }5 q5 p9 \
  149.     }
    , {! `3 a! v" b, u8 ?4 C
  150. }
复制代码
4.运行看是否报错,若没错将我们的服务器网站发布到IIS(支持WebSocket的IIS上,win7的系统时不可以的)上
点击“生成”->"发布........",以文件系统的方式发布,目标位置为我们创建的IIS网站对应的物理路径
8 o( `* H, B' ?" U
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享分享 支持支持 反对反对
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

GMT+8, 2024-12-22 15:26 , Processed in 0.111012 second(s), 24 queries .

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