我写了个消息转发程序,也加了心跳处理,1分钟没读写操作的用户自动被踢下线.
可是现在遇到一个问题,如A用户要发送消息给B用户,通过服务器中转,
服务器在接收到A的消息时,B用户实际已经断网了(我把B用户的网线拔掉了),
这时服务器既然是不知道的.
[code="java"]
ChannelFuture writeFuture = channel.write(msg);
final Channel sendChannel = ctx.channel();
writeFuture.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
if (future.isSuccess()){
sendChannel.write(JSONResult.getSuccess());
System.err.println("future.isSuccess()");
}
if (future.isDone()){
sendChannel.write(JSONResult.getSuccess());
System.err.println("future.isDone()");
}
if (future.isCancelled()){
sendChannel.write(JSONResult.getSuccess());
System.err.println("future.isCancelled()");
}
}
});
[/code]
operationComplete都会返回成功..只有到了1分钟的时候,服务器才回把B用户踢下线.我要怎么才能在服务端判断B用户实际已经掉线了??
你这种情况属于正常的,没有问题。
客户端异常掉线,比如断开网线或者断电等情况下,客户端的channel对象不会自动关闭,所以才引入了心跳的机制,也就是服务器端通过监测在心跳期间内(1分钟)是否收到了客户端发过来的消息,来判断是否可以和客户端进行通信,如果没有收到任何消息,则视为客户端掉线。心跳机制就是为了解决你说的这个问题的。
不光是netty,所有基于socket的通信都有这个问题,因为客户端和服务端是基于消息的协议,只有客户端主动发出断开的消息给服务端,服务端才能明确知道客户端断开了连接,直接拔掉网线或者断电的情况下,属于底层的异常,客户端程序是根本监测不到的,即使你的客户端程序能够监测到,也没有用,因为此时网线已经被拔掉了,根本没法给服务端发送消息。所以服务端才引入了心跳机制来对应这种异常情况,相当于超时机制,超过规定时间没有接到消息,就视为客户端掉线了,以释放服务端的资源。
相当于两个人通话,对方突然把手机电池拔掉了,一点声音也没有,持续了1分钟,你这边肯定是不知道他那边出了什么状况,最后你肯定就挂机了,不可能傻等着,呵呵。
详细情况可以看一下下面的文章,里面有异常掉线的解释:
[url]http://vanadiumlin.iteye.com/blog/1276757[/url]
楼上给的很全,,楼主仔细研究下吧.不是很复杂的