Wcf中部署WebSocket

前言:最近接手了新的项目,一个MVC的Web端页面实时监控并控制着多台机器上面的多个应用程序,及分布式管理,而每台机器上面的应用都部署在计划任务上面,这里用到任务调度器,后续会写一篇总结介绍任务调度器在这里边的用法,每台机器上面都部署一个Wcf服务,即时通信用的SignalR也部署在Wcf中,接手的第一个任务就是把SignalR换成WebSocket。要求:每台机器上的应用运行时调用Wcf服务向web实时发送数据,每台机器上要有一个SocketServer的服务端,这样就避免了高并发;WebSocket框架我选的是Fleck简单易用,单个并发量达到6万多上限也是够用了,再加上异步就绰绰有余。

引包:

因为是在Wcf中部署,所以只需在每次启动服务时打开websocket连接即可:

static List<IWebSocketConnection> allSockets = new List<IWebSocketConnection>();

        public SpiderMonitor()
        {

            var server = new WebSocketServer(AppSettings.SocketUrl);

            server.RestartAfterListenError = true;
            server.Start(socket =>
            {

                socket.OnOpen = () =>
                {
                    allSockets.Add(socket);
                };
                socket.OnClose = () =>
                {
                    allSockets.Remove(socket);
                };
                socket.OnMessage = message =>
                {
                    allSockets.ToList().ForEach(s => s.Send(message));
                };
            });
        }

发送消息:

public void SendMessage(string msg)
        {
            if (!String.IsNullOrWhiteSpace(msg))
            {
                allSockets.ToList().ForEach(s => s.Send(msg));
            }
        }

 

客户端代码:

var lockReconnect = false;  //避免ws重复连接
        var ws = null;          // 判断当前浏览器是否支持WebSocket
        //var wsUrl = serverConfig.socketUrl;
        //createWebSocket(wsUrl);   //连接ws

        function createWebSocket(url) {
            try {
                if ('WebSocket' in window) {
                    ws = new WebSocket(url);
                    
                }
                initEventHandle(url);
            } catch (e) {
                reconnect(url);
                console.log(e);
            }
        }

        function initEventHandle(url) {
            ws.onclose = function () {
                reconnect(url);
                console.log(url+" "+"连接关闭!" + new Date().toLocaleString());
            };
            ws.onerror = function (e) {
                reconnect(url);
                console.log(url+" "+"连接错误!"+ e.reason);
            };
            ws.onopen = function () {
                console.log(url+" "+"连接成功!" + new Date().toLocaleString());
            };
            ws.onmessage = handler;
        }
        // 监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
        window.onbeforeunload = function () {
            ws.close();
        }

        function reconnect(url) {
            if (lockReconnect) return;
            lockReconnect = true;
            setTimeout(function () {     //没连接上会一直重连,设置延迟避免请求过多
                createWebSocket(url);
                lockReconnect = false;
            }, 1000);
        }



        //WebSocket将信息和日志实时推送上来;
        $(function () {
            var strArray = new Array();
            strArray.push('ws://10.88.22.27:5008');
            strArray.push('ws://10.88.22.82:5008');
            strArray.push('ws://10.88.22.38:5008');
            strArray.push('ws://10.88.22.62:5008');
            strArray.push('ws://10.88.22.70:5008');
            strArray.push('ws://10.88.22.19:5008');
            strArray.push('ws://10.88.22.30:5008');
            strArray.push('ws://10.88.22.12:5008');
            for (var i = 0; i < strArray.length; i++) {

                createWebSocket(strArray[i]);
                //console.log(strArray[i] + "开始创建连接");
            }
        });

发布上线时,websocket连接使用规则要跟你的项目的IP一致;即当你项目ip是localhost时,websocket链接也是本地IP,发布上线时同理;

还有一个很重要的,websocket发布时必须绕过代理,否则会连接不上;

 

效果:

 

这里的websocket链接如果不发送消息只能保持一分钟,一分钟后自动断开;如果想长时间保持连接可以定时发送一些空的信息

 

posted @ 2021-08-20 18:30  点终将连成线  阅读(279)  评论(0编辑  收藏  举报