NetCore WebSocket 即时通讯示例,供大家参考,具体内容如下
1.新建Netcore Web项目
2.创建简易通讯协议
1
2
3
4
5
6
7
|
public class MsgTemplate { public string SenderID { get ; set ; } public string ReceiverID { get ; set ; } public string MessageType { get ; set ; } public string Content { get ; set ; } } |
SenderID发送者ID
ReceiverID 接受者ID
MessageType 消息类型 Text Voice 等等
Content 消息内容
3.添加中间件ChatWebSocketMiddleware
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
public class ChatWebSocketMiddleware { private static ConcurrentDictionary< string , System.Net.WebSockets.WebSocket> _sockets = new ConcurrentDictionary< string , System.Net.WebSockets.WebSocket>(); private readonly RequestDelegate _next; public ChatWebSocketMiddleware(RequestDelegate next) { _next = next; } public async Task Invoke(HttpContext context) { if (!context.WebSockets.IsWebSocketRequest) { await _next.Invoke(context); return ; } System.Net.WebSockets.WebSocket dummy; CancellationToken ct = context.RequestAborted; var currentSocket = await context.WebSockets.AcceptWebSocketAsync(); //string socketId = Guid.NewGuid().ToString(); string socketId = context.Request.Query[ "sid" ].ToString(); if (!_sockets.ContainsKey(socketId)) { _sockets.TryAdd(socketId, currentSocket); } //_sockets.TryRemove(socketId, out dummy); //_sockets.TryAdd(socketId, currentSocket); while ( true ) { if (ct.IsCancellationRequested) { break ; } string response = await ReceiveStringAsync(currentSocket, ct); MsgTemplate msg = JsonConvert.DeserializeObject<MsgTemplate>(response); if ( string .IsNullOrEmpty(response)) { if (currentSocket.State != WebSocketState.Open) { break ; } continue ; } foreach (var socket in _sockets) { if (socket.Value.State != WebSocketState.Open) { continue ; } if (socket.Key == msg.ReceiverID || socket.Key == socketId) { await SendStringAsync(socket.Value, JsonConvert.SerializeObject(msg), ct); } } } //_sockets.TryRemove(socketId, out dummy); await currentSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing" , ct); currentSocket.Dispose(); } private static Task SendStringAsync(System.Net.WebSockets.WebSocket socket, string data, CancellationToken ct = default (CancellationToken)) { var buffer = Encoding.UTF8.GetBytes(data); var segment = new ArraySegment< byte >(buffer); return socket.SendAsync(segment, WebSocketMessageType.Text, true , ct); } private static async Task< string > ReceiveStringAsync(System.Net.WebSockets.WebSocket socket, CancellationToken ct = default (CancellationToken)) { var buffer = new ArraySegment< byte >( new byte [8192]); using (var ms = new MemoryStream()) { WebSocketReceiveResult result; do { ct.ThrowIfCancellationRequested(); result = await socket.ReceiveAsync(buffer, ct); ms.Write(buffer.Array, buffer.Offset, result.Count); } while (!result.EndOfMessage); ms.Seek(0, SeekOrigin.Begin); if (result.MessageType != WebSocketMessageType.Text) { return null ; } using (var reader = new StreamReader(ms, Encoding.UTF8)) { return await reader.ReadToEndAsync(); } } } } |
控制只有接收者才能收到消息
1
2
3
4
|
if (socket.Key == msg.ReceiverID || socket.Key == socketId) { await SendStringAsync(socket.Value,JsonConvert.SerializeObject(msg), ct); } |
4.在Startup.cs中使用中间件
1
2
|
app.UseWebSockets(); app.UseMiddleware<ChatWebSocketMiddleware>(); |
5.建立移动端测试示例 这里采用Ionic3运行在web端
创建ionic3项目略过 新手可点这里查看 或者有Angular2/4项目竟然可直接往下看
(1) 启动Ionic项目
当初创建ionic3项目时候遇到不少问题
比如ionic-cli初始化项目失败 切换到默认npmorg源就好了
比如ionic serve失败 打开代理允许FQ就好了
启动后界面是这样式的
(2) 创建聊天窗口dialog 具体布局实现 模块加载略过直接进入websocket实现
在这之前别忘了启动web项目 否则会出现这样情况 链接不到服务
(3)dialog.ts具体实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
export class Dialog { private ws: any; private msgArr: Array<any>; constructor( private httpService: HttpService) { this .msgArr = []; } ionViewDidEnter() { if (! this .ws) { this .ws = new WebSocket( "ws://localhost:56892?sid=222" ); this .ws.onopen = () => { console.log( 'open' ); }; this .ws.onmessage = ( event ) => { console.log( 'new message: ' + event .data); var msgObj = JSON.parse( event .data); this .msgArr.push(msgObj);; }; this .ws.onerror = () => { console.log( 'error occurred!' ); }; this .ws.onclose = ( event ) => { console.log( 'close code=' + event .code); }; } } sendMsg(msg) { //msg为我要发送的内容 比如"hello world" var msgObj = { SenderID: "222" , ReceiverID: "111" , MessageType: "text" , Content: msg }; this .ws.send(JSON.stringify(msgObj)); } |
ws://localhost:56892?sid=222 这是websocke服务链接地址
sid表示着我这个端的WebSocke唯一标识 找到这个key就可以找到我这个用户端了
6.在web端也实现一个会话窗口
1
2
3
4
5
6
7
8
9
|
< div class = "container" style = "width:90%;margin:0px auto;border:1px solid steelblue;" > < div class = "msg" > < div id = "msgs" style = "height:200px;" ></ div > </ div > < div style = "display:block;width:100%" > < input type = "text" style = "max-width:unset;width:100%;max-width:100%" id = "MessageField" placeholder = "type message and press enter" /> </ div > </ div > |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
<script> $( function () { $( '.navbar-default' ).addClass( 'on' ); var userName = '@Model' ; var protocol = location.protocol === "https:" ? "wss:" : "ws:" ; var wsUri = protocol + "//" + window.location.host + "?sid=111" ; var socket = new WebSocket(wsUri); socket.onopen = e => { console.log( "socket opened" , e); }; socket.onclose = function (e) { console.log( "socket closed" , e); }; socket.onmessage = function (e) { console.log(e); var msgObj = JSON.parse(e.data); $( '#msgs' ).append(msgObj.Content + '<br />' ); }; socket.onerror = function (e) { console.error(e.data); }; $( '#MessageField' ).keypress( function (e) { if (e.which != 13) { return ; } e.preventDefault(); var message = $( '#MessageField' ).val(); var msgObj = { SenderID: "111" , ReceiverID: "222" , MessageType: "text" , Content: message }; socket.send(JSON.stringify(msgObj)); $( '#MessageField' ).val( '' ); }); }); </script> |
基本开发完成 接下来看看效果
7.web和webapp端对话
8.webapp发送 web接收
9.目前就实现了这么多 因为项目还涉及其它技术 暂时不开放源码了
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。