(中國電信荊州分公司,湖北 荊州434020)
隨著互聯(lián)網(wǎng)技術(shù)和計(jì)算機(jī)技術(shù)在不斷進(jìn)步,通過互聯(lián)網(wǎng)進(jìn)行通訊交流的人越來越多,聊天通訊系統(tǒng)也在不斷地優(yōu)化,開發(fā)設(shè)計(jì)技術(shù)也在不斷地提高。下面,筆者基于Java語言對一個小型實(shí)用即時(shí)網(wǎng)絡(luò)聊天通訊系統(tǒng)的實(shí)現(xiàn)展開分析和設(shè)計(jì)。
整個系統(tǒng)的總體實(shí)現(xiàn)如圖1所示??蛻舫晒Φ卿浐髮?chuàng)建一個線程來接收服務(wù)器端的信息并進(jìn)行處理,同樣,服務(wù)器端接收到一個連接后就為這個連接創(chuàng)建一個線程來對客戶的操作進(jìn)行處理。在服務(wù)器端打開之后就創(chuàng)建了一個數(shù)據(jù)源,為客戶服務(wù)的線程在需要訪問數(shù)據(jù)庫的時(shí)候就從服務(wù)器端的數(shù)據(jù)源里取一個數(shù)據(jù)庫的連接來進(jìn)行數(shù)據(jù)庫操作,減少了頻繁的數(shù)據(jù)庫連接和釋放的次數(shù),提高了效率。
圖1 整個系統(tǒng)的總體實(shí)現(xiàn)
客戶端與服務(wù)器端之間的消息都是一個個實(shí)現(xiàn)了Message接口的對象,Message接口有一個方法getType(),該方法返回該對象的類型,在發(fā)送和接收的時(shí)候都是直接對Message類型的對象進(jìn)行操作[1]。這樣的好處就是在接收發(fā)送信息時(shí)可以統(tǒng)一處理。Message接口的定義如下所示:
具體的消息類型都已經(jīng)在PackageType里面進(jìn)行定義,而具體的消息類在構(gòu)造時(shí)就要為type斌一個相應(yīng)的值.目前系統(tǒng)用到的消息類和其相應(yīng)的在PackageType里定義的type值如表1所示。
具體的消息類因?yàn)橐ㄟ^網(wǎng)絡(luò)進(jìn)行發(fā)送因此必須實(shí)現(xiàn)Serializable接口,同時(shí)要實(shí)現(xiàn)Message接口。下面就聊天內(nèi)容消息類對具體消息類的實(shí)現(xiàn)進(jìn)行分析。
表1 消息包和其對應(yīng)的type值
在每個具體消息類里面都有一個成員type,用來標(biāo)識消息的類型,實(shí)現(xiàn)getType方法返回type,同時(shí)type在構(gòu)造函數(shù)中進(jìn)行賦值。
登錄的信息在登錄窗口進(jìn)行輸入,登錄過程則調(diào)用客戶端主窗口的方法來實(shí)現(xiàn),如果成功登錄登錄窗口就退出,顯示客戶端主窗口,如果登錄不成功就彈出提示框,用戶可在登錄窗口修改輸入的信息再進(jìn)行登錄。登錄過程的順序?yàn)椋孩倏蛻舳诉B接服務(wù)器端。用公鑰加密生成的密鑰,把加密的密鑰發(fā)送到服務(wù)器端;服務(wù)器端用私鑰解密接收到的密鑰,設(shè)置加密密碼;②客戶端對用戶的密碼進(jìn)行加密,發(fā)送驗(yàn)證信息;服務(wù)器端驗(yàn)證用戶信息,返回驗(yàn)證結(jié)果,如果失敗就關(guān)閉socket,結(jié)束過程;③客戶端驗(yàn)證失敗就提示失敗,結(jié)束過程;驗(yàn)證成功就顯示主窗口,發(fā)送自己的狀態(tài)信息;服務(wù)器端讀取客戶的狀態(tài),發(fā)送用戶的信息;④客戶端接收自己的信息,存儲下來,服務(wù)器端發(fā)送客戶的好友列表;⑤客戶端讀取好友列表。
注冊的信息在注冊窗口輸入,注冊過程就與服務(wù)器建立一個連接,把注冊時(shí)填的信息通過Regist Message發(fā)送到服務(wù)器,服務(wù)器把注冊信息添加到數(shù)據(jù)庫,然后通過RegistResultMessage返回一個注冊到的號碼給客戶端,如果過程出現(xiàn)錯誤就返回的注冊到的號碼為0??蛻舳耸盏阶越Y(jié)果后把注冊到的結(jié)果顯示給用戶,或者提示注冊不成功。由于在數(shù)據(jù)庫添加記錄后要返回注冊到的號碼,所以在數(shù)據(jù)庫設(shè)計(jì)的時(shí)候hmnum沒有用到自動遞增,而是在注冊的時(shí)候先得到hmnum的最大值,然后把最大值加1作為注冊到的帳號,寫到數(shù)據(jù)庫,同時(shí)把這個號碼返回給客戶端。
聊天部分是系統(tǒng)的核心,涉及到嚴(yán)格的順序控制和許多的細(xì)節(jié)。首先是在客戶端的實(shí)現(xiàn),在好友列表的列表項(xiàng)里保存了所有在系統(tǒng)的使用過程中要用到的信息,有好友的帳號、好友的昵稱、好友的狀態(tài)、好友的頭像、好友的頭像號和與該好友的聊天窗口。收到該好友的聊天消息時(shí),如果與該好友的聊天窗口還沒有初始化,就新建一個與該好友的聊天窗口存儲在好友的列表里,然后把收到消息加入到聊天窗口里;如果與該好友的聊天窗口已經(jīng)建立就直接把收到的消息加入到聊天窗口。如果聊天窗口還沒有打開,就把好友的頭像換成跳動的頭像來提示用戶已收到該好友的聊天信息。如果主窗口已經(jīng)縮進(jìn)到屏幕的上方或者最小化,則系統(tǒng)托盤會有消息框提示收到好友的消息。要打開與該好在的聊天窗口,只要在主窗口雙擊好友的列表項(xiàng)就行了。如果在好友頭像跳動即有收到好友的時(shí)候打開窗口就會顯示已收到的消息,打開聊天窗口后就可以與該好友進(jìn)行聊天。
發(fā)送文件的過來要由發(fā)送端、服務(wù)器和接收端共同協(xié)作來完成,要發(fā)送的文件都通過服務(wù)器來進(jìn)行中轉(zhuǎn)。文件發(fā)送的順序控制為:①發(fā)送端發(fā)送文件信息,要求發(fā)送文件(發(fā)送文件的線程啟動);服務(wù)器端向接收端發(fā)送文件信息,要求發(fā)送文件;接收端選擇接收或拒絕,發(fā)送結(jié)束。②服務(wù)器端如果選擇接收,為傳輸文件創(chuàng)建一個線程,創(chuàng)建serversocket等待發(fā)送端和接收端連接,把serversocket端口發(fā)送給接收端;接收端收到端口,連接到服務(wù)器的serversocket(接收文件的線程啟動)。③服務(wù)器端與接收端連接上,把serversocket端口發(fā)送給發(fā)送端。④發(fā)送端收到端口,連接到服務(wù)器的serversocket;服務(wù)器端與發(fā)送端連接上后,向發(fā)送端發(fā)送一個信息,表示已經(jīng)可以開始發(fā)送文件的數(shù)據(jù)。⑤發(fā)送端收到信息后發(fā)送數(shù)據(jù),開始循環(huán)發(fā)送文件數(shù)據(jù),同時(shí)更新進(jìn)度條和傳輸速度;服務(wù)器端接收發(fā)送端的數(shù)據(jù),再發(fā)送到接收端;接收端接收文件數(shù)據(jù),同時(shí)更新進(jìn)度條和傳輸速度。⑥發(fā)送端傳輸完成,線程結(jié)束;服務(wù)器端傳輸完成,線程結(jié)束;接收端傳輸完成,線程結(jié)束。
[1]Bruce Eckel.Thinking in Java [M].Third Edition.北京:機(jī)械工業(yè)出版社,2004:315-370.