怎么设计?
模型会有很多。写一些我看到过的模型吧。大都是C/S模型,分为client端 和 server端,client端通过servet端与其他client端实现通信。
db模型:负责client端的登陆验证等操作。
重点在实现通信的网络模型管理上的不同。一、多线程模型client端登陆的时候会想servet端db验证username和password,验证的时候发起TCP连接返回success的话,就在客户端起动一个线程线程内部run方法不停的循环监听来自服务端的推送信息
要注意的是聊天应用的特性,socket的输入流要监听来自服务端的推送(服务端的推送信息要被展现到client端的聊天界面上),不过还要监听client端本身的输入,在点击发送之后将client端本身的输入通过socket的输出流发送到服务器端,好比cosole界面上也是要有输入的。
在Chat聊天面板的按钮监听中,通过Manager类获得与Chat相关的Socket对象,
在Socket的输出流当中将数据输出
Server端:每个client端与server端建立连接之后都会在server端都建立一个连接线程,线程run方法也是不断监听来自client端的输入,如client1跟server建立连接,client2跟server建立连接,client1在chat面板上输入信息“Hello client2!”,server端接收到信息之后,将检查信息的发送对象是1,接收对象是2,于是找到2跟server端的连接线程,将数据通过2连接线程的socket输出流写出。
简单点对点聊天通信协议:
利用了Java自身的序列化机制,将Message对象通过网络进行传播(首先我们的client端server端都是java写的,所以能无差别序列化反序列化,不过如果不是同一种语言,这种序列化机制会无法使用,此时可以使用xml,json或者protocolbuffer 这样的数据格式进行数据传输,当然,我们自己定义数据格式也是可以的)由于使用java自身序列化方式,所以TCP协议粘包问题这里也不用考虑
message协议的规范大概是登陆注册类型和消息传递类型两种,登陆使用的协议是在登陆注册类型当中其实需要加入一个result字段用于标示成功或者失败,这里当时迷糊使用了Message对象来表示是否登陆成功或者失败,中字段messagetype 1用来成功 2 用来失败
上面都是一些具体实现了,不过题主问的是聊天室,上面讲述的都是点对点的聊天,聊天室,或者说聊天群应该怎么实现呢?在上面的基础之上实现聊天室也很简单,比如建立一个多人聊天室,发送信息的时候使用新的聊天室协议,协议中附带有所有群成员的name,这样就找到所有群成员跟server的连接,将message发送过去就可以了。
二、上面的例子使用了TCP模型,于是可以建立一个client端跟server端的线程,同时建立一个servet端跟client端的线程用于监听socket数据。上面还实现了点对点聊天,正是因为点对点聊天,所以需要启动线程在run方法当中while循环监听socket数据。下面举这个例子‘http://blog.sina.com.cn/s/blog_89429f6d01010xvj.html这个blog上的例子是单独实现了聊天室,但是是有问题的while (true) { //这种不带信息长度的数据读取,在大并发量情况在肯定出问题,因为这个msg读取的可能不只是1条信息,可能多条信息糅杂在一起,也就是TCP粘包问题 String msg = fromserver.readUTF(); if (msg != null) jta1.append(msg + \"
\"); }
Linux下tcp协议socket的recv函数返回时机分析(粘包)
关注我:私信回复“666”获取往期Java高级架构资料、源码、笔记、视频
Dubbo、Redis、Netty、zookeeper、Spring cloud、分布式、高并发等架
构技术