最近遇到一个题目


   用Java语言设计实现一个聊天室系统

   基本功能要求:

   定义好简单的前后台通信协议

   实现注册、登录功能

   实现实时聊天功能

   在linux环境下搭建并运行服务器

   注意代码编程风格、编程规范


   刚开始看感觉并不是很难得东西,但是后来我绕了比较多的弯,可能是当时脑子想别的了j_0013.gif


   定义好简单的前后台传输协议,这个是一个点,但是我被这个问题困扰了很久,主要原因是一直在思考如何通过读取流判断一个次请求结束了,因为我打算用一个socket进行通信,所以我决定试试两种简单方案:

   一种是以键值对形式来传输信息,具体格式是

   10086(四个字节,int类型,为后面内容的长度)PackType(用作识别包的类型,选择合适的)

   key1=value1

   key2=value2

   ......

   因为聊天内容涉及到各种特殊字符所以我用了设定了一个key: content,这个key写在所有key的后面,所以出现这个content后,value的内容就直接读取,不存在转义的问题。


   另一种一种是以xml来传输信息,

   这种没有使用,当时我思考了一下,有这么一个疑问在这里,因为我如果使用xml的话我肯定是使用dom4j,dom4j的原理就是要读取一个xml文件。那么,我没有解决的问题就是一次请求发来,接收到什么时候结束,我就更不知道什么时候是xml文件结束的标志了。后来想想,读取一个根标签对不就结束了么,不过这个可能要自己解析了。


  完成了协议的格式,接下来就是协议的解析了,解析并不难写,所以很快搞定,不过在测试的时候发现了些问题,因为解析存在一些bug导致流阻塞,流读取确实要小心点。


   然后我就开始进行服务端架构进行分析,搞了一个类似于tomcat的东西。而且有application域、session域、request域。


   把上面的代码写好过后,接下来就是对不同的请求代码处理进行实现,现在发现这种架构用起来真方便,写请求处理就如同servlet。


   接下来一个消息群发处理,在application域中设置一个记录上线人的Socket,在发送消息时进行迭代处理,可以将Socket重复利用,不知道这样合不合理,利用socket断线后抛异常来将对应的用户在上线列表里删除掉。或者可以存ip,直接进行一个连接发送UDP协议包也行,这里用UDP比较好。


   然后完成客户端,客户端的登录、注册功能还是比较简单,一次请求、一次响应即可。消息也是,不过这里需要一个接口来完成消息的显示功能。

   不过我很闲的搞了个控制台的客户端,边刷消息,边打字,这好像在一个控制台不可能实现的,于是我就搞了个刷消息时按1 来进行打字,而消息监听暂停,虽然觉得用java/swing一下就搞定的东西,干嘛要用控制台,不过这里因为涉及到了线程,所以我打算复习下。

   因为同时需要在一个控制台中进行消息显示与输入消息,很显然只能让一个线程使用控制台资源,在输入的时候需要消息显示线程暂停。


   下面是我控制线程暂停和开启的方式:


class MessageListenerThread extends Thread{
    private boolean waitFlag;
    ...
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
    //暂停
    public void setWait(){
        waitFlag= false;
    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
    //继续运行
    public void setRun(){
        waitFlag= true;
        synchronized (this){
            this.notify();
        }
    }
    //run方法
    public void run(){
        while(...){
            if(waitFlag){
                synchronized(this){
                    this.wait();
                }
            }
            ...
        }
    }
    ...
}


   消息监听是一个线程,同时另一个线程监听控制台的输入,当输入'1'时,将消息监听线程暂停,输入完毕后,发送消息,并继续运行消息监听线程,这是我程序中的解决方案。


   最近看了看nio技术,好像可以通过nio来提升性能,打算有时间就做一个。


   总结:复习了Socket,线程,IO流。


   初次写服务器,经验太少,希望大家可以对我的小总结提些意见,非常感谢。