对于基于web层的聊天室已经不是新鲜事了,但是用Java开发的还是比较少。原因可能是没有一套好的实现机制,我现在就分享一下个人几个月前的一点心得,也算是抛砖引玉了.
基本功能如下:分频道聊天对话,分频道分屏显示,表情符号处理,扩展性还是比较强的
众所周知,实现聊天无非2种方式,1种是保持长连接,1种是使用AJAX定时发送请求即客户端将数据从服务器拉过来.由于对SCOKET的一些异常错误处理自己还不是很熟悉,因此采取的是第2种自己熟悉的方式.
设计思路如下:
1.在WEB层提供一个类似VO的JAVABEAN(也可作为JSON BEAN),提供一些属性封装数据,一个对象代表1条消息
2.利用一个工具类计算聊天索引号例如一个单例类,每个用户进入聊天室后会取得当前最大的索引号放入SESSION作为自己的索引号,当发送消息时索引号会增加并且更新当前用户的聊天索引号
3.实现一个MAP结构来保存聊天记录并放入APPLICATION,我使用的是TREEMAP,键为聊天索引号,值为聊天对象
4.通过聊天对象的属性判断来按频道以及按用户的信息区分显示,通过用户当前的聊天索引号和当前最大的聊天索引号的比较来控制给用户显示N条之前的信息(即进入聊天室后可以看到多少条以前的信息)以及在聊天信息栏里保持显示的N条信息(也可手动清屏).
5.开启一个线程定时清除集合里的聊天对象,也可同时持久化形成聊天记录
6.客户端利用定时器每隔几秒向服务器端发送刷新聊天信息的请求,根据配置由服务器端将N条信息以构造好的HTML格式的字符串的形式发送给客户端显示在一个DIV中
基本思路就是以上,经过实际测试,目前是单台TOMCAT至少能支持350人在线聊天,再多的因为没实际环境,即使使用LoadRunner也得不到太准确的结果.可以扩展的功能有客户端实现字体的改变以及聊天记录查看.
做这个的过程中我的感觉如下:对于多从事企业级开发的JAVA程序员来说,已经自然地会在实现过程中按照J2EE的分层体系进行划分:WEB层 业务层 持久层,或者通过对DDD的学习以及SSH等FRAMEWORK的使用,已经形成了VIEW-ACTION-SERVICE-DOMAIN OBJECT-DAO的定式(实际上SPRING并不是一个支持DDD的FRAMEWORK).但是如果不注重CACHE的使用以及真正在分析和设计时使用DDD(例如采用聚合根控制对整个聚合对象的访问实现针对聚合对象CACHE的FLUSH)的方式,很容易陷入以DB为中心的思考方式,即"80%的业务都是CRUD 90%的业务都必须和DB交互",这是第1点.第2点,比如在做WEB2.0,甚至游戏这种对数据的即时性要求很高,大部分操作在内存的系统的时候,没有了DAO或者不需要频繁调用DAO,应该怎样分层.比如在做这个聊天程序的时候,第1版完成时我发现由于没有DAO,因此没有第1时间就将业务逻辑从控制器中分离,即SERVLET里有很多和业务相关的代码,最后通过不断地重构分离了,不过还是看得出自己的OO思维还不够成熟.