Vue + WebApi用WebSocket推数据到界面

256 阅读2分钟

前言

在用Vue和WebApi做项目时,用到了WebSocket。在网上资料比较杂,大多是html,webapi版本不一致。而且WebSocket也不一样,有的是.Net Freamwork 4.8的,有的.Net core的。这里我用Vue3.0 和.Net5


一、Vue前端

这里就只说我个人踩过的坑。wsuri这里当WebApi的地址是http开头时,这里就是ws开头。如果服务端地址是https开头,那么这里就是wss开头,否则是连不上的。

<template>
    <div>
      <el-button @click="threadPoxi()" >测试</el-button>
      <span>{{this.receiveStr}}</span>
    </div>
</template>

<script>
    export default {
        data() {
            return {
                websock: null,
                receiveStr:'0',
            }
        },
        methods: {
            threadPoxi(){  // 实际调用的方法
                //参数
                const agentData = "mymessage";
                //若是ws开启状态
                if (this.websock.readyState === this.websock.OPEN) {
                    this.websocketsend(agentData)
                }
                // 若是 正在开启状态,则等待300毫秒
                else if (this.websock.readyState === this.websock.CONNECTING) {
                    let that = this;//保存当前对象this
                    setTimeout(function () {
                        that.websocketsend(agentData)
                    }, 300);
                }
                // 若未开启 ,则等待500毫秒
                else {
                    this.initWebSocket();
                    let that = this;//保存当前对象this
                    setTimeout(function () {
                        that.websocketsend(agentData)
                    }, 500);
                }

            },
            initWebSocket(){ //初始化weosocket
                //ws地址
                //const wsuri = "wss://localhost:44315/ws";
                const wsuri = "ws://localhost:11269/ws";
                this.websock = new WebSocket(wsuri);
                
                //打开连接处理程序
                this.websoc.onopen=() => {
                  alert("WebSocket开启");
                };
                this.websock.onmessage = this.websocketonmessage;
                this.websock.onclose = this.websocketclose;
            },
            websocketonmessage(e){ //数据接收                
                alert("接收到WebSocket数据:" + e.data);
                //receiveStr = redata.value;
                this.receiveStr = "5234564";
                console.log(redata.value);
            },
            websocketsend(agentData){//数据发送
                this.websock.send(agentData);
            },
            websocketclose(e){  //关闭
                console.log("connection closed (" + e.code + ")");
                alert("WebSocket关闭");
            }
        },
        created(){
            this.initWebSocket()
        }
    }
</script>

二、服务端

1.新建WebApi

选Net5,新建webapi。在新建时取消启用SSL,地址就会变成http开头。如果用https,就启用了SSL加密,https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。在前端回调函数没有证书是无法触发的。也就是说用https,和wss,前端的onopen,onmessage等函数不会触发(踩过的坑)。

2.输入代码

代码如下(示例):

[HttpGet("/ws")]
public async Task Get()
 {
     if (HttpContext.WebSockets.IsWebSocketRequest)
     {
         //接受websocket客户端连接
         using var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync();
         await Echo(webSocket);
     }
     else
     {
         //不是websocket客户端请求
         HttpContext.Response.StatusCode = 400;//
     }
 }
 /// <summary>
 /// 对客户端的处理,接受消息,发送消息,关闭连接
 /// </summary>
 /// <param name="webSocket"></param>
 /// <returns></returns>
 private async Task Echo(WebSocket webSocket)
 {
     var buffer = new byte[1024 * 4];
     var result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);

     string receiveString = Encoding.UTF8.GetString(buffer);
     while (!result.CloseStatus.HasValue)
     {
         var serverMsg = Encoding.UTF8.GetBytes($"Server: Hello. You said: {Encoding.UTF8.GetString(buffer)}");
         //向客户端发送消息
         await webSocket.SendAsync(new ArraySegment<byte>(serverMsg, 0, serverMsg.Length), result.MessageType, result.EndOfMessage, CancellationToken.None);
         //继续接受客户端消息
         result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
     }
     //关闭释放与客户端连接
     await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
 }

总结

本人也是新手刚入坑,写的不对的地方请大佬指正哈。