你好,欢迎来到电脑编程技巧与维护杂志社! 杂志社简介广告服务读者反馈编程社区  
合订本订阅
 
 
您的位置:杂志经典 / 编程语言
基于Java的Web聊天室系统(下)
 

public void broadcast(String s) throws IOException  //广播过程

    {

        Enumeration e=chatusers.keys();

        while(e.hasMoreElements())  {

            String key=(String)e.nextElement();

            Connection c=(Connection)chatusers.get(key);

            c.out.writeUTF(s);

            c.out.flush();

        }

    }

}  

四、客户端的Java Applet

当含有Applet的页面传送到客户的浏览器时,Applet被解释执行。Applet有一个参数(PARAM)为username,代表聊天用户的代号。当Applet初始化同服务器进行连接时,发送一条形式如$username…的消息,告诉服务器聊天用户的名字。聊天用户可以输入list命令来列出当前聊天室的用户(参见前面的Connection线程的代码)。客户端Applet启动了一个StreamListener的线程专门用于从服务器获取消息并显示在Applet的发言区。

虽然我们可以正确的传输与显示中文,但在Java AppletText类组件中不能输入中文的现象仍然存在,尤其是在IE浏览器上。这个问题产生的根源不是Java语言本身或者我们所编写的代码不正确,而完全是Microsoft VM for JavaBug。对于使用IE的用户来说,在Web上的Java聊天室输入中文是麻烦的,需要通过拷贝/粘贴方式把汉字贴入AppletTextField。对于这个问题,我们可以使用一个基本的技巧来解决。那就是不使用JavaTextFieldTextArea类进行输入,而是依靠HTML页面中的表格(Form)的Text元素进行输入,然后把输入结果传递给Applet。传递的方法是在HTML页面里加入JavaScript程序,与该页面的Applet进行通讯。

对于客户端Applet来说,进行必要的资源清理工作尤为重要。在HTML页面的生存期内,Applet执行的顺序一般是:init()start()stop()destroy()。所以我们必须在Appletstop()方法中进行资源清理工作,此外,当与聊天服务器连接中断(如服务器down机或因超时被服务器踢出时),也要进行相应的清理工作。这样,客户端的系统资源不会丢失(如内存泄漏leak),而且服务器端也能够迅速掌握客户端的状态。

客户端的主要代码段及解释如下:

⑴登录页面default.asp

该页面将登录用户的用户名动态的传递给Applet,这是通过插入ASP脚本[3]实现的。如果不用ASP,也可以使用JavaScript编写一个弹出的输入对话框让用户输入名字。

<HTML><HEAD><TITLE>聊天室</TITLE>

<script language="javascript">

function SendIt() //Form的输入传递给Applet

{

document.AppletClient.SendToServer(document.CHATFORM.textField.value);

document.CHATFORM.textField.value="";

}

function ClearDisplay() //调用AppletClear过程清除发言显示区

{ document.AppletClient.Clear(); }

</script></HEAD><BODY>

<%

If trim(request("username"))="" then

'显示用户登录Form

%>

<form name="LOGINFORM" action="default.asp">

<font style="font-size:14">输入你的代号:</font>

<input type="text" name="username" size=20 style="font-size:14">

<input type="submit" value="进入聊天室" style="font-size:14">

</form>

<%

else  '否则显示聊天Form

%>

<APPLET CODE="ChatClient.class" name=AppletClient WIDTH=500 HEIGHT=300>

<PARAM name="username" value="<%=request("username")%>">

</APPLET>

<form name="CHATFORM" onSubmit="SendIt();return false;">

<input type="text" name="textField" size=40" style="font-size:14">

<input type="button" value="发送" onClick="SendIt()" style="font-size:14">

<input type="button" value="清除显示区" onClick="ClearDisplay()" style="font-size:14">

</form>

<% end if%></BODY></HTML>

Applet的定义及初始化

public class ChatClient extends Applet{   

   public final static int PORT=6543;

   public Socket s=null;

   protected DataInputStream in=null; // 读缓冲

   protected DataOutputStream out=null; // 写缓冲

   protected TextArea outputarea; // 显示发言的区域

   protected StreamListener listener=null; //监听线程用于显示服务器发回的消息

   protected String username; //聊天用户名

   public void init()  { //Applet的启动过程

       super.init();

       username=getParameter("username"); //获取用户名参数

       outputarea=new TextArea();

       outputarea.setEditable(false); //仅用于显示

       this.setLayout(new BorderLayout());

       this.add("Center",outputarea);

       try{ //进行连接

           //由于Applet的安全限制,只能同下载服务器进行连接

           s=new Socket(this.getCodeBase().getHost(),PORT);

           in=new DataInputStream(s.getInputStream());

           out=new DataOutputStream(s.getOutputStream());

           listener=new StreamListener(in,outputarea,this);

           outputarea.appendText("连接到服务器

"+s.getInetAddress().getHostName()

               +":"+s.getPort()+"\n");

           outputarea.appendText("使用list命令列出当前聊天室的用户\n");

           out.writeUTF("$username"+username); //登录用户名

           }

       catch(IOException e){

           outputarea.appendText("错误:不能与聊天服务器进行连接\n");

       }

   }

⑵提供给JavaScript调用的过程

public void SendToServer(String s)     {

//此过程供网页内的JavaScript程序调用,将发言s发送到服务器

try{

Date nowTime=new Date();

//将当前时间插入发言,时:分:秒

String chattime=nowTime.getHours()+":"+nowTime.getMinutes()+":"+nowTime.getSeconds();

out.writeUTF(s+"   ("+chattime+")");

}

catch(IOException e){ outputarea.appendText("错误:不能发送消息到聊天服务器\n");}

}

public void Clear() //此过程供网页内的JavaScript程序调用,清除显示区

{  outputarea.setText("");     }

⑶线程中止Stop()过程

   public void stop()  {

       //释放相关资源

       if(listener!=null)  {  //中止输入流监听线程

           listener.stop();

           listener=null; }

       try{    if(s!=null) s.close();  } //关闭Socket

       catch(IOException e)

       { outputarea.appendText("错误:无法关闭Socket\n"); }

       s=null;

       outputarea.appendText("释放资源\n");

       super.stop();

   }}

⑷输入流监听线程StreamListener

class StreamListener extends Thread{

   ……

   public void run(){

       String line;

       try

       {

           for(;;){

               line=in.readUTF();  //读输入

               if(line==null) break;

               //将服务器发回信息添加到textarea显示区

               output.appendText(line+"\n");

           }

       }

       catch(IOException e){}

       finally{  //清理工作

           try{

               if(app.s!=null) app.s.close(); //关闭socket

           }catch(IOException e2)

           { output.appendText("错误:无法关闭Socket\n"); }

           app.s=null;

           output.appendText("与服务器连接断开,释放资源\n");

       }}

}

五、试验结果及结论

整个Java聊天室系统的程序在Visual J++ 1.1下编译运行通过,服务器端安装NT Server 4.0IIS 4.0,运行聊天服务器。客户端使用NetscapeIE浏览器进行连接。试验证明,该聊天室系统解决了在Java语言中的中文传输、显示及输入问题。该聊天室系统具有高效性、健壮性和灵活性,达到了预期的设计目标。读者可以在此基础上进一步增加功能,如建立私有聊天房间、用户间互送消息甚至将聊天室该为虚拟图形版等等,Java语言将会带给程序员更多的想像与发挥余地。

参考文献:

1           Introduction ,JDK 1.1.6 Online DocumentSun1997

2           Java Language SpecificationVisual J++ Online HelpMicrosoft1997

Active Server Pages帮助,Microsoft Developer NetworkMicrosoft1998
  推荐精品文章

·2024年9月目录 
·2024年8月目录 
·2024年7月目录 
·2024年6月目录 
·2024年5月目录 
·2024年4月目录 
·2024年3月目录 
·2024年2月目录 
·2024年1月目录
·2023年12月目录
·2023年11月目录
·2023年10月目录
·2023年9月目录 
·2023年8月目录 

  联系方式
TEL:010-82561037
Fax: 010-82561614
QQ: 100164630
Mail:gaojian@comprg.com.cn

  友情链接
 
Copyright 2001-2010, www.comprg.com.cn, All Rights Reserved
京ICP备14022230号-1,电话/传真:010-82561037 82561614 ,Mail:gaojian@comprg.com.cn
地址:北京市海淀区远大路20号宝蓝大厦E座704,邮编:100089