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链接如果不发送消息只能保持一分钟,一分钟后自动断开;如果想长时间保持连接可以定时发送一些空的信息