最近在做一个用到websocket的项目,大体是这样:服务端用的是java开发的web服务,客户端是机床,机床端跑的是用C#技术编写的exe程序,在exe程序中,会有ws连接web服务端,从而web端能监控机床端的状态。(这里并没有涉及到页面js中使用websocket)
服务端要监控客户端遇到一个很让人为难的要求就是“web服务端需要能够感知到客户端的联网和断网状态,进而在后台操作后台数据库”,查过很多资料,websocket端无法感知客户端的连接情况,那么我使用了第一种方式:服务端定时发信息给客户端,如果发不过去,触发onError的方法,那么就在onError中做进一步操作。可是这种方法在线上运行以后很快得到了否定,服务端用的是
public void checkClientLiving(final String cncId){
Runnable runnable = new Runnable() {
public void run() {
while (true) {
// ------- code for task to run
try {
...//具体要做什么
} catch (IOException e1) {
e1.printStackTrace();
}
// ------- ends here
try {
Thread.sleep(5000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
Thread thread = new Thread(runnable);
thread.start();
}
不断的新起来一个线程,增加了服务端的压力,如果哪一个线程出现错误,客户端就算是有重连机制,也连不上了,这样就像一团乱麻。
于是采用了方法二:客户端每10s(举个例子)向服务器端发一个信息,服务端将发这个数据的信息和保存时间存入表中,随后应用用定时任务不断的检查当前时间和刚刚存入的时间的差值:这里用到了这个函数TIMESTAMPDIFF(SECOND, dataEnterTime,now()),如果这个值大于20s,就判定断网。其实就是定时任务开启,不断扫描最后一次发送时间和现在时间的差值,时间太长的话,那就是断了,而不是每次都主动向客户端发信息。
这个问题就解决了!
项目上想通过
websocket
做好友的上线下线通知功能,用户上线时
客户端
websocket
连接
服务端
,调用
服务端
onOpen()方法,
服务端
通知所有好友当前用户上线;用户退出时
客户端
websocket
断开连接,调用
服务端
onClose()方法,
服务端
通知所有好友当前用户离线。
这样做会有一个很大的问题,如果
客户端
是关闭流量、关闭WIFI
断网
而不是正常退出,
服务端
就不会收到
客户端
的断连请求,因此
服务端
并不会触发onClose()方法,导致其好友无法收到当前用户的离线信息。
经过网上大量资
本文只针对于web项目。开始想的是使用
websocket
进行长连接服务,但有个问题就来了,
客户端
异常断电、异常
断网
,比如说我现在把电脑咋了,网线掐了,
服务端
是不知道的,所以无法触发oncolse方法,通道就没办法关闭,该咋办呢?而且还有个缺点,如果用户过多,A用户向服务器发送10000次心跳,那么服务器也要回10000次,压力会很大。
采用心跳机制解决。
客户端
定时向
服务端
发送空消息(ping),
服务端
启动心跳检测,超过一定时间范围没有新的消息进来就默认为
客户端
已断线,
服务端
主动执行clos
因为计算机休眠、网络不稳定等原因,导致实时监视页面的
websocket
数据推送断了,数据不再更新没有实时性。
目的效果:
当
websocket
断开连接时马上重连,依然断开则1分钟后再重连,直到连接成功为止。
注意:当切换页面等正常销毁
websocket
排除在此机制外。可通过设置timerFlagWS以及关闭时的状态码e.code判断
是否
重连。
let websock = null
let socketTimer = null
let socketParam = {
type: 'te
WebSocket
(SuperSocket.
WebSocket
实现)
服务端
主动断开
客户端
的连接
使用SuperSocket.
WebSocket
实现的
WebSocket
服务端
,当有
WebSocket
客户端
连接上以后,
WebSocket
客户端
如果发消息太长或者过大时,就会出现
WebSocket
主动断开
客户端
的连接的问题,解决如下:
using SuperSocket.SocketBase.Config;
using Super
WebSocket
;
using System;
using System.Co