cncml手绘网
标题: 在IIS上搭建WebSocket服务器(二) [打印本页]
作者: admin 时间: 2018-11-7 00:43
标题: 在IIS上搭建WebSocket服务器(二)
服务器端代码编写
1.新建一个ASP.net Web MVC5项目
8 u! n$ L/ s1 d3 l# w! b9 T
2.新建一个“一般处理程序”
3.Handler1.ashx代码如下:
- using System;0 U( U4 g7 ?) o$ l% ?7 D, ?
- using System.Collections.Generic;7 {0 t) ~) ?$ t p! {* W
- using System.Linq;
c1 F( b' ]4 R: B7 J - using System.Net.WebSockets;- Z. q. S: X0 j4 }) U+ @: t- n
- using System.Text;
" J& z( b/ m3 q6 s2 p - using System.Threading;9 T$ A5 R) F! ]8 M( l" O
- using System.Threading.Tasks;6 }0 v2 C3 l p; m7 k* s; i3 g
- using System.Web;
3 _5 S2 \! z, N4 t: N - using System.Web.WebSockets;
' K7 ]2 W; U* i. i) T9 P
7 W ]" h7 E6 a3 I0 J/ k" h' Q* t- * l9 h+ [7 f$ r% c( z
- namespace WebApplicationWebsocketHandler
: l/ a7 L! u# X0 L3 L! G- a - {- X; g0 Y' a4 F% S+ O' C
- /// <summary>" X% I7 \5 Q' |' \9 f+ t% J4 k+ i
- /// 离线消息
9 ~! p* N) a; F; {) ]% {* w - /// </summary>& e% a. P' t- D4 b
- public class MessageInfo6 l# U) x! P6 B/ \
- {
' W+ W5 ?, ^ g' c - public MessageInfo(DateTime _MsgTime, ArraySegment<byte> _MsgContent)
; F$ g6 b5 g" w& P. R. e8 p - {9 }8 U4 y& s: ^8 L' V
- MsgTime = _MsgTime;+ a8 c0 w5 V0 e9 ]
- MsgContent = _MsgContent;7 S& e- i& l' k# D2 f
- }2 ]# [! i4 X4 s' G7 y8 j$ T3 ]- z# {/ u
- public DateTime MsgTime { get; set; }1 p0 F( c2 c' u8 B
- public ArraySegment<byte> MsgContent { get; set; }
3 j* T! {0 F- S6 N, @& z - }5 L; j& {; W! z" j
3 ~, A6 s" K5 U/ s2 ]2 J- 4 O# |% ]: E' @& T
- & Z+ M8 l V ?( v9 z7 n4 Y! s
2 W3 O. c% ]& z6 h( T1 N- /// <summary>
! `- z; e. y+ q5 B- m( i - /// Handler1 的摘要说明5 [' e+ r' x, E
- /// </summary>
% i. J. c. N% y/ ^ - public class Handler1 : IHttpHandler
5 a5 x3 [/ Y4 U - {* }1 |8 U8 C6 t+ N
- private static Dictionary<string, WebSocket> CONNECT_POOL = new Dictionary<string, WebSocket>();//用户连接池9 v$ C) r ]/ j- |4 b: k
- private static Dictionary<string, List<MessageInfo>> MESSAGE_POOL = new Dictionary<string, List<MessageInfo>>();//离线消息池
* O& A% ], ?$ I" B; W( w8 u& k - public void ProcessRequest(HttpContext context)' d7 J8 N1 z7 \: m e( d
- {
7 G) H% \/ W7 j& i - //context.Response.ContentType = "text/plain"; u5 r- X/ I' n) g9 u) W7 P0 T
- //context.Response.Write("Hello World");
2 ]% w# S' r5 p4 Q0 T - if (context.IsWebSocketRequest)) l `% @% P/ {0 F5 F8 O6 a8 o: T
- {
: }( b1 \4 S7 v5 v# X - context.AcceptWebSocketRequest(ProcessChat);
8 m2 U/ [6 E! q - } 9 q, u$ U8 r5 _; @: N& G2 P
- }
3 `" b9 m2 S$ R/ [( s' I - # g: b7 P( y* Y# N* W
- private async Task ProcessChat(AspNetWebSocketContext context)
7 _- d6 E) a1 e - {, B/ L7 R* Q3 f- P
- WebSocket socket = context.WebSocket;9 b7 P% H' w3 K
- string user = context.QueryString["user"].ToString();: _: J: X/ k( @# O( m! D/ g' K" h
3 b0 w6 R, b7 C; O& Y- ~- try- a2 v3 x- K1 _' _5 _2 y4 J2 g
- {
1 @5 k5 v" B( _ - #region 用户添加连接池6 ~0 X- w2 y# t0 E6 {" b& @$ I; D
- //第一次open时,添加到连接池中
1 n d+ W4 p# s% m8 V* Y - if (!CONNECT_POOL.ContainsKey(user))5 M# N: ~9 m, R$ ]( T' P: _
- CONNECT_POOL.Add(user, socket);//不存在,添加
% H+ I( c3 ?$ r - else
2 m- I( X; Z; @" W9 d, {4 ] - if (socket != CONNECT_POOL[user])//当前对象不一致,更新 u% o" U/ t$ ~3 e/ }' h/ i7 N1 ~
- CONNECT_POOL[user] = socket;6 n' o, s u/ c$ Q: t8 h
- #endregion, y; J/ l3 t: ^3 y6 u
4 _6 b# n# q) X. P% S- #region 离线消息处理4 q# N1 w$ j0 z& g3 L5 t% k
- if (MESSAGE_POOL.ContainsKey(user))
- l9 O5 i2 E* t. J* L2 d D7 l - {
! @9 v& m* o# c/ r- {) p+ T8 X% s - List<MessageInfo> msgs = MESSAGE_POOL[user];
2 S: K3 j5 @9 L, j* i" p - foreach (MessageInfo item in msgs)
5 i0 e9 L: n w; [/ {2 K - {
( P* I8 x/ l0 M! Z' `& @* W - await socket.SendAsync(item.MsgContent, WebSocketMessageType.Text, true, CancellationToken.None);0 b9 O# u' c8 o* f. G
- }
4 E9 d5 U- i0 y) z - MESSAGE_POOL.Remove(user);//移除离线消息
# _3 W! T% n" s2 j3 Q' X - }* q% e! O+ T8 Q8 w/ ~& y+ Z4 l
- #endregion
" M1 N5 T3 i) j - 4 u' z1 A- e8 @, ~2 e
- string descUser = string.Empty;//目的用户
$ z- t, r6 d" F q - while (true)9 v0 @1 @* t- x1 S( Q
- {8 z/ x* R: w% l& t9 A/ }7 L
- if (socket.State == WebSocketState.Open)( P4 k6 B H- L
- {
1 b n: j: |# }! c1 K% a - ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[2048]);
8 ~# n& t/ A1 } - WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None);
! O7 l+ N6 _, x" \8 x - 5 G1 U6 W) I5 [; B4 `2 ~
- #region 消息处理(字符截取、消息转发)2 D/ C7 e: B" Q( U( S9 l
- try+ D( K, [4 P, {. B
- {
# z; L; Z* u0 H& S/ P& f) Z- B: U0 i9 P - #region 关闭Socket处理,删除连接池6 D: h$ Y; D! r# M; e/ `1 _
- if (socket.State != WebSocketState.Open)//连接关闭" K, U' e; B6 Z" c" b; w
- {6 ~4 x& H$ n' P% W6 k$ f
- if (CONNECT_POOL.ContainsKey(user)) CONNECT_POOL.Remove(user);//删除连接池' e1 H6 G6 I: A: H% n# q c7 V
- break;( W$ j6 i ]: d! k
- }& f% M( b, i2 T/ G' P. L8 r
- #endregion
; n1 g4 y( g6 T" A4 j - ' a# N r% [8 K
- string userMsg = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);//发送过来的消息
( z9 \' C. g1 n0 w( ?( a; x5 u - string[] msgList = userMsg.Split('|');
1 T' \$ F1 y$ I+ } - if (msgList.Length == 2): I( \0 N0 F9 j7 Y7 z
- {
8 Y: x+ U7 [9 U0 Y* F9 W - if (msgList[0].Trim().Length > 0): ]1 y6 b0 u; [/ I0 E3 n
- descUser = msgList[0].Trim();//记录消息目的用户
% D$ [! @) x, `- Q0 u. m( x - buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(msgList[1]));; K9 Z9 J0 C& Y. @% J8 h+ x! d
- }
9 q# f6 w; X+ d( Y - else
$ q& [# B6 V1 r1 z% A7 @1 ]7 n - buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(userMsg));
6 X& w1 ?# W2 t& d0 e
4 h( h7 m. D2 }7 k% [8 `- if (CONNECT_POOL.ContainsKey(descUser))//判断客户端是否在线
+ R: v8 }' ]) d- ~, V! O5 \ - {
% `* \- `$ a5 ` - WebSocket destSocket = CONNECT_POOL[descUser];//目的客户端
0 }# o# n7 @+ ]5 V - if (destSocket != null && destSocket.State == WebSocketState.Open)) }- z {: q9 S3 p6 N: `0 K
- await destSocket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);6 c, f& [! V0 J+ \# y+ G
- }5 l$ N: p) g5 z% O
- else
* Y* y* K ` U" v6 i: f! N6 u" q3 | - {
( w$ ~; D9 {# w& ^% b: c$ y1 }9 b - Task.Run(() =>
) r/ F" s+ H' | - {
/ b, d# c- i( u& | - if (!MESSAGE_POOL.ContainsKey(descUser))//将用户添加至离线消息池中 X% j+ M9 ]4 z9 K1 J
- MESSAGE_POOL.Add(descUser, new List<MessageInfo>());6 J$ D. h# T3 @( A9 h
- MESSAGE_POOL[descUser].Add(new MessageInfo(DateTime.Now, buffer));//添加离线消息
, y2 u# ~! V/ c - });4 F# l; ^- |+ x" A K1 _
- }
+ d. G0 {. U& X8 n8 \: o3 Y- z1 Z - }6 t; m/ U. s/ [0 a1 v+ j& h
- catch (Exception exs)/ r/ Z T: \" \7 z; [+ m9 w
- {
- I0 A% S) y; ^, D+ i8 |& C - //消息转发异常处理,本次消息忽略 继续监听接下来的消息1 @4 F1 I: w9 K! [
- } J* _# R7 I% f n
- #endregion
0 ]$ G- Z3 o* Z - }# z, e% _% L1 p3 \7 T b$ Q
- else7 ^! u2 s3 K% K+ q" Q
- {
' j {$ F& }- C3 C/ [4 t: C - break;9 p" S6 @5 x# j- B3 g: k
- }) F X) y& b+ ?
- }//while end7 x8 z8 [0 D+ ]6 x
- }
( c5 o% R* _1 [$ [% r - catch (Exception ex); Y3 n: q. S- U& b% F2 t
- {
' P; j: b9 C5 R$ c; m! i1 P! Y% J - //整体异常处理
7 E% r8 w6 a6 K4 P7 x - if (CONNECT_POOL.ContainsKey(user)) CONNECT_POOL.Remove(user);
' |8 _0 S2 d5 S8 D - }* l+ U1 C7 k8 h+ d0 d( I( s
- }
: o9 \& o5 d0 v+ v( X5 ?2 F6 } - ! F' q6 N$ V" e
0 E7 Q6 \6 U: l1 ~( o# Z- public bool IsReusable
/ P6 j; c( q1 x5 x- m - {
7 v- O+ L: m6 U - get
: t* K7 Y" h" f5 W9 b/ s/ B- d - {
6 X' J, t& k. g# L& ? - return false;3 s4 n5 e+ k/ z* u Z
- }
) e9 C, m$ W5 G9 D y4 L9 P& ^9 Q - }
/ K" N3 C6 S9 j% I7 M- q - }
1 S5 r) @# |& p1 S# R- z - }
复制代码4.运行看是否报错,若没错将我们的服务器网站发布到IIS(支持WebSocket的IIS上,win7的系统时不可以的)上
点击“生成”->"发布........",以文件系统的方式发布,目标位置为我们创建的IIS网站对应的物理路径
3 d6 z3 u& l' j* k N4 q
欢迎光临 cncml手绘网 (http://bbs.cncml.com/) |
Powered by Discuz! X3.2 |