首页 > 其他分享 >NETCORE - WebSocket通信

NETCORE - WebSocket通信

时间:2022-10-23 20:12:01浏览次数:37  
标签:websocket socket NETCORE 通信 var WebSocket string ct

NETCORE - WebSocket通信

 

webscoket 通信 一般为 客户端与服务端通信,如需两个服务端通信,可把其中一个服务端模拟成客户端。

项目框架  vue + .net6 

创建 NET6 的 webapi 项目:NETCORE.WebSocketServer

 

 

 

创建类:MsgTemplate.cs

namespace NETCORE.WebSocketServer
{
    public class MsgTemplate
    {
        public string SenderID { get; set; }
        public string ReceiverID { get; set; }
        public string MessageType { get; set; }
        public string Content { get; set; }
    }
}

 

 

创建中间件 ChatWebSocketMiddleware.cs

using Newtonsoft.Json;
using System.Collections.Concurrent;
using System.Net.WebSockets;
using System.Text;

namespace NETCORE.WebSocketServer
{
    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);
                Console.WriteLine("接收到数据:" + response);
                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);
                        await SendStringAsync(socket.Value, $"收到,状态:正常,操作完成。", ct);
                    }
                    //if (socket.Key == "A0001")
                    //{
                    //    for (int i = 0; i < 10000; i++)
                    //    {
                    //        Thread.Sleep(1000);
                    //        await SendStringAsync(socket.Value, $"状态:正常,操作数:{i}", 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 jsonData = JsonConvert.DeserializeObject<MsgTemplate>(data);
            //var sendText = "已收到信息,现在回复。" + jsonData.Content;

            var sendText = data;
            var buffer = Encoding.UTF8.GetBytes(sendText);
            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();
                }
            }
        }
    }

}

 

 

 

在Program.cs 中使用中间件 

app.UseWebSockets();
app.UseMiddleware<ChatWebSocketMiddleware>();

 

启动后 websocket 地址:

wss://localhost:7187

 

 

 

创建 VUE 项目:

<template>
    <div>
        websockettest
    </div>
</template>
<script> 

export default {
    mounted() {
        this.connectWebsocket();
    },
    methods: {
        connectWebsocket() {
            let websocket;
            if (typeof WebSocket === "undefined") {
                console.log("您的浏览器不支持WebSocket");
                return;
            } else {
                let url = `wss://localhost:7187?sid=A0001`;
                // let url = `ws://127.0.0.1:18200?sid=A0001`;

                // 打开一个websocket
                websocket = new WebSocket(url);
                // 建立连接
                websocket.onopen = () => {
                    // sendData(0);
                    // function sendData(iv) {
                    //     setTimeout(() => {
                    // 发送数据
                    let obj = {
                        SenderID: 'client',
                        ReceiverID: 'A0001',
                        MessageType: 'text',
                        // Content: `客户端请求数据。![${iv}]`
                        Content: `客户端请求数据。!`
                    }

                    websocket.send(JSON.stringify(obj));
                    console.log("websocket发送数据中");
                    //         if (iv < 10000) sendData(++iv);
                    //     }, 1000);
                    // }
                };
                // 客户端接收服务端返回的数据
                websocket.onmessage = evt => {
                    console.log("websocket返回的数据:", evt);
                };
                // 发生错误时
                websocket.onerror = evt => {
                    console.log("websocket错误:", evt);
                };
                // 关闭连接
                websocket.onclose = evt => {
                    console.log("websocket关闭:", evt);
                };
            }
        }
    }
};
</script>

 

 

启动服务后:

注意要先启动 NETCORE 的后端服务。

 

 

 

 

 

 

 

 

 

 

 

参考:http://www.zzvips.com/article/64044.html

 

标签:websocket,socket,NETCORE,通信,var,WebSocket,string,ct
From: https://www.cnblogs.com/1285026182YUAN/p/16819295.html

相关文章

  • uWebSockets.js 遇见 Http3
    HTTP/3引入运行在UDP上的新(不同)传输协议QUIC意味着理论上和目前实验上的延迟减少,目前标准已发布,在开始之前可以参阅《​​​​WebSockets和HTTP​​》​​uWebSockets.......
  • 通过Linux的socket套接字实现客户端与服务器端的通信
    具体案例:使用树莓派ds18b20温度传感器实现温度上报首先需要获得传感器文件中保存的温度信息:温度信息通常保存在路径为“/sys/bus/w1/devices/28-xxxxxxxxxxxx/w1......
  • 记一次SpringBoot整合WebSocket 找不到ServerEndpointExporter类的问题
    packagecom.mengxiangnongfu.cms.framework.configure;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Confi......
  • 多径信道下通过LMS均衡算法提高通信质量
    目录​​一、理论基础​​​​二、核心程序​​​​三、仿真测试结果​​作者ID:fpga和matlab擅长技术:1.无线基带,无线图传,编解码2.机器视觉,图像处理,三维重建3.人工智......
  • 16.Springboot集成Websocket
    Springboot集成Websocket1.导入pom依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId><......
  • 通信题
    问题你尝试在一块信息介质上记录下一个\(1\)到\(n\)之间的整数\(x\),每次可以写入一个比特\(0\)或\(1\),不过因为一些原因,实际写入的比特不一定和发出的指令相同,但......
  • 一篇文章搞定组件通信
    常用的组件通信方式:6种props适用于的场景:父子组件通信注意事项:如果父组件给子组件传递数据(函数):本质就是子组件给父组件传递数据如果父组件给子组件传递数据(数据):本......
  • WebSocket是什么
    WebSocketWebSocket(ws)也可以称之为一种协议,提供给我们基于TCP之上的,能够让服务器和客户端互相发送信息的这么一种协议。whynothttp最开始我其实没有搞清楚http和ws的......
  • springboot 整合websocket
    1.             name用于确定给谁发消息的一个标识     ......
  • 北斗通信终端机_北斗通信终端
    北斗通信终端机_北斗通信终端计讯物联北斗通信终端机TN521,定位系统可向用户提供全天候、二十四小时服务,高精度快速定位、实时导航。工业级防水,防腐蚀,高低温,防碰撞......