本章节要实现的效果如下:
本章代码基于 第四章;在第四章中,我们已经学会了服务端和客户端之间的双向通信;已经为多人聊天室打下了基础;
在这章我们只需要修改一些代码即可;
首先,实现之前,先考虑数据怎么在 客户端和客户端之间传递?;
- 自己当服务端又作客户端?
- 消息统一发送到客户端,由服务端再传递给另外一个客户端
从上面的思考中,明显选择第二个方案;如果自己做服务端有做客户端,逻辑判断方面可以把自己搞死;所以我们的做法也是基于第二种,比较出名的 socket.io 也是采用这种方案;关于 socket.io 可以参考我的这篇博客 Android 使用socket.io 实现实时通信 ;基于 nodejs 搭建个服务端,你能快速实现一个多人聊天室。
一、代码实现
废话不多说,在第四章的代码上,修改服务端的代码,当有消息时,用接口传递出来,在消息获取中,添加接口传递出来:
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
do {
String msg = br.readLine();
if (msg != null){
//System.out.println("client: "+msg);
//把从客户端接收到的数据,传递出去,以便发送给其他客户端
if (mListener != null){
mListener.newMsg(ClientDataHandle.this,msg);
}
}else{
System.out.println("连接已断开");
break;
}
} while (!isFinish);
然后回到 TcpServer 这个类:
@Override
public void newMsg(final ClientDataHandle handle, final String msg) {
System.out.println(handle.getInfo()+" say: "+msg);
mExecutorService.execute(new Runnable() {
@Override
public void run() {
for (ClientDataHandle clientHandle : mClientHandles) {
if (clientHandle == handle){
//跳过自己
continue;
}
//发送给其他客户端
clientHandle.sendMsg(msg);
}
}
});
}
可以看到我们的改造还是很快的,只需要判断是否是自身,如果不是,则通过服务端发送给其他客户端,这样就实现了我们刚才的思路; 客户端 - 服务端 - 客户端。
二、性能问题
从代码来看,为了并发问题,我们开辟了很多线程来实现 并发问题;在服务端中,发送一个线程,接收一个线程,每一个客户端进入,线程的数量都是 2n+ 的增长;这样对 cpu 和内存的消耗是很多的;
当然,你可能会说,我们用固定线程池来优化,是,这样是能解决一下,但是量的取舍又是一个问题;当然google 也意思到了这个问题,NIO 就是为了解决 socket 的并发而出现的。
这里我们也不过多去优化了,socket 的学习就到此为止了,后面我们将学习 NIO ,为文件快传这个实例做准备。