NetCore WebSocket即时通讯示例

所属分类: 网络编程 / ASP.NET 阅读数: 1269
收藏 0 赞 0 分享

NetCore WebSocket 即时通讯示例,供大家参考,具体内容如下

1.新建Netcore Web项目

2.创建简易通讯协议

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

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端

创建ionic3项目略过 新手可点这里查看  或者有Angular2/4项目竟然可直接往下看

(1) 启动Ionic项目

当初创建ionic3项目时候遇到不少问题

比如ionic-cli初始化项目失败 切换到默认npmorg源就好了

比如ionic serve失败 打开代理允许FQ就好了

启动后界面是这样式的

(2) 创建聊天窗口dialog 具体布局实现 模块加载略过直接进入websocket实现

在这之前别忘了启动web项目 否则会出现这样情况 链接不到服务

(3)dialog.ts具体实现

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端也实现一个会话窗口

<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 + "//" + 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.目前就实现了这么多  因为项目还涉及其它技术 暂时不开放源码了

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

更多精彩内容其他人还在看

.NET Core源码解析配置文件及依赖注入

这篇文章我们设计了一些复杂的概念,因为要对ASP.NET Core的启动及运行原理、配置文件的加载过程进行分析,依赖注入,控制反转等概念的讲解等
收藏 0 赞 0 分享

.NET Corek中Git的常用命令及实战演练

这篇文章将通过故事的形式从Git的历史谈起,并讲述Git的强大之处。然后通过实战演练教你如何在Github以及码云上托管我们的代码并进行代码的版本控制
收藏 0 赞 0 分享

Asp.Net Core WebAPI使用Swagger时API隐藏和分组详解

这篇文章主要给大家介绍了关于Asp.Net Core WebAPI使用Swagger时API隐藏和分组的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Asp.Net Core具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
收藏 0 赞 0 分享

如何利用FluentMigrator实现数据库迁移

这篇文章主要给大家介绍了关于如何利用FluentMigrator实现数据库迁移的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
收藏 0 赞 0 分享

ASP.NET Core利用Jaeger实现分布式追踪详解

这篇文章主要给大家介绍了关于ASP.NET Core利用Jaeger实现分布式追踪的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用ASP.NET Core具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
收藏 0 赞 0 分享

浅谈从ASP.NET Core2.2到3.0你可能会遇到这些问题

这篇文章主要介绍了ASP.NET Core2.2到3.0可能会遇到的问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

详解.net core webapi 前后端开发分离后的配置和部署

这篇文章主要介绍了.net core webapi 前后端开发分离后的配置和部署,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

详解ASP.Net Core 中如何借助CSRedis实现一个安全高效的分布式锁

这篇文章主要介绍了ASP.Net Core 中如何借助CSRedis实现一个安全高效的分布式锁,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

.net 4.5部署到docker容器的完整步骤

这篇文章主要给大家介绍了关于.net 4.5部署到docker容器的完整步骤,文中通过示例代码介绍的非常详细,对大家学习或者使用.net4.5具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
收藏 0 赞 0 分享

.net core并发下线程安全问题详解

这篇文章主要给大家介绍了关于.net core并发下线程安全问题的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用.net core具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
收藏 0 赞 0 分享
查看更多