用Java实现的eChat聊天服务器

原创 2003年08月17日 16:24:00

Java实现的eChat聊天服务器<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

James @ www.chenshen.com

 

摘要:与一般的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

用户类,保存登陆用户的所以信息

9Actions

我定义了7Action,这个类是具体的实现(具体的看第三章)

10Config.xml

系统配置文件,包括每个房间的详细配置(范例如下)

<配置信息>

    <房间>

       <房间名称> eChat聊天室 < SPAN>房间名称>

       <管理员> James < SPAN>管理员>

       <讨论主题> 山上的朋友,你们好!< SPAN>讨论主题>

       <端口> 3166 < SPAN>端口>

       <人数限制> 999 < SPAN>人数限制>

    < SPAN>房间>

< SPAN>配置信息>

 

二、     线程模型

线程模型设计如下:

<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />CSDN_Dev_Image_2003-7-41203560.gif

程序运行的流程如下:

1)  聊天服务器主线程从Config.xml中读取所有房间的信息

2)  根据配置文件中的信息分别建立Room对象,并把信息传送给Room对象

3)  根据Room对象中的port属性,建立房间监听线程和系统消息线程

4)  当用户连接服务器时,房间监听线程accept后与客户建立Socket连接,并建立客户连接线程(每个用户都有一个单独的连接线程)

5)  随后要为每个用户建立一个用户跟踪线程来判断是否在线(详细原因看第五章)

这样一个完整的线程模型就建立了,而客户端与服务端此后就通过Socket进行通讯。

 

三、     Action模型

客户端和服务端之间的交互比较复杂,在这里我定义了7action并在Actions类中给出了具体的实现。Actions的定义如下:

1) Index: 处理 index 动作[登陆区]

2) Main: 处理 main 动作[框架区]

3) Talk: 处理 talk 动作[输入区]

4) list: 处理 list 动作[用户在线列表]

5) Login: 验证用户并登陆

6) Send: 处理发送请求

7) outInfo: 处理 outInfo 动作

每个Actions对应请求页面如下:

CSDN_Dev_Image_2003-7-41203562.gif

 

 

CSDN_Dev_Image_2003-7-41203564.gif

 

客户端与服务端之间通讯是基于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("<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />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

July 3, 2003

Java 利用 Socket 实现服务器客户端聊天

Socket是网络编程中最基本的通信接口,常用的网络辅助类,比如URL等之类,其底层还是基于Socket来实现的。 而Socket,形象来说,就是连接通信的两端,比如这样 SS,中间的通道就是网络了,...
  • foolsheep
  • foolsheep
  • 2014年05月15日 00:03
  • 3348

【Java】Java多线程实现的聊天客户端和服务器

主要涉及知识 ·Java中GUI程序的编写,包括事件监听机制。 ·Java的网络通信编程,ServerSocket,Socket类的使用。 ·Java中多线程的编程,Thread类,Runnable接...
  • White_Idiot
  • White_Idiot
  • 2016年10月14日 13:22
  • 3433

java类似QQ的聊天室程序的实现(下)(服务器端程序)

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.i...
  • u012429555
  • u012429555
  • 2016年05月10日 19:48
  • 1377

用Java实现的eChat聊天服务器.docx

  • 2011年02月28日 20:59
  • 194KB
  • 下载

通过java编写客户端,服务器程序,实现聊天功能

  • 2009年09月04日 15:54
  • 1KB
  • 下载

java实现服务器,android上客户端,实现聊天

  • 2012年12月06日 13:07
  • 53KB
  • 下载

java 高仿QQ8.x版聊天室好友列表+服务器实现

  • 2016年06月30日 16:29
  • 3.99MB
  • 下载

java Smack整合Openfire服务器实现IM即时通讯聊天功能

原文:java Smack整合Openfire服务器实现IM即时通讯聊天功能 源代码下载地址:http://www.zuidaima.com/share/1816369152052224.h...
  • yaerfeng
  • yaerfeng
  • 2016年07月12日 09:55
  • 3935

Java 网络编程(TCP)实现服务器与客户端1对多的随意顺 序的聊天室

要求:任何一个客户端说的任何一句话,都会转发给所有客户端,(并在服务器端记录在聊天文件中,包括聊天时间信息.服务器只转发,不参与聊天.) (每一个参与聊天的客户端要有自己的名字.在进入聊天室的时候输...
  • Generationlong
  • Generationlong
  • 2015年07月12日 19:35
  • 2557

JAVA作业 sockect编程实现聊天室(一服务器多客户端)

题目:利用多线程、Socket编程、GUI编写一个聊天室,客户端可以发送信息,服务器将接收到的每个用户端的信息实时发送给其他客户端。(提示:服务器为每个客户端启动一个单独线程,客户端启动一个单独线程接...
  • Sugar_girl
  • Sugar_girl
  • 2016年12月20日 19:45
  • 269
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:用Java实现的eChat聊天服务器
举报原因:
原因补充:

(最多只允许输入30个字)