Rumah > pembangunan bahagian belakang > Tutorial C#.Net > 制作NetCore WebSocket即时通讯实例详解

制作NetCore WebSocket即时通讯实例详解

巴扎黑
Lepaskan: 2017-08-08 11:23:49
asal
5245 orang telah melayarinya

这篇文章主要为大家详细介绍了NetCore WebSocket即时通讯示例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

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; }
 }
Salin selepas log masuk

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();
  }
  }
 }
 }
Salin selepas log masuk

控制只有接收者才能收到消息


if (socket.Key == msg.ReceiverID || socket.Key == socketId)
{
 await SendStringAsync(socket.Value,JsonConvert.SerializeObject(msg), ct);
}
Salin selepas log masuk

4.在Startup.cs中使用中间件


app.UseWebSockets();
app.UseMiddleware<ChatWebSocketMiddleware>();
Salin selepas log masuk

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(&#39;open&#39;);
  };

  this.ws.onmessage = (event) => {
  console.log(&#39;new message: &#39; + event.data);
  var msgObj = JSON.parse(event.data);
  this.msgArr.push(msgObj);;
  };

  this.ws.onerror = () => {
  console.log(&#39;error occurred!&#39;);
  };

  this.ws.onclose = (event) => {
  console.log(&#39;close code=&#39; + event.code);
  };
 }
 }

 sendMsg(msg) {//msg为我要发送的内容 比如"hello world"
 var msgObj = {
  SenderID: "222",
  ReceiverID: "111",
  MessageType: "text",
  Content: msg
 };
 this.ws.send(JSON.stringify(msgObj));
 }
Salin selepas log masuk

ws://localhost:56892?sid=222 这是websocke服务链接地址
sid表示着我这个端的WebSocke唯一标识 找到这个key就可以找到我这个用户端了

6.在web端也实现一个会话窗口


<p class="container" style="width:90%;margin:0px auto;border:1px solid steelblue;">
 <p class="msg">
 <p id="msgs" style="height:200px;"></p>
 </p>

 <p 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" />
 </p>
</p>
Salin selepas log masuk


<script>
 $(function () {
  $(&#39;.navbar-default&#39;).addClass(&#39;on&#39;);

  var userName = &#39;@Model&#39;;

  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);
  $(&#39;#msgs&#39;).append(msgObj.Content + &#39;<br />&#39;);
  };

  socket.onerror = function (e) {
  console.error(e.data);
  };

  $(&#39;#MessageField&#39;).keypress(function (e) {
  if (e.which != 13) {
   return;
  }

  e.preventDefault();

  var message = $(&#39;#MessageField&#39;).val();

  var msgObj = {
   SenderID:"111",
   ReceiverID:"222",
   MessageType: "text",
   Content: message
  };
  socket.send(JSON.stringify(msgObj));
  $(&#39;#MessageField&#39;).val(&#39;&#39;);
  });
 });
 </script>
Salin selepas log masuk

基本开发完成 接下来看看效果

7.web和webapp端对话

8.webapp发送 web接收

9.目前就实现了这么多  因为项目还涉及其它技术 暂时不开放源码了

Atas ialah kandungan terperinci 制作NetCore WebSocket即时通讯实例详解. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan