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.目前就实现了这么多 因为项目还涉及其它技术 暂时不开放源码了
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。