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 及以上才行。

  • 相关阅读:
    Atitit. visual studio vs2003 vs2005 vs2008  VS2010 vs2012 vs2015新特性 新功能.doc
    Atitit. C#.net clr 2.0  4.0新特性
    Atitit. C#.net clr 2.0  4.0新特性
    Atitit.通过null 参数 反射  动态反推方法调用
    Atitit.通过null 参数 反射  动态反推方法调用
    Atitit..net clr il指令集 以及指令分类  与指令详细说明
    Atitit..net clr il指令集 以及指令分类  与指令详细说明
    Atitit.变量的定义 获取 储存 物理结构 基本类型简化 隐式转换 类型推导 与底层原理 attilaxDSL
    Atitit.变量的定义 获取 储存 物理结构 基本类型简化 隐式转换 类型推导 与底层原理 attilaxDSL
    Atitit.跨语言反射api 兼容性提升与增强 java c#。Net  php  js
  • 原文地址:https://www.cnblogs.com/FlowLight/p/10381647.html
Copyright © 2011-2022 走看看