cncml手绘网
标题: 在IIS上搭建WebSocket服务器(二) [打印本页]
作者: admin 时间: 2018-11-7 00:43
标题: 在IIS上搭建WebSocket服务器(二)
服务器端代码编写
1.新建一个ASP.net Web MVC5项目
1 P, M; _) l" {6 X( I2.新建一个“一般处理程序”
3.Handler1.ashx代码如下:
- using System;" u* `* H- q! m) K( |
- using System.Collections.Generic;1 H- }+ w3 B- a# I* `
- using System.Linq;6 h+ ]. q+ ^! M
- using System.Net.WebSockets;
2 x4 k3 M7 |9 `" l - using System.Text;
7 A" _; b" s1 ?1 _ - using System.Threading;
( Y, N1 Q9 z1 e/ @ - using System.Threading.Tasks;, x. \9 O" i0 |+ _0 s
- using System.Web;
[" ~; x* F$ L) \ - using System.Web.WebSockets;
" Q/ I2 d/ A# \ - % D4 f) M! W" w! ]1 n9 R J- G
- / w/ }" T$ I' H! Z$ W- N
- namespace WebApplicationWebsocketHandler
9 q2 [( U( c0 H4 L$ j/ h - {& @! }4 Z2 a4 N* W% g( m
- /// <summary>
* R2 E$ C1 Y0 _0 D - /// 离线消息
4 j% G6 _( k [% Z5 a/ x - /// </summary>) Z G# P7 e9 n; h* W* O
- public class MessageInfo
) T5 [1 w9 `" P - {( ]$ v3 n2 w9 y* C: e
- public MessageInfo(DateTime _MsgTime, ArraySegment<byte> _MsgContent). W" }; ~0 b0 G3 f, \- _( a
- {
. p7 X! a) O8 Y: X- F% Z - MsgTime = _MsgTime;3 l- Q* S5 z9 n2 _& y
- MsgContent = _MsgContent;
/ p9 j- y9 A* E; O& a( S! v - }
" g7 `) j; z U3 ?& Q- W - public DateTime MsgTime { get; set; }
! I6 h6 D4 b( v; O - public ArraySegment<byte> MsgContent { get; set; }
) |5 k, y. V& G4 p - }
n+ n; a% r) E0 A& x4 T
( @4 {9 l& B5 s- A$ j6 E) J- ; t; H6 V2 ~7 J; r: y
- 1 g- Q$ p& S) }( Z( b- ?8 S
/ Z7 }. K+ |8 u0 L- /// <summary>5 R, P$ S) v6 l, L7 x
- /// Handler1 的摘要说明
9 {1 c& U& ]. P9 r" K# r. ~, O7 @ - /// </summary>
+ d& k( k7 @, W: e% g( j - public class Handler1 : IHttpHandler
$ E5 r5 ?' s' k U) `5 V/ p' ? - {( S/ b p/ N+ W8 W$ K6 M$ p, e
- private static Dictionary<string, WebSocket> CONNECT_POOL = new Dictionary<string, WebSocket>();//用户连接池2 B- @$ a S; w1 f
- private static Dictionary<string, List<MessageInfo>> MESSAGE_POOL = new Dictionary<string, List<MessageInfo>>();//离线消息池" B* a, B4 {4 s" X
- public void ProcessRequest(HttpContext context)" N' n, ] e' r' T* ^7 A
- {( h( J5 y, i6 b( q5 Y% U6 C
- //context.Response.ContentType = "text/plain";, @6 ~3 J- w& E: D
- //context.Response.Write("Hello World");7 e% L- x, a# {3 o" s! J
- if (context.IsWebSocketRequest)( F, ?5 Y9 q9 R1 a
- {
' q' H' e; E0 B; e7 A - context.AcceptWebSocketRequest(ProcessChat);- d; t/ ~$ W6 u9 ?/ C6 B
- } * }8 d V' S' F8 B: T+ j
- }
* W6 D+ Q1 {) l: b) ~3 t
; p! n' S' Y& e5 L7 r7 o- private async Task ProcessChat(AspNetWebSocketContext context)
, j- ~/ p' r/ F% Q5 ^ - {
/ I4 @$ f5 l, `2 { - WebSocket socket = context.WebSocket;* d. c" E5 u3 v, k3 ~) d7 O6 V
- string user = context.QueryString["user"].ToString();1 L) k1 o) I! K
- * D0 @' D6 \ M2 {: \8 r& F6 r- ?
- try" r! s* S# g8 M1 G
- {% e% L+ _6 w+ [( |, _1 r
- #region 用户添加连接池4 p; H9 ^) z; j' b+ {* u# F* i5 j3 }7 b
- //第一次open时,添加到连接池中
6 T$ Q; _5 N0 N9 ^4 U) J5 ?2 s - if (!CONNECT_POOL.ContainsKey(user))
5 j: k4 n+ F6 S* x' H, T - CONNECT_POOL.Add(user, socket);//不存在,添加( A" D( i9 A: B9 a$ f
- else
) B$ a* c& M4 T - if (socket != CONNECT_POOL[user])//当前对象不一致,更新
: Q3 l* i' o$ k% ~7 c7 T - CONNECT_POOL[user] = socket;3 k+ G+ ?; w: Y7 ]+ l t
- #endregion4 i! b) D; [& H0 T. y
; z/ i E; ~3 b9 Z1 s+ {- #region 离线消息处理$ Y0 j1 Z# Q* c9 l; E
- if (MESSAGE_POOL.ContainsKey(user))! q0 J+ L5 F; j6 J3 C
- {) L1 r9 o" G3 u! i
- List<MessageInfo> msgs = MESSAGE_POOL[user];4 o+ _( Q8 T7 r3 _0 O. j1 D' o6 ?5 {$ T) ]
- foreach (MessageInfo item in msgs)
9 n/ R( w+ C6 V6 ]& ?9 J7 S - {' t+ N9 T# \" y* H
- await socket.SendAsync(item.MsgContent, WebSocketMessageType.Text, true, CancellationToken.None);$ @, Q" ]2 m4 g9 F$ T
- }4 M6 d$ v' F* \8 m
- MESSAGE_POOL.Remove(user);//移除离线消息
& n! ~" i( k, s2 A# y - }0 l3 u( T% ~3 N$ {
- #endregion5 c+ \6 q7 w, @% w& n. z. }
- 7 y/ _7 t* r8 j5 t/ k' l6 `" Q
- string descUser = string.Empty;//目的用户
2 Y' d' \& [$ M0 o - while (true)8 l( p' U( W3 y6 h. T. D. ?; U0 u7 W; q
- {
) z# e' Q# {3 M8 r% C m - if (socket.State == WebSocketState.Open)+ w! G4 x3 A. M+ k
- {9 Q- E) g q: _8 M3 O
- ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[2048]);3 H. S7 h: }& S* k; s1 t
- WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None);
" f1 l& t# J/ U - , ?# z! |3 |- _; J. y) I7 p h
- #region 消息处理(字符截取、消息转发)% z" s, K/ ?: J9 r2 _9 i
- try
% a; ?+ @+ M' X* @6 Y t7 [1 y - {( U$ J' U' T. b% R
- #region 关闭Socket处理,删除连接池1 Z! @4 J2 d3 @/ T. k# L! o
- if (socket.State != WebSocketState.Open)//连接关闭
' k# c, D) t; D, h# \ - {5 f' l7 a- ]2 _
- if (CONNECT_POOL.ContainsKey(user)) CONNECT_POOL.Remove(user);//删除连接池
7 J1 e: E) T. L% q - break;
2 m% ^0 r" ^7 u4 C - }
* [6 O& E" R6 E5 Z) R d - #endregion) j% q+ p/ b2 N3 O1 D
- * Z, L- t+ j3 e7 Z" h+ A: _3 g
- string userMsg = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);//发送过来的消息
& S# A( I9 T% y3 @4 g0 z+ @ - string[] msgList = userMsg.Split('|');
/ C1 D6 ?9 A- v# K/ ?6 x; p# w! {' [ - if (msgList.Length == 2)3 ~: n: S3 v, W; G) E% P- w, k( }
- {
/ g% h7 R* Y6 L$ Y/ c$ g* s0 o+ B7 w+ c - if (msgList[0].Trim().Length > 0)
1 n6 N, H! b3 q - descUser = msgList[0].Trim();//记录消息目的用户
5 t/ r2 R- l7 p9 T4 ^1 Q3 O: o! F - buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(msgList[1]));: d1 ?& @; t' d
- } i: T: N% u: r% P% W$ X, x0 A# Y
- else* e% S G U( o8 p$ a) [9 f
- buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(userMsg));
2 s/ H1 L2 h! p8 U: e! C; }
# f! O5 A) z/ e" Y P% @- if (CONNECT_POOL.ContainsKey(descUser))//判断客户端是否在线; e w" c% R5 @& C
- {
! S) P7 o3 V4 v( M9 W6 g$ m - WebSocket destSocket = CONNECT_POOL[descUser];//目的客户端$ }. Q) ~- Q( e
- if (destSocket != null && destSocket.State == WebSocketState.Open)+ T& m' }: z" j. ^' G) G2 ?
- await destSocket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);7 Y9 {* W# P8 B6 k
- }- x9 L* {+ |& j9 g* j; N) o
- else' J8 h. ^1 q( x
- {+ @( q( c1 t& j" j5 N
- Task.Run(() =>
. \+ N( F* p: I0 r$ A3 X- K - {
: Y$ n% q& y8 X5 R# B: J7 y - if (!MESSAGE_POOL.ContainsKey(descUser))//将用户添加至离线消息池中
7 Z3 f6 ^# T2 P3 a, Y7 c9 l1 h - MESSAGE_POOL.Add(descUser, new List<MessageInfo>());
7 W! c+ @ G0 }1 ?+ C' V1 v - MESSAGE_POOL[descUser].Add(new MessageInfo(DateTime.Now, buffer));//添加离线消息
9 X2 v9 S% R! e+ L - });
3 M6 B# T0 e# z; I) `! S - }. T( E. Y, o; U) P3 s* {2 @0 u
- }! ?1 e2 r+ V) t" B" Y2 ~
- catch (Exception exs)
6 e" D2 k' ^5 N$ J5 _ - {8 `1 |( E% [2 e/ l" _
- //消息转发异常处理,本次消息忽略 继续监听接下来的消息
- `* \4 L9 r2 ] - }3 p! f, y7 n) C+ N2 l' ~
- #endregion
. _. D# T) @% ^: z$ i1 q - }
. Z/ \, d% j, c+ q9 W. u4 d& L! _0 q! j - else2 |: Z% R. f: `/ N. ?( v
- {: v9 t/ u; n* j$ K
- break;1 [7 [( y! @: l+ L0 F% R/ P+ c
- }
, y( [+ }2 z0 b! u/ k - }//while end7 f) K. L4 k8 O
- }1 D* o$ F' J. H# A/ H
- catch (Exception ex)
' }% i$ A- _; A - {- V$ Y5 } K9 n5 n
- //整体异常处理/ [0 T: L) N- ]$ C
- if (CONNECT_POOL.ContainsKey(user)) CONNECT_POOL.Remove(user);6 y" j. u4 Q) W* G
- }
, q4 A$ r3 }6 _' n - }- m: @: d8 \7 L8 @4 j0 P
4 A8 |+ w0 Q+ f' F- * ?; H2 s7 X0 _. c1 v( k
- public bool IsReusable
& v% T5 k9 E1 V5 n. c - {& R% k- s& Q' C c8 Q' j! f: V
- get; C8 W% Q$ o6 Q7 f+ p0 B
- {3 W1 o) d5 j! I5 v
- return false;
! c- ?1 [+ f! t! T- Y/ G2 ^; G - }
" ?# M" K# ?5 j+ Z) M+ `9 I2 l - }
5 |$ i9 h4 m+ V T; w - }( q6 e3 y* a* ^8 c" g3 L
- }
复制代码4.运行看是否报错,若没错将我们的服务器网站发布到IIS(支持WebSocket的IIS上,win7的系统时不可以的)上
点击“生成”->"发布........",以文件系统的方式发布,目标位置为我们创建的IIS网站对应的物理路径
- ?# T% z( `+ z2 o% @% x& } g( g ~& }
| 欢迎光临 cncml手绘网 (http://bbs.cncml.com/) |
Powered by Discuz! X3.2 |