摘要:与一般的ASP聊天室不同,这种聊天服务器是完全独立的服务端程序。当它运行的时候先监听端口,一旦用户通过浏览器访问,便模拟WEB服务器通过HTTP和用户通讯。由于使用了Java技术,所以安全性以及速度上比起一般的ASP聊天室优势明显。
以下列出了eChat聊天服务器的技术特点:
1)跨平台:可以稳定运行在Liunx下
2)多线程:提高了聊天服务器的整体性能
3) Server Push:使客户与服务器处于不间断状态,实现了“无刷新”聊天
一、     主要类的说明
在介绍具体模型之前,我要把涉及到的几个主要类先说明下:
1) ChatServer
整个程序的主线程,由它来控制其它线程的开始
2) TextChatServer
文本聊天线程,以后可以扩展语音聊天等
3) Room
房间类,保存了所有和房间有关的资料(包括房间名、房间端口、用户列表等)
4) RoomListenThread:
房间监听线程,接受所有连接此房间的客户Socket
5) SysMsgThread
系统消息发送线程,通过它向房间广播系统消息(登陆信息或广告)
6) ClientThread
客户连接线程,每个用户都会和服务器建立一个Socket连接
7) ClientManageThread
客户跟踪线程,用来监视客户的连接情况(因为read方法会引起阻塞,所以必须为每个用户分配一个单独线程)
8) User
用户类,保存登陆用户的所以信息
9)Actions
我定义了7种Action,这个类是具体的实现(具体的看第三章)
10)Config.xml
系统配置文件,包括每个房间的详细配置(范例如下)
<配置信息>
<房间>
<房间名称> eChat聊天室 </房间名称>
<管理员> James </管理员>
<讨论主题> 山上的朋友,你们好!</讨论主题>
<端口> 3166 </端口>
<人数限制> 999 </人数限制>
</房间>
</配置信息>
二、     线程模型
线程模型设计如下:
程序运行的流程如下:
1) 聊天服务器主线程从Config.xml中读取所有房间的信息
2) 根据配置文件中的信息分别建立Room对象,并把信息传送给Room对象
3) 根据Room对象中的port属性,建立房间监听线程和系统消息线程
4) 当用户连接服务器时,房间监听线程accept后与客户建立Socket连接,并建立客户连接线程(每个用户都有一个单独的连接线程)
5) 随后要为每个用户建立一个用户跟踪线程来判断是否在线(详细原因看第五章)
这样一个完整的线程模型就建立了,而客户端与服务端此后就通过Socket进行通讯。
三、     Action模型
客户端和服务端之间的交互比较复杂,在这里我定义了7种action并在Actions类中给出了具体的实现。Actions的定义如下:
1)Index:处理 index 动作[登陆区]
2)Main: 处理 main 动作[框架区]
3)Talk: 处理 talk 动作[输入区]
4)list: 处理 list 动作[用户在线列表]
5)Login: 验证用户并登陆
6)Send: 处理发送请求
7)outInfo: 处理 outInfo 动作
每个Actions对应请求页面如下:
客户端与服务端之间通讯是基于HTTP协议,客户端发出连接请求后。服务端返回HTTP消息头。然后,客户端就会发出GET/POST请求。服务端接收到客户端的参数后再根据actions的不同进行响应,并在action中判断是否断开Socket连接。代码片断如下:
    // 返回参数Params
    HttpParser requestParam = new HttpParser (_clientSocket);
    HashMap _param = requestParam.GetParams ();
    // 创建Actions对象
    Actions action = new Actions (_out, _param, _room);
    if ( requestParam.action != null ){
       //System.out.println("acton :"+requestParam.action);
       if ( requestParam.action.equals ("") ){
           action.index ();
           } else if ( requestParam.action.equals ("main") ){
           action.main ();
       } else if ( requestParam.action.equals ("login") ){
           action.login ();
       } else if ( requestParam.action.equals ("talk") ){
           action.talk ();
       } else if ( requestParam.action.equals ("send") ){
           action.send ();
       } else if ( requestParam.action.equals ("chat") ){
           action.chat ();
       } else if ( requestParam.action.equals ("list") ){
           action.list ();
       } else if ( requestParam.action.equals ("outinfo") ){
       // 把这个一直不断开的连接加入User对象
           action.outInfo (_clientSocket);
           return; //不断开连接
       } else{
           // 未知Action就转入index
           action.index ();
       }
    }
    _out.flush ();
    //断开连接
    _clientSocket.close ();
这就是一个完整的动作处理模型
四、     Server Push技术
需要说明下:我实现聊天服务器是用Server Push技术来保证“无刷新”聊天。这种源自Linux下的技术到底是什么?我简单说明下:
Server Push技术的聊天室聊天室基本原理是,不使用HTTP服务器程序,由自己的Socket程序监听服务器的80端口,根据html规范,在接收到浏览器的请求以后,模仿www服务器的响应,将聊天内容发回浏览器。在浏览器看来就象浏览一个巨大的页面一样始终处于页面接收状态。也就是说,我们不再使用CGI等方式来处理聊天的内容,而采用我们自己的程序来处理所有的事务。实际上它就是一个专门的聊天服务器。
说这么多,实际上核心的地方就是:用户请求WEB页面的Socket始终不断开,就像一个巨大的页面始终处于接受状态,这样服务器就可以不间断的向客户端发送聊天信息。下面看看我的具体实现。
我的Actions模型中处理Server Push的是outinfo动作,请注意这里:
} else if ( requestParam.action.equals ("outinfo") ){
       // 把这个一直不断开的连接加入User对象
           action.outInfo (_clientSocket);
           return; //不断开连接
我在关闭Socket连接之前就return了,所以这个请求的Socket始终保持接受状态。我可以源源不断地写入信息,这就是Server Push技术的一种应用。
五、     判断用户断线
判断用户是否短线是个比较棘手的问题。(我一直没有找到更好的方法,只能用老土方法了)
当用户正常关闭浏览器或者把页面转到其他地方时,客户端和服务端一直保持连接的Socket实际上并没有断,只是不能够进行写操作。所以可以用以下代码判断:
try{
    BufferedInputStream _in;
    _in = new BufferedInputStream (clientSocket.getInputStream ());
    // read()方法会引起阻塞,所以必须为每个用户分配一个单独线程(会影响效率)
    _in.read ();
} catch ( IOException e ){
    DelUser (clientSocket);
}
当read方法发生异常时可以捕捉到,然后把用户删除掉。头疼的是read()方法是阻塞的(可以用Java.NIO解决)如果用一个线程来管理显然不合适,所以我给每个用户线程又配了个跟踪线程,你要阻塞就去阻塞吧只要不影响别人就行~~
六、     结束
这里我写的还比较简单,如果您有兴趣可以去我的网站和我交流。
聊天服务器的源代码也可以在http://www.chenshen.com下载。
关于作者:
沈晨,James,高级程序员,SCJP
www.chenshen.com
James@njut.edu.cn

用Java实现的eChat聊天服务器相关推荐

  1. java搭建聊天服务器_使用 ServerSocket 建立聊天服务器-2

    1. 从serverListener中可以看出,每一个客户端创建新的请求之后,都会把它分配给一个独立的chatsocket ,但是每一个ChatSocket都是相互独立的,他们之间并不能沟通,所以要新 ...

  2. 局域网服务器发送消息,Java实现简单局域网聊天室

    本文实例为大家分享了Java实现简单局域网聊天室的具体代码,供大家参考,具体内容如下 Java 的Socket编程: 1.TCP协议是面向连接的.可靠的.有序的.以字节流的方式发送数据,通过三次握手方 ...

  3. Java实现即时聊天:聊天服务器+聊天客户端+Web管理控制台

    来源:cnblogs.com/blogtimes/p/14767484.html 一.前言 说实话,写这个玩意儿是我上周刚刚产生的想法,本想写完后把代码挂上来赚点积分也不错.写完后发现这东西值得写一篇 ...

  4. 使用JAVA建立稳定的多线程服务器

    2002 年 7 月 03 日 本文详细的介绍了使用Java语言建立一套多线程服务器的过程,该服务器使用对象传递消息,在线程中使用队列机制,使服务器的性能大大提高了.这套服务器可以被用于各种C/S或B ...

  5. 服务器收到消息加入数组,从聊天服务器发送到聊天客户端的数组更新

    我发现了一个聊天服务器的代码,我有一个简短的问题.这是关于以下摘录:从聊天服务器发送到聊天客户端的数组更新 clientOutputStreams.add(作家); 显然,这种字符串数组应该被发送到聊 ...

  6. java大作业网络聊天室

    这个项目是我大一的java期末大作业,学习了一个学期的成果,编程能力不够,做的并不够好,写在这里记录一下自己的成长,也欢迎大家给出宝贵意见! 第一次写博客哟,请多多支持! 该篇博客写一个基于java的 ...

  7. 实战即时聊天,一文说明白:聊天服务器+聊天客户端+Web管理控制台。

    目录 一.前言 二.最终效果 1.聊天服务器 2.聊天客户端 3.Web管理控制台 三.需求分析 四.概要设计 1.技术选型 1)聊天服务端 2)Web管理控制台 3)聊天客户端 4)SpringBo ...

  8. 聊天服务器 单机性能,环信即时聊天服务器

    环信即时聊天服务器 内容精选 换一换 本章节通过示例项目"小蝌蚪即时交互游戏"介绍如何使用DevCloud开发基于PHP语言的H5应用.项目名称:小蝌蚪即时交互游戏.项目简介:小蝌 ...

  9. java tcp多人聊天室

    TCP的多人聊天室 上次写了一个只能两个人通信的TCP,这次写了个可以多人聊天的,利用多线程实现. 设计模式: 服务端:首先运行服务器,然后启动一个专门处理客户端消息的线程,然后监听是否有客户端连接, ...

最新文章

  1. 索引中丢失 IN 或 OUT 参数:: 103,解决办法
  2. Spring IOC 容器源码分析系列文章导读
  3. 自定义字符串查找函数c语言,(C语言自定义函数,/*编写函数实现在字符串pStr中查找子串pSub int subString( char* pStr, char* pSub);...
  4. 一篇来自前端同学对后端接口的吐槽
  5. js执行环境作用域和闭包_JavaScript中执行上下文,提升,作用域和闭包的终极指南
  6. 描写计算机老师上课的神态,请你用一段话描写一位老师上课的情景,注意抓住神态语言动作等细节...
  7. crc16码表的使用_查表法计算CRC16校验值
  8. java获取access token_微信java 开发4 access_token获取
  9. arduino eeg脑电模块_应用深度学习EEGNet来处理脑电信号
  10. linux文件管理命令详解
  11. 如何给计算机关闭网络连接,win10系统的电脑怎么把网络连接关闭?
  12. KU FPGA DDR4 SDRAM仿真/板卡测试
  13. 硬盘结构及raid磁盘阵列
  14. 蓝桥杯:调和级数————Python
  15. codeforces 869E The Untended Antiquity
  16. 2021年危险化学品经营单位主要负责人考试报名及危险化学品经营单位主要负责人复审考试
  17. ∑-Δ 型ADC原理
  18. 基于51单片机的自动红外感应洗手器proteus仿真程序设计
  19. php实现等比例缩放图片
  20. 关于IDEL中出现No module named requests错误

热门文章

  1. 博弈论_奇偶性、单向行走
  2. 天猫店群比淘宝店群好做吗?同是无货源差距为何那么大,个人分享
  3. Java开发的基中之基
  4. PTA 选择结构 7-1 能买手机吗?
  5. vue常用的时间、手机号等的格式化方法
  6. WPS文档出现很多小箭头解决
  7. 可视为线性回归的曲线回归(R语言)
  8. 年薪30万只是中游水平,算法工程师是一种怎样的存在?
  9. 在浏览器查看base64格式的图片
  10. qq空间播放器肤代码