日期:2014-05-20  浏览次数:20961 次

求助:Java Nio 保持长连接分发消息
最近闲来无事想做个小型的聊天工具,客户端用android已经做好了,跟服务器的交互不想使用Http的方式,改用socket长连接,这样的话消息能及时送达就避免了http不断轮询的消耗。
网上关于Java NIO大部分都是些基础的例子和结构,关于长连接的实在是很少,
现在已经能正常监听请求和读写内容,但是没办法让服务器发送消息到指定的一台或若干台客户端,老的JavaIO可以通过保存Socket,但是nio每次事件都是一个新的SelectionKey,保存了也是旧的(目前的理解),请教各位,如何才能保存下跟每个客户端的会话呢,如下是部分代码

public class SeekServer extends Thread{
private final int ACCPET_PORT = 55555;
private final int TIME_OUT = 3000;
private Selector mSelector = null;
private ServerSocketChannel mSocketChannel = null;
private ServerSocket mServerSocket = null;
private InetSocketAddress mAddress = null;

public SeekServer() {
long sign = System.currentTimeMillis();
try {
mSocketChannel = ServerSocketChannel.open();
if(mSocketChannel == null) {
System.out.println("can't open server socket channel");
}
mServerSocket = mSocketChannel.socket();
mAddress = new InetSocketAddress(ACCPET_PORT);
mServerSocket.bind(mAddress);
Log.i("server bind port is " + ACCPET_PORT);
mSelector = Selector.open();
mSocketChannel.configureBlocking(false);
SelectionKey key = mSocketChannel.register(mSelector, SelectionKey.OP_ACCEPT);
key.attach(new Acceptor());
Log.i("Seek server startup in " + (System.currentTimeMillis() - sign) + "ms!");
} catch (ClosedChannelException e) {
Log.e(e.getMessage());
} catch (IOException e) {
Log.e(e.getMessage());

}

public void run() {
Log.i("server is listening...");
while(!Thread.interrupted()) {
try {
if(mSelector.select(TIME_OUT) > 0) {
Log.i("find a new selection key");
Set<SelectionKey> keys = mSelector.selectedKeys();
Iterator<SelectionKey> iterator = keys.iterator();
SelectionKey key = null;
while(iterator.hasNext()) {
key = iterator.next();
Runnable at = (Runnable) key.attachment();
if(at != null) {
at.run();
}
keys.clear();
}
}
} catch (IOException e) {
Log.e(e.getMessage());
}
}
}

class Acceptor implements Runnable{

public void run(){
try {
SocketChannel sc = mSocketChannel.accept();
new Handler(mSelector, sc);//开始处理这个Channel
} catch (ClosedChannelException e) {
Log.e(e);
} catch (IOException e) {
Log.e(e);
}
}
}
}

------最佳解决方案--------------------
楼主,其实可以不用socket,我们组一直用servlet 3.0的异步功能和android保持长连接的,只需要写一个监听类,然后在请求进来,处理完逻辑后如果不用返回,挂起即可,完全能满足你的需求.
------其他解决方案--------------------
不懂 友情帮顶!
------其他解决方案--------------------
友情帮顶~
------其他解决方案--------------------
sokect 其实我也不懂,  过些天会看看
------其他解决方案--------------------