这篇文章主要为大家详细介绍了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.目前就实现了这么多 因为项目还涉及其它技术 暂时不开放源码了
来源: http://www.phperz.com/article/17/0905/337790.html