目前为了判断客户端是否掉线,我使用的方案是:客户端每秒发送心跳信息,服务器端起一Timer 线程每10s去判读,如果三次都未读到心跳信息,则判断客户端已经掉线,则将该socket 关闭,另外我的通信基于外网环境,在通信中为防止丢包现象,我又使用的方案是:服务器发送聊天信息给客户端,客户端收到信息后反馈接收到的回馈,若服务器端未收到回馈信息则重复发送,三次未收到信息则确定该客户端也已掉线。我的问题是如何由于两种实现都在服务器端线程使用到了readLine()去接收信息,我如何区分是心跳信息还是正常接收到信息后反馈信息,因为同时使用readLine()的话会导致两个阻塞线程去接收信息。各位对这种处理有什么好的建议吗?
解决方案 »
- 在用struts2框架写代码,部署完成,启动tomcat6的时候出现以下异常,请高手帮忙解决一下!
- struts2 action转发到另个action对象参数该怎么传递
- 问一个在页面里遇到的问题~
- 请教一个程序问题
- JAVA在B/S项目中怎样实现打印功能?
- 我部署一个web应用到jboss上,然后报错是 incomplete Deployment listing,是少了那个文件了?
- 紧急了~~~Tomcat突然出现了如下问题
- JDK1.6自带的webservice并发问题
- 各位大哥大姐一定要帮帮我:在JBuildx中创建的CMP实体Bean中增加方法时出错!!!(急!!!)
- (简单问题)写WebWork First Demo时遇到的问题
- 关于HSSFWorkbook生成excel文件,编辑器打开乱码的问题
- 这到底是咋了
最好只有一个线程readline(),然后判断消息类型进行分发处理
String s=io.readline();
if(s.startwith("a")){
//一种消息类型
}else if(s.startwith("b")){
//另一种消息类型
}
心跳不一定靠心跳命令来维持,正常的包过来,应该也算一个心跳包。
曾经看到一种方法,没试过是否可行,LZ可以试试起个线程后,每个一段时间调用socket的sendUrgentData方法,若没有异常,则表示连接是好的,这个方法的好处就是服务器端不会收到客户端的数据,这个前提是禁用OOBINLINE,默认情况下,此选项是禁用的!
心跳信息加个标示位就好,类似楼上的。开始我也用自己完全实现了NIO。瞬间发送上千数据也基本没有丢失。
后面要用Socket传递文件的时候,自己分包装包。最后虽然实现了。但是感觉速度不够。现在我用mina框架。传递文件交给FTP。判断断线有3个,一个是每个连接存在的时候,都放在一个内存里面hashma,value是sesion。然后有个定时器,每n分钟去检查,断了就关闭服务器。
另外还有一个mina提供的sessionIdle,就是一定时间没有受到信息的话,就断开。
第三个自然是客户端主动要求断开的。这样的做法,服务器端一起就2个线程,一个server,一个是定时器的。
没有多线程,性能大大提高。你这样单独的time去检查超时,如果连接大了,容易丢失,速度也不够
建议你读一下TCP的RFC协议关于带外数据
感觉需要反馈的吧,不然丢包了,那么服务器就强断了。应该返回表示收到。比如paypal收费,都是要交互2次确定不丢失
2.至于防止通信中丢包现象,udp的话,应该用stop-and-wait方法去做,即先将要发的包排好序,然后先发一批出去,等待响应,收到后再发一批,至于响应,我觉得客户端返回一个标识即可,而tcp的话,实在不明白为什么要防止丢包,要出现丢包,那是网络问题,是物理层或者网关的问题了,你程序不必关心和解决吧。
3.防阻塞的话用nio吧
4.建议用mina2
java Socket实现心跳保活非常容易,因为java有异常机制。我们可以在服务器端启动一个定时器(Timer类),不停给客户端发消息,如果客户端断开了则服务器会出现异常(IOException等),所以可以根据异常信息判断客户端断开了。同理客户端在接收保活消息时出了相应异常,则断然认为服务器断开了,此时可以关掉socket实例!
谢谢,望高人点评!
这个其实很简单的,使用ObjectOutputStream和ObjectInputStream就可以了,你自定义一个类型,或者干脆就用一个MAP,作为消息的封装工具!
你随便定义一些可被忽略的数据包,比如MSGID==Constant.NULL诸如此类的,你的客户端时不时地发一些这样的垃圾包到服务器,服务器根本不用启动线程,就设置一个读取超时,当超过多少时间没有读到数据包就把它干掉!