NetCore WebSocket 即时通讯示例
1.新建Netcore Web項目
2.創(chuàng)建簡易通訊協(xié)議
public class MsgTemplate
{
public string SenderID { get; set; }
public string ReceiverID { get; set; }
public string MessageType { get; set; }
public string Content { get; set; }
}
SenderID發(fā)送者ID
ReceiverID 接受者ID
MessageType 消息類型 Text Voice 等等
Content 消息內(nèi)容
3.添加中間件ChatWebSocketMiddleware
1 public class ChatWebSocketMiddleware
2 {
3 private static ConcurrentDictionary<string, System.Net.WebSockets.WebSocket> _sockets = new ConcurrentDictionary<string, System.Net.WebSockets.WebSocket>();
4
5 private readonly RequestDelegate _next;
6
7 public ChatWebSocketMiddleware(RequestDelegate next)
8 {
9 _next = next;
10 }
11
12 public async Task Invoke(HttpContext context)
13 {
14 if (!context.WebSockets.IsWebSocketRequest)
15 {
16 await _next.Invoke(context);
17 return;
18 }
19 System.Net.WebSockets.WebSocket dummy;
20
21 CancellationToken ct = context.RequestAborted;
22 var currentSocket = await context.WebSockets.AcceptWebSocketAsync();
23 //string socketId = Guid.NewGuid().ToString();
24 string socketId = context.Request.Query["sid"].ToString();
25 if (!_sockets.ContainsKey(socketId))
26 {
27 _sockets.TryAdd(socketId, currentSocket);
28 }
29 //_sockets.TryRemove(socketId, out dummy);
30 //_sockets.TryAdd(socketId, currentSocket);
31
32 while (true)
33 {
34 if (ct.IsCancellationRequested)
35 {
36 break;
37 }
38
39 string response = await ReceiveStringAsync(currentSocket, ct);
40 MsgTemplate msg = JsonConvert.DeserializeObject<MsgTemplate>(response);
41
42 if (string.IsNullOrEmpty(response))
43 {
44 if (currentSocket.State != WebSocketState.Open)
45 {
46 break;
47 }
48
49 continue;
50 }
51
52 foreach (var socket in _sockets)
53 {
54 if (socket.Value.State != WebSocketState.Open)
55 {
56 continue;
57 }
58 if (socket.Key == msg.ReceiverID || socket.Key == socketId)
59 {
60 await SendStringAsync(socket.Value, JsonConvert.SerializeObject(msg), ct);
61 }
62 }
63 }
64
65 //_sockets.TryRemove(socketId, out dummy);
66
67 await currentSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", ct);
68 currentSocket.Dispose();
69 }
70
71 private static Task SendStringAsync(System.Net.WebSockets.WebSocket socket, string data, CancellationToken ct = default(CancellationToken))
72 {
73 var buffer = Encoding.UTF8.GetBytes(data);
74 var segment = new ArraySegment<byte>(buffer);
75 return socket.SendAsync(segment, WebSocketMessageType.Text, true, ct);
76 }
77
78 private static async Task<string> ReceiveStringAsync(System.Net.WebSockets.WebSocket socket, CancellationToken ct = default(CancellationToken))
79 {
80 var buffer = new ArraySegment<byte>(new byte[8192]);
81 using (var ms = new MemoryStream())
82 {
83 WebSocketReceiveResult result;
84 do
85 {
86 ct.ThrowIfCancellationRequested();
87
88 result = await socket.ReceiveAsync(buffer, ct);
89 ms.Write(buffer.Array, buffer.Offset, result.Count);
90 }
91 while (!result.EndOfMessage);
92
93 ms.Seek(0, SeekOrigin.Begin);
94 if (result.MessageType != WebSocketMessageType.Text)
95 {
96 return null;
97 }
98
99 using (var reader = new StreamReader(ms, Encoding.UTF8))
100 {
101 return await reader.ReadToEndAsync();
102 }
103 }
104 }
105 }
控制只有接收者才能收到消息
if (socket.Key == msg.ReceiverID || socket.Key == socketId)
{
await SendStringAsync(socket.Value,JsonConvert.SerializeObject(msg), ct);
}
4.在Startup.cs中使用中間件
app.UseWebSockets(); app.UseMiddleware<ChatWebSocketMiddleware>();
5.建立移動端測試示例 這里采用Ionic3運行在web端
創(chuàng)建ionic3項目略過 新手可點這里查看 或者有Angular2/4項目經(jīng)驗的可直接往下看
(1) 啟動Ionic項目
當(dāng)初創(chuàng)建ionic3項目時候遇到不少問題
比如ionic-cli初始化項目失敗 切換到默認(rèn)npmorg源就好了
比如ionic serve失敗 打開代理允許FQ就好了
啟動后界面是這樣式的
(2) 創(chuàng)建聊天窗口dialog 具體布局實現(xiàn) 模塊加載略過直接進(jìn)入websocket實現(xiàn)
在這之前別忘了啟動web項目 否則會出現(xiàn)這樣情況 鏈接不到服務(wù)
(3)dialog.ts具體實現(xiàn)
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為我要發(fā)送的內(nèi)容 比如"hello world"
var msgObj = {
SenderID: "222",
ReceiverID: "111",
MessageType: "text",
Content: msg
};
this.ws.send(JSON.stringify(msgObj));
}
ws://localhost:56892?sid=222 這是websocke服務(wù)鏈接地址
sid表示著我這個端的WebSocke唯一標(biāo)識 找到這個key就可以找到我這個用戶端了
6.在web端也實現(xiàn)一個會話窗口
<div class="container">
<div class="msg">
<div id="msgs"></div>
</div>
<div>
<input type="text" id="MessageField" placeholder="type message and press enter" />
</div>
</div>
<script>
$(function () {
$('.navbar-default').addClass('on');
var userName = '@Model';
var protocol = location.protocol === "https:" ? "wss:" : "ws:";
var wsUri = protocol + "http://" + 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>
基本開發(fā)完成 接下來看看效果
7.web和webapp端對話
8.webapp發(fā)送 web接收
總結(jié)
以上是生活随笔為你收集整理的NetCore WebSocket 即时通讯示例的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 查看oracle监听服务状态,(总结)O
- 下一篇: oracle统计每日归档大小,Oracl