NetCore WebSocket即時通訊示例
NetCore WebSocket 即時通訊示例,供大家參考,具體內(nèi)容如下
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
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();
}
}
}
}
控制只有接收者才能收到消息
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運(yùn)行在web端
創(chuàng)建ionic3項目略過 新手可點這里查看 或者有Angular2/4項目竟然可直接往下看
(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" 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>
<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接收


9.目前就實現(xiàn)了這么多 因為項目還涉及其它技術(shù) 暫時不開放源碼了
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
asp.net sqlconnection con.close和con.dispose區(qū)別
con.close是用來關(guān)閉和數(shù)據(jù)庫的連接,相對于open2008-12-12
LINQ字符串向datetime 轉(zhuǎn)換時失敗的處理方法
LINQ字符串向datetime 轉(zhuǎn)換時失敗的處理方法,需要的朋友可以可以參考一下2013-03-03
asp.net 禁用viewstate在web.config里
在web.config里設(shè)置禁用viewstate的代碼。2009-06-06
.net?core?api接口JWT方式認(rèn)證Token
本文詳細(xì)講解了.net?core?api接口JWT方式認(rèn)證Token,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-12-12
ASP.NET實現(xiàn)級聯(lián)下拉框效果實例講解
這篇文章主要為大家詳細(xì)介紹了ASP.NET實現(xiàn)級聯(lián)下拉框效果實例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2015-09-09
.NET開發(fā)實現(xiàn)一個微信跳一跳的輔助程序
最近比較火的小游戲就是微信跳一跳了,下面這篇文章主要給大家介紹了關(guān)于如何利用.NET開發(fā)實現(xiàn)一個微信跳一跳輔助程序的相關(guān)資料,利用此輔助可以輕松的實現(xiàn)高分,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2018-01-01
asp.net中調(diào)用Office來制作3D統(tǒng)計圖的實例代碼
這篇文章介紹了asp.net中調(diào)用Office來制作3D統(tǒng)計圖的實例代碼,有需要的朋友可以參考一下2013-11-11

