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運行在web端
創(chuàng)建ionic3項目略過 新手可點這里查看 或者有Angular2/4項目竟然可直接往下看
(1) 啟動Ionic項目

當初創(chuàng)建ionic3項目時候遇到不少問題
比如ionic-cli初始化項目失敗 切換到默認npmorg源就好了
比如ionic serve失敗 打開代理允許FQ就好了
啟動后界面是這樣式的

(2) 創(chuàng)建聊天窗口dialog 具體布局實現(xiàn) 模塊加載略過直接進入websocket實現(xiàn)
在這之前別忘了啟動web項目 否則會出現(xiàn)這樣情況 鏈接不到服務

(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服務鏈接地址
sid表示著我這個端的WebSocke唯一標識 找到這個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)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
.Net使用RabbitMQ實現(xiàn)短信密碼重置的操作步驟
在C#開發(fā)中,通過RabbitMQ實現(xiàn)短信服務可增強應用的消息通知能力,本文介紹了使用RabbitMQ發(fā)送短信的步驟,包括安裝RabbitMQ客戶端庫、創(chuàng)建連接和通道、實現(xiàn)短信發(fā)送服務、配置RabbitMQ消費者,并集成到用戶密碼重置流程中,通過示例代碼,可以快速理解整個實現(xiàn)過程2024-09-09
asp.net 使用駐留在頁面中的Cache緩存常用可定時更新的數(shù)據(jù)
這個就先需要先知道一下System.Web.Caching.Cache類,其實在我做WEB應用的時候,我會將一些使用頻繁但是又要經(jīng)常使用并且需要急時更新的對象放到Cache中,這樣可以很大程序上減少從硬盤上讀取數(shù)據(jù)的次數(shù)。2010-03-03
Win 2000下ASP.NET開發(fā)環(huán)境的配置
Win 2000在默認情況下是不支持ASP.NET的。必須對它進行一個環(huán)境的配置,本文將圖文介紹,在配置過程中遇到困難的朋友可以參考下2012-11-11
ASP.NET Core 3.x 并發(fā)限制的實現(xiàn)代碼
這篇文章主要介紹了ASP.NET Core 3.x 并發(fā)限制的實現(xiàn)代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-11-11
ASP.NET也像WinForm程序一樣運行的實現(xiàn)方法
我們今天要談到的是讓ASP.NET的程序也像WinForm一樣的運行,這樣就不需要安裝IIS或者Visual Studio這樣的特定環(huán)境了2012-01-01
.Net Core配置Configuration具體實現(xiàn)
這篇文章主要介紹了.Net Core配置Configuration具體實現(xiàn),文中運用大量代碼進行講解,如果有對相關(guān)知識感興趣的小伙伴可以參考這篇文章,希望可以幫助到你2021-09-09

