你好,欢迎来到电脑编程技巧与维护杂志社! 杂志社简介广告服务读者反馈编程社区  
合订本订阅
 
 
您的位置:杂志经典 / 编程语言
WEB聊天室的四种实现方案及其比较
 

一、基于ActiveX的聊天室

基于ActiveX的聊天室其实现过程类似于前文所述的Java聊天室。在返回给客户端的HTML页面里插入ActiveX控件,该ActiveX控件与Web服务器上运行的专用聊天服务程序进行连接,当客户端用户输入新发言时,发言被传送到聊天服务器并由其广播。和Java Applet一样,ActiveX控件实现了实时聊天。

在网页上使用ActiveX比用Java Applet具有更快的速度和更大的灵活性。因为ActiveX控件下载后,不需要虚拟机解释而是直接执行,如同本机上的应用程序一样。在网页中你可以嵌入各种ActiveX控件(如数据表格、多媒体、图形图象、压缩加密等等),可以方便的将传统应用程序轻松的移植到Intranet/Internet上。它所能实现的功能远远超过现有的各种动态网页技术,包括DHTMLCGIASP等。不过话又说回来,由于ActiveX能够存取客户机的所有资源,所以安全性成为该技术流行开来的最大障碍。当下载的网页中包含ActiveX控件时,浏览器用户必须确认该控件带有可以信赖的公司的电子签名,才敢放心执行。ActiveX的另一缺陷是它只能运行于Windows平台,而且只同IE浏览器配合较好,对于Netscape的用户来说,必须下载专门的PlugIn才能查看ActiveX网页。

我们使用Visual Basic 6来实现聊天服务器和客户端的ActiveX控件。

(1)聊天服务器的编写

新建一个工程,类型为标准EXE,名字为prjChatServer,将主Form名字改为frmServer,其上放置的控件有:

txtLog,类型TextBox,属性MultiLine=True  ScrollBars=Vertical

sktChatServer,类型 Winsock,属性 Index=0

cmdExit,类型 CommandButton

txtLog用于显示各客户连接信息,sktChatServerWinsock控件数组,用于处理与各客户的TCP/IP连接,cmdExit按钮则用于退出系统。

frmServer的代码窗口中加入以下代码:

Option Explicit

Private Const LISTEN_PORT As Integer = 1888  '监听端口号

Private Type ActiveClient_Type

    Connected As Boolean   '是否在连接状态

    ClientIP As String       '客户端的IP地址

End Type

Private gClients() As ActiveClient_Type  '存储所有连接的聊天用户

Private Sub AddLog(sMess As String)  '显示信息

    txtLog.Text = txtLog.Text + sMess + Chr(13) + Chr(10)

End Sub

Private Sub cmdExit_Click()

    Unload Me

End Sub

Private Sub Form_Load()

    ReDim gClients(0)

    sktChatServer(0).LocalPort = LISTEN_PORT

    sktChatServer(0).Listen   '启动服务器

    AddLog "聊天服务器启动,端口号为" + CStr(LISTEN_PORT) + " ..."

End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)

    Dim i As Integer

    '退出时断开所有的连接

    For i = 1 To UBound(gClients)

        If gClients(i).Connected Then

            sktChatServer(i).Close

            Unload sktChatServer(i)

        End If

    Next

End Sub

Private Sub sktChatServer_Close(Index As Integer)

    AddLog sktChatServer(Index).RemoteHostIP + "(" + CStr(Index) + ")" + " 离开了聊天室."

    sktChatServer(Index).Close

    Unload sktChatServer(Index)

    gClients(Index).Connected = False

    BroadCast Index, "离开了聊天室"

End Sub

'接受新用户连接服务器请求

Private Sub sktChatServer_ConnectionRequest(Index As Integer, ByVal requestID As Long)

    Dim i As Integer

    Dim pos  As Integer

    '寻找gClients中是否有空闲的位置

    pos = 0

    i = 0

    Do While (pos = 0) And (i < UBound(gClients))

        i = i + 1

        If Not gClients(i).Connected Then

            pos = i

            Exit Do

        End If

    Loop

    '如果没有,则添加一个新的元素

    If pos = 0 Then

        pos = UBound(gClients) + 1

        ReDim Preserve gClients(pos)

    End If

    '创建Accept该用户的Socket

    Load sktChatServer(pos)

    sktChatServer(pos).Accept requestID

    gClients(pos).Connected = True

    gClients(pos).ClientIP = sktChatServer(pos).RemoteHostIP

    AddLog gClients(pos).ClientIP + "(" + CStr(pos) + ") 进入了聊天室..."

    BroadCast pos, "进入了聊天室"

End Sub

'当客户有消息发出时,将该消息进行广播

Private Sub sktChatServer_DataArrival(Index As Integer, ByVal bytesTotal As Long)

    Dim sTemp As String

    Dim i As Integer

    sktChatServer(Index).GetData sTemp, vbString

    If UCase(CStr(sTemp)) = "QUIT" Then '用户要求退出

        sktChatServer_Close Index

    Else

        BroadCast Index, sTemp

    End If

    AddLog gClients(Index).ClientIP + "(" + CStr(Index) + "):" + sTemp

End Sub

Private Sub BroadCast(idx As Integer, sMess As String)  广播过程

    Dim i As Integer

    For i = 1 To UBound(gClients)

        If gClients(i).Connected Then

            sktChatServer(i).SendData gClients(idx).ClientIP + "(" + CStr(idx) + "):" + sMess

            DoEvents

        End If

    Next

End Sub

其工作原理同前文所述的聊天服务器类似,用一个动态数组存储各个聊天用户的连接状态。当新用户连接时,增加一个Winsock控件,即Load sktChatServer(pos),用于同该用户通信。


运行时的聊天服务器画面如下图所示:

(2)聊天客户端的ActiveX控件的编写

新建一个工程,名字为prjChatClient,类型为ActiveX控件。将工程中的用户控件类命名为MyChat。在MyChat用户控件上放置下列控件:

txtLog,类型 TextBox,属性 MultiLine=TrueScrollBars=Vertical

sktChatClient,类型 Winsock,属性缺省(不用设置)

txtSend,类型 TextBox,属性 Text=127.0.0.1 (默认连接到本机)

cmdConnect,类型 CommandButton,属性 Caption=连接

cmdSend,类型 CommandButton,属性 Caption=发送

txtLog用于显示消息;sktChatClientWinsock控件,用于连接到服务器进行TCP/IP会话;txtSend编辑框有两个作用,在按〖连接〗按钮时是服务器的域名或IP地址(如localhost127.0.0.1),在按〖发送〗按钮时,是该用户要说的话,在实际操作时,可以按回车键发出命令。

MyChat的代码窗口中加入以下代码:

Option Explicit

Private Const REMOTE_PORT As Integer = 1888

Private Sub AddLog(sMess As String)

    txtLog.Text = txtLog.Text + sMess + Chr(13) + Chr(10)

End Sub

Private Sub cmdConnect_Click()

    sktChatClient.Close

    sktChatClient.RemoteHost = txtSend.Text

    sktChatClient.RemotePort = REMOTE_PORT

    sktChatClient.Connect

    AddLog "登录服务器 " + txtSend.Text + "..."

    Do

        DoEvents

    Loop Until sktChatClient.State = sckConnected Or sktChatClient.State = sckError

    If sktChatClient.State = sckError Then

        AddLog "不能登录到服务器!"

    Else

        AddLog "连接成功!"

        cmdConnect.Enabled = False

        cmdSend.Enabled = True

    End If

End Sub

Private Sub cmdSend_Click()

    sktChatClient.SendData txtSend.Text

End Sub

Private Sub sktChatClient_Close()

    AddLog "从服务器断开..."

    sktChatClient.Close

    Do

        DoEvents

    Loop Until sktChatClient.State = sckClosed

    cmdConnect.Enabled = True

    cmdSend.Enabled = False

End Sub

Private Sub sktChatClient_DataArrival(ByVal bytesTotal As Long)

    Dim sTemp As String

    sktChatClient.GetData sTemp, vbString

    AddLog sTemp

End Sub

Private Sub txtSend_KeyPress(KeyAscii As Integer)

    If KeyAscii = 13 Then '回车键

        If cmdSend.Enabled Then '发送

            cmdSend_Click

        Else

            cmdConnect_Click

        End If

        txtSend.Text = ""

    End If

End Sub

所有工作完成后,选择菜单〖文件〗-〖生成prjChatClient.ocx〗生成该ActiveX控件。我们必须使用VB的打包与安装向导来在网上发布这个ActiveX控件。启动VBPackage&Deployment向导,选择工程为prjChatClient.vbp,点击〖打包〗按钮,选择包类型为〖Internet软件包〗,打包向导最终为我们生成prjChatClient.HTMprjChatClient.CAB两个文件。下面我们开始测试,假定在Web服务器中建了虚拟目录chat,将两个文件拷入chat对应的实际目录,在浏览器的地址中敲入http://服务地址/chat/prjChatClient.htm就可以进入聊天,运行时的画面如下所示:


当〖连接〗按钮有效时,表示目前是断开状态,在输入框中敲入服务器名或IP地址再按回车键就可以连接服务器;当〖发送〗按钮有效时,表示目前已经连接到聊天服务器,在输入框中敲入信息按回车键则发送信息到服务器,敲入QUIT则退出聊天室。

需要指出的是,VB的安装向导缺省并未将MSWinsck.OCX(Winsocket控件)VB6的运行库打入CAB安装包中,所以如果别的机器要登录到聊天服务器,则需要mswinsck.ocxvb6的运行库,否则会从www.microsoft.com下载,为了测试方便,可以在安装向导的最后一步选择将winsock.ocxVB6的运行库加入CAB文件,或在客户机上安装vb6

二、基于ASP的聊天室

ASPActive Server Page)因为其使用简单的VBScript语言以及方便的连接后端数据库等特性而成为NT+IIS平台的首选技术。使用ASP编写出的聊天室代码很少,其原理类似前文所述的CGI聊天室,不过聊天信息现在可以不用存放到文件或数据库中,而是存放到Application对象里。

每一个ASP应用(即对应的虚拟目录及子目录)都会有一个Application对象,所有进入该应用的浏览器客户可以存取到共享的Application对象。同时每个客户都有自己的会话对象Session。这样我们可以在Application对象里放置发言缓冲区,在Session对象里放置每个聊天用户的名字。

下面我们来逐步编写一个ASP聊天室,首先在Web服务器上建立一个虚拟目录aspchat,对应c:\aspchat,在c:\aspchat下编写global.asa文件,内容如下:

(1)  初始化 global.asa文件

<script language="VBScript" runat="Server">

Sub Application_OnStart

  Dim gMess(10)

  Application("gMess")=gMess

  Application("gMess_pos")=0

End Sub

</script>

ApplicationgMess变量存储最近的发言(此处最多为10条),gMess_pos表示下一条发言所放的位置。

    (2)C:\aspchat下编写default.asp文件,其实是上下两个Frame

<title>ASP聊天室</title>

<FRAMESET ROWS="*,50">

    <FRAME SRC="mess.asp">

    <FRAME SRC="login.asp">

</FRAMESET>

其中mess.asp用于显示最近的发言,login.asp用于登录及会话。

(3)c:\aspchat下编写mess.asp,在开头放置了定时刷新的HEAD标签:

<html>

<head>

<META HTTP-EQUIV="Refresh" CONTENT="4">

</head>

<body>

<%

Dim gmess

gmess=Application("gMess")

for i=0 to 9   显示缓冲区中所有的发言

     response.write "<p>"&gmess(i)

Next

%>

</body>

</html>

(4)编写登录及会话的login.asp文件

<html><head></head><body>

<%

Dim uname

Dim gmess

uname=Session("UserName")

if uname="" then ' 用户尚未登录

     uname=Request("username") '是否在登录Form中输入了名字

     if uname="" then  '显示Login Form

%>

         <form action=login.asp method="post">

         输入您的名字:

         <input type=text name=username size=20>

         <input type=submit value="进入聊天室">

         </form>

<%

         response.end  '停止ASP输出

     else 'Session变量

         Session("UserName")=uname

         '以下代码显示该用户进入聊天室

         pos=Application("gMess_pos")

         gmess=Application("gMess")

         gmess(pos)=uname&"进入了聊天室"

         pos=pos+1

         if pos=10 then pos=0

         Application.Lock

         Application("gMess_pos")=pos

         Application("gMess")=gmess

         Application.Unlock

     end if

%>

<%

else

     将发言加入Application的发言缓冲区

     mess=Request("Message")

     mess=Session("UserName")&": "&mess&"<font color=green>(时间:"&Now&")</font>"

     pos=Application("gMess_pos")

     gmess=Application("gMess")

     gmess(pos)=mess

     pos=pos+1

     if pos=10 then pos=0

     Application.Lock  为了防止并发写,先锁定

     Application("gMess_pos")=pos

     Application("gMess")=gmess

     Application.Unlock  解锁

end if

%>

<form action=login.asp method="post">

输入您的发言:

<input type=text name=Message size=50>

<input type=submit value="发言">

</form>

</body>

</html>

所有工作完成后,就可以在浏览器中输入http://服务器地址/aspchat/  来测试ASP聊天室了,首先输入名字进入聊天室,然后就可以开始会话。

运行时的画面如下图所示:

 

 


三、总结

    至此,四种常见的聊天室实现方案已经叙述完毕。通过Web聊天室的实现过程可以了解到各种不同的动态网页技术的特点,从而能根据实际应用环境进行正确的选择。下面是这四种方案的比较:

 

比较项目

CGI

Java

ActiveX

ASP

Winxx平台适应性

OK

OK

OK

OK

Unix平台适应性

OK

OK

--

--

IE浏览器适应性

OK

OK

OK(需安全保证)

OK

Netscape浏览器适应性

OK

OK

需安装PlugIn

OK

执行速度

最快

较快

实时聊天

--

OK

OK

--

OK表示此项指标良好,--表示无

 

  推荐精品文章

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

  联系方式
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