zoukankan      html  css  js  c++  java
  • vue+webapi 实现WebSocket 推送

    后台我是采用webapi 方式 写WebSocket,本来想用singler,后面有考虑到是vue 项目,就直接使用WebSocket了,因为不需要对ie做兼容。

    后台具体代码,因为可能多个浏览器 访问都是不用的sockt 对象,需要分别存储在字典list中,并在socket 链接关闭的时候销毁,也思考过      while (true)  为什么不会陷入死循环,原因在于        WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None);这句话,会阻塞 程序,只有等 有推送消息的时候,程序才会继续执行!

    using BozhouDMA.Model;
    using BozhouDMA.Service.Home;
    using BozhouDMAApi.Controllers.Base;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Net.Http;
    using System.Net.WebSockets;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Web;
    using System.Web.Http;
    using System.Web.WebSockets;
    using Newtonsoft.Json;
    
    namespace BozhouDMAApi.Controllers.Home
    {
        public class HomeController : ResultController
        {
            private HomeService hs = new HomeService();
    
            public static Dictionary<string, WebSocket> dicSockets = new Dictionary<string, WebSocket>();
    
    
    
            /// <summary>
            /// 创建socket连接
            /// </summary>
            /// <returns></returns>
            [HttpGet]
            public HttpResponseMessage CreateSocket()
            {
                if (HttpContext.Current.IsWebSocketRequest)
                {
                    HttpContext.Current.AcceptWebSocketRequest(ProcessWSChat);
                }
                return new HttpResponseMessage(HttpStatusCode.SwitchingProtocols);
            }
    
    
            /// <summary>
            /// 接收 报警程序推送数据
            /// </summary>
            /// <param name="polices"></param>
            /// <returns></returns>
            [HttpPost]
            public Dictionary<string, object> PushPoliceInfo([FromBody] List<Alarm> polices)
            {
    
                try
                {
    
                    if (dicSockets != null && dicSockets.Count > 0)
                    {
                        foreach (var dic in dicSockets)
                        {
                                var socket = dic.Value;
                                if (socket.State == WebSocketState.Open)
                                {
                                    var msg = JsonConvert.SerializeObject(polices);
                                    ArraySegment<byte> buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(msg));
                                    socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
                                }
                        }
                    }
                 
    
                    return this.Success("推送成功!");
    
                }
                catch (Exception e)
                {
                    return this.Fail("推送失败," + e.Message);
                }
    
            }
    
            /// <summary>
            /// 接收前端发送的数据
            /// </summary>
            /// <param name="arg"></param>
            /// <returns></returns>
            private async Task ProcessWSChat(AspNetWebSocketContext arg)
            {
                WebSocket socket = arg.WebSocket;
                string key = arg.SecWebSocketKey;
                if (!dicSockets.ContainsKey(key) )
                {
                    dicSockets.Add(key, socket);
                }
    
    
                while (true)
                {
                    ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[1024 * 10]);
                    WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None);
    
                    if (socket.State == WebSocketState.Open)
                    {
                        //前端发送的命令
                        string message = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);
    
                    }
                    else
                    {
                        dicSockets.Remove(key);
                        break;
                    }
                }
            }
    
        }
    }
    View Code

    前端使用es6 封装一个类

    let result = '';
    let ws = null;
    
    export default class socketTool {
      static init () {
        if (ws == null) {
          ws = new WebSocket('ws://' + window.location.hostname + ':4110/api/Home/CreateSocket');
    
          ws.onopen = function () {
            console.log('WebSocket连接成功!');
          };
          ws.onmessage = function (res) {
            console.log('推送数据:' + res.data);
            result = result + res.data;
          };
          ws.onerror = function (error) {
            console.log('WebSocket连接失败,错误:' + error);
          };
          ws.onclose = function () {
            console.log('WebSocket连接关闭!');
          };
        }
      }
    
      // 发送数据到后端
      static send (msg) {
        if (ws.readyState === WebSocket.OPEN) {
          ws.send(msg);
        } else {
          console.warn('WebSocket连接已关闭!');
        }
      }
    
      // 关闭Socket
      static close () {
        ws.close();
      }
    }
    View Code

    为了方式测试,我使用另外一个接口调用 ,webapi 作为推送:

     testPush (param, callback) {
        http.post('/Home/PushPoliceInfo', param, function (res) {
          callback && callback(res);
        });
      }
    
    
      let alarms = [{ "EventID": 1, "EventDate": "2019 - 02 - 14 16: 34: 19", "CustomerNo": "普通用户:96719佟国印", "UserType": "1", "AlarmContent": "用水异常没过下限 | 下限读数:5.66666666666667 | 当前读数:0", "AlarmType": "1", "AlarmHandle": null, "AlarmStatus": "1", "ID": 13607, "CreateDate": "2019 - 02 - 14 16: 34: 19", "ModifyDate": "2019 - 02 - 14 16: 34: 19", "Remark": null },
          { "EventID": 1, "EventDate": "2019-02-14 16:34:19", "CustomerNo": "普通用户:96718阮宜华", "UserType": "1", "AlarmContent": "用水异常没过下限 | 下限读数:2.20833333333333| 当前读数:0", "AlarmType": "1", "AlarmHandle": null, "AlarmStatus": "1", "ID": 13606, "CreateDate": "2019-02-14 16:34:19", "ModifyDate": "2019-02-14 16:34:19", "Remark": null }];
          homeServer.testPush(alarms, function () {
    
          });
    View Code

     最终实现效果

     

    后面在同事的电脑上发现 WebSocket不行,经过多次对比排除,发现win 7系统不支持,需要win 8以上 ,以及server 2012 及以上才行。

  • 相关阅读:
    2017年年终总结
    7只老鼠测试100个瓶子
    jgs--多线程和synchronized
    springboot&&vue简单的景点信息管理系统
    springboot&&vue前后端分离入门案例
    npm安装教程
    springboot整合mybatisplus
    spring整合Mybatis-plus
    Springboot简单练手的记账本
    SpringBoot整合thymeleaf简单的CRUD
  • 原文地址:https://www.cnblogs.com/FlowLight/p/10381647.html
Copyright © 2011-2022 走看看