• 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

      1 public class ChatWebSocketMiddleware
      2     {
      3         private static ConcurrentDictionary<string, System.Net.WebSockets.WebSocket> _sockets = new ConcurrentDictionary<string, System.Net.WebSockets.WebSocket>();
      4 
      5         private readonly RequestDelegate _next;
      6 
      7         public ChatWebSocketMiddleware(RequestDelegate next)
      8         {
      9             _next = next;
     10         }
     11 
     12         public async Task Invoke(HttpContext context)
     13         {
     14             if (!context.WebSockets.IsWebSocketRequest)
     15             {
     16                 await _next.Invoke(context);
     17                 return;
     18             }
     19             System.Net.WebSockets.WebSocket dummy;
     20 
     21             CancellationToken ct = context.RequestAborted;
     22             var currentSocket = await context.WebSockets.AcceptWebSocketAsync();
     23             //string socketId = Guid.NewGuid().ToString();
     24             string socketId = context.Request.Query["sid"].ToString();
     25             if (!_sockets.ContainsKey(socketId))
     26             {
     27                 _sockets.TryAdd(socketId, currentSocket);
     28             }
     29             //_sockets.TryRemove(socketId, out dummy);
     30             //_sockets.TryAdd(socketId, currentSocket);
     31 
     32             while (true)
     33             {
     34                 if (ct.IsCancellationRequested)
     35                 {
     36                     break;
     37                 }
     38 
     39                 string response = await ReceiveStringAsync(currentSocket, ct);
     40                 MsgTemplate msg = JsonConvert.DeserializeObject<MsgTemplate>(response);
     41 
     42                 if (string.IsNullOrEmpty(response))
     43                 {
     44                     if (currentSocket.State != WebSocketState.Open)
     45                     {
     46                         break;
     47                     }
     48 
     49                     continue;
     50                 }
     51 
     52                 foreach (var socket in _sockets)
     53                 {
     54                     if (socket.Value.State != WebSocketState.Open)
     55                     {
     56                         continue;
     57                     }
     58                     if (socket.Key == msg.ReceiverID || socket.Key == socketId)
     59                     {
     60                         await SendStringAsync(socket.Value, JsonConvert.SerializeObject(msg), ct);
     61                     }
     62                 }
     63             }
     64 
     65             //_sockets.TryRemove(socketId, out dummy);
     66 
     67             await currentSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", ct);
     68             currentSocket.Dispose();
     69         }
     70 
     71         private static Task SendStringAsync(System.Net.WebSockets.WebSocket socket, string data, CancellationToken ct = default(CancellationToken))
     72         {
     73             var buffer = Encoding.UTF8.GetBytes(data);
     74             var segment = new ArraySegment<byte>(buffer);
     75             return socket.SendAsync(segment, WebSocketMessageType.Text, true, ct);
     76         }
     77 
     78         private static async Task<string> ReceiveStringAsync(System.Net.WebSockets.WebSocket socket, CancellationToken ct = default(CancellationToken))
     79         {
     80             var buffer = new ArraySegment<byte>(new byte[8192]);
     81             using (var ms = new MemoryStream())
     82             {
     83                 WebSocketReceiveResult result;
     84                 do
     85                 {
     86                     ct.ThrowIfCancellationRequested();
     87 
     88                     result = await socket.ReceiveAsync(buffer, ct);
     89                     ms.Write(buffer.Array, buffer.Offset, result.Count);
     90                 }
     91                 while (!result.EndOfMessage);
     92 
     93                 ms.Seek(0, SeekOrigin.Begin);
     94                 if (result.MessageType != WebSocketMessageType.Text)
     95                 {
     96                     return null;
     97                 }
     98 
     99                 using (var reader = new StreamReader(ms, Encoding.UTF8))
    100                 {
    101                     return await reader.ReadToEndAsync();
    102                 }
    103             }
    104         }
    105     }
    控制只有接收者才能收到消息
    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失败 打开代理允许翻墙就好了

    启动后界面是这样式的

    (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="90%;margin:0px auto;border:1px solid steelblue;">
        <div class="msg">
            <div id="msgs" style="height:200px;"></div>
        </div>
    
        <div style="display:block;100%">
            <input type="text" style="max-unset;100%;max-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.目前就实现了这么多  因为项目还涉及其它技术 暂时不开放源码了 

  • 相关阅读:
    090828 H 小道理
    091031 T PowerShell Solution
    关注我们共有的家园,别让企鹅成为传说
    发布网站时自动切换connectionString
    bookmark: partitioned tables in sql server 2005
    it did suprise me a little bit..
    无法删除附加到事件上的匿名代理
    如何在自己工程项目中使用TouchJSON框架
    VMware 8安装苹果操作系统Mac OS X 10.7 Lion正式版
    Net线程间通信的异步机制
  • 原文地址:https://www.cnblogs.com/besuccess/p/7043885.html
Copyright © 2020-2023  润新知