一、設計內容及要求
1.1綜述
A.系統概述
我們要做的就是類似QQ這樣的面向企業內部的聊天軟件,基本功能和QQ類似。首先,系統分為兩大部分,第一部分是客戶端,是用戶使用的部分,第二部分就是服務器,所有的客戶端都是通過服務器來進行用戶身份驗證及聊天轉接的。客戶端提供主要的界面及服務請求,如:登錄界面、注冊界面、找回密碼界面、主窗體界面、聊天界面、信息查看界面等。客戶端主要提供服務請求界面,核心的業務邏輯處理主要由服務器提供,並向客戶端發送請求的結果。同時,服務器要能提供服務的開啟、關閉功能及查看在線人數及客戶端登錄日志。
人員組成及分工
張XX(組長):負責整體的架構設計、后台數據庫及通信部分。
房 X(組員):聊天界面、注冊界面、登錄界面、找回密碼、及其業務邏輯。
高 X(組員):主窗體界面、信息查看及其業務邏輯。
B.要求
1).小組成員必須按時完成各自的任務。
2).設計上與技術上有問題的先自行解決(看書、上網查),如不能解決的集體討論解決。有其它的問題及時提出來!
3).必須寫文檔(寫把各自模塊的整體設計用UML圖或Viso畫的圖(盡量不要只是簡單的語言敘述)表達出來),學會用面向對象的思想來來設計,采用模塊化的思想分解模塊。(設計原則與設計模式能用的用)
4).每個類必須有類說明,每個函數也必須有函數說明,函數的具體設計也必須有必要的注釋。
5).如果不能遵守規定或要求的可以提前退出,不強留。
(注:即使不會寫代碼,也沒關系,只要一能用UML圖或其他的圖等表達出自己的設計思想及具體的實現設計也行)
C.開發環境
運行環境:Myeclipse集成開發環境,jdk 1.6版本。
使用語言:Java語言。
使用數據庫:Oracle數據庫。
1.2需求分析
需求背景
即時通信軟件為我們提供了諸多的方便,使我們逐步享受信息時代的便捷。大家最熟悉的即時通信軟件就是QQ了,因為它幾乎已經融入了我們每個人的日常生活。沒有了QQ,沒有了手機,我們或許真的“活不了了”。由此可見,生活在信息時代的人們對即時通信、聊天軟件有巨大的需求,這樣的軟件也將為我們節省大量的時間和金錢,或許還能成為我們發家致富的工具,比如:產品的推介、售后服務及技術交流等。
然而,既然已經有了QQ如此強大的即時通信軟件,我們再去做這樣的軟件還有什么競爭力嗎?QQ已經深入人心,要想再去做可能沒有任何競爭力。此時,我們可以換一個角度,調整用戶對象。如今,企業內部信息在這個信息時代就是金錢,尤其是一些大企業的內部信息,如果這些信息泄露,可能會造成巨大的經濟損失,甚至將導致企業破產。但是,為了便捷企業員工之間的交流,做這樣的一個企業內部即時通信、聊天軟件還是很有市場的。我們的目標就是做的像QQ,但面向企業內部使用。
企業內部為了方便員工之間便捷的交流,需要開發一款適合企業內部員工進行即時通信的軟件,這樣的軟件既滿足了企業內部員工之間便捷的交流,同時,也防止企業內部信息的外流,開發這樣一塊面向企業內部的即時通信軟件,對於企業來說獲益良多。
在開發這款軟件時,為了使習慣了使用QQ的用戶,更加方便的使用本軟件,我們將很大程度上,模仿QQ的用戶界面設計,以適應用戶的使用習慣,方便用戶使用。
功能需求
1)客戶端:提供登錄、主窗體及聊天等界面及對應的業務邏輯,向服務器發送相應的服務請求,並接受相應的處理結果。客戶端是輕量級的軟件,只負責鏈接遠程服務器,並發出相應的服務請求,並不進行核心業務邏輯的處理。具體的處理交給服務器,而客戶端只接收服務器處理的結果並顯示給用戶。
2)服務器:監控登錄信息及在線用戶信息,接收客戶端的服務請求,並做相應的處理,然后將處理結果發送給客戶端。服務器負責處理核心的業務邏輯,並負責連接數據庫,保存和讀取數據。因此,服務器端設計的好壞也直接影響即時通信軟件的質量。
用例描述
1)客戶端:
圖 1-1 客戶端用例圖
2)服務器:
圖 1-2 服務器端用例圖
二、設計原理及方案
2.1總體設計
系統架構設計
1)采用MVC架構模式
客戶端:
A. 包view(視圖、界面層):只負責界面的顯示。
B. 包business(業務邏輯層):核心業務的處理。
C. 包data (數據訪問層):讀寫數據、接收發送數據。
服務器:
A. 包view(視圖、界面層):只負責界面的顯示。
B. 包business(業務邏輯層):核心業務的處理。
C. 包data (數據訪問層):讀寫數據、接收發送數據。
2) 文件組織
A. 客戶端:
圖2-1 客戶端文件組織結構
B. 服務器:
圖2-2 服務器文件組織結構
3) 采用基於網路的三層C/S模式
圖2-3 基於C/S的模式圖
功能模塊設計
1)客戶端:
圖2-4 客戶端功能模塊圖
2)服務器:
圖3-5 服務器功能模塊圖
數據庫設計
1)概念結構設計
圖 2-6 數據庫實體E-R圖
2)邏輯結構設計
用戶表(QQ號、密碼、簽名、頭像編號、昵稱、性別、生日、星座、血型、學歷、電話、郵箱、所在地)
分組表(組號、組名、創建時間、QQ號)
好友表(好友QQ號、QQ號、所屬分組號、添加時間、是否上線)
聊天記錄表(記錄編號、發送者QQ號、接受者QQ號、發送時間、信息編號)
聊天內容(信息編號、內容、字體類型、字體大小、字體顏色)
登錄信息表(登錄編號、登錄IP、端口號、登錄時間、是否在線、QQ號)
QQ群(群編號、群名稱、創建時間)
用戶與群關系(關系編號、QQ號、群編號)
3)表結構設計
表 2-1 用戶與群關系(User_Group)
字段名稱 |
說明 |
字段類型 |
字段長度 |
是否為空 |
約束 |
ugno |
關系編號 |
Number |
2 |
否 |
主鍵 |
|
QQ號 |
number |
5 |
否 |
外鍵 |
gno |
群編號 |
number |
5 |
否 |
外鍵 |
表 2-2 用戶信息表(UserInfo)
字段名稱 |
說明 |
字段類型 |
字段長度 |
是否為空 |
約束 |
|
QQ號 |
number |
5 |
否 |
主鍵 |
pwd |
密碼 |
Nvarchar2 |
10 |
否 |
|
sign |
簽名 |
Nvarchar2 |
30 |
是 |
|
photoID |
頭像編號 |
Number |
2 |
否 |
|
nickname |
昵稱 |
Nvarchar2 |
10 |
否 |
|
sex |
性別 |
Char |
2 |
否 |
男或女 |
birthday |
生日 |
Date |
|
是 |
|
constellation |
星座 |
Nvarchar2 |
60 |
是 |
|
bloodType |
血型 |
Char |
10 |
是 |
A、B、O、AB |
diploma |
學歷 |
Nvarchar2 |
10 |
是 |
|
telephone |
電話 |
Nvarchar2 |
15 |
是 |
|
|
電子郵件 |
Nvarchar2 |
20 |
是 |
|
address |
所在地 |
Nvarchar2 |
20 |
是 |
|
表 2-3分組信息表(Subgroup)
字段名稱 |
說明 |
字段類型 |
字段長度 |
是否為空 |
約束 |
sno |
組號 |
Number |
2 |
否 |
主鍵 |
sname |
組名 |
Nvarchar2 |
20 |
否 |
|
sdate |
創建日期 |
Date |
|
是 |
默認當前日期 |
|
QQ號 |
number |
5 |
否 |
外鍵 |
表 2-4好友信息表(Friends)
字段名稱 |
說明 |
字段類型 |
字段長度 |
是否為空 |
約束 |
Fno |
編號 |
Number |
2 |
否 |
主鍵 |
fqq |
好友QQ |
number |
5 |
|
外鍵 |
fsno |
所屬分組號 |
Number |
2 |
否 |
外鍵 |
fdate |
添加日期 |
Date |
|
|
|
Fstatus |
是否在線 |
number |
2 |
|
|
|
本人QQ |
number |
5 |
|
外鍵 |
表 2-5聊天記錄表(ChatInfo)
字段名稱 |
說明 |
字段類型 |
字段長度 |
是否為空 |
約束 |
cno |
記錄編號 |
number |
2 |
|
主鍵 |
csendqq |
發送者QQ |
number |
5 |
|
外鍵 |
creceiveqq |
接受者QQ |
number |
5 |
|
外鍵 |
cdate |
發送日期 |
TimeStamp |
|
|
|
tno |
信息編號 |
Number |
3 |
|
外鍵 |
表 2-6信息表(Text)
字段名稱 |
說明 |
字段類型 |
字段長度 |
是否為空 |
約束 |
tno |
信息編號 |
Number |
3 |
否 |
主鍵 |
tcontext |
內容 |
Nvarchar2 |
200 |
|
|
tfonttype |
字體類型 |
Nvarchar2 |
10 |
|
|
tfontsize |
字體大小 |
Number |
5 |
|
|
tfontcolor |
字體顏色 |
Nvarchar2 |
5 |
|
|
表 2-7登錄信息表(Login)
字段名稱 |
說明 |
字段類型 |
字段長度 |
是否為空 |
約束 |
lno |
登錄編號 |
Number |
5 |
否 |
主鍵 |
lip |
登錄IP |
Nvarchar2 |
20 |
|
|
lport |
端口號 |
Number |
5 |
|
|
ldate |
登錄日期 |
Date |
|
|
|
lstatus |
是否在線 |
Number |
1 |
|
1 or 0 |
lqq |
QQ號 |
number |
5 |
否 |
外鍵 |
表 2-8 QQ群信息(GroupTable)
字段名稱 |
說明 |
字段類型 |
字段長度 |
是否為空 |
約束 |
gno |
群編號 |
Number |
5 |
否 |
主鍵 |
gname |
群名稱 |
Nvarchar2 |
20 |
否 |
|
gdate |
創建日期 |
date |
|
|
|
通信協議設計
計算機之間傳送數據由兩種,即TCP通信和UDP通信。TCP是可靠的面向連接的通信協議,二UDP是不可靠的面向無連接的通信協議。
1)基於TCP的通信
在進行登錄用戶驗證、添加好友、刪除好友等操作時,采用基於TCP的通信協議。
2)基於UDP的通信
基於UDP通信的基本模式:
(1)將數據打包,稱為數據包(好比將信件裝入信封一樣),然后將數據包發往目的地。
(2)接受別人發來的數據包(好比接收信封一樣),然后查看數據包中的內容。
在進行用戶聊天時,采用基於UDP的通信協議。
緩存數據設計
1) 用戶信息Bean
為了保存用戶及好友的個人信息,此處設計用戶信息緩存數據,當用戶登錄時,將用戶個人及好友的基本信息保存,以備用戶查詢,就不用再次連接數據庫獲取了。
UserInfoBean類:保存用戶QQ號、昵稱、簽名、血型、地址等信息。
2) 消息信息Bean
用戶在進行聊天時,需要傳遞必要的信息,此處的消息Bean數據結構就是存儲收發用戶的QQ號、IP地址、消息內容、字體大小、字體顏色、字體類型等信息。
Message類:保存收發用戶的QQ號、IP地址等信息
2.2詳細設計
系統流程圖
圖 2-7 系統流程圖
設計模式使用
1)中介者模式:
所有的用戶都通過服務器進行通信,服務器其中介的作用。
2)觀察者模式:
當有用戶登錄時,會通知其他在線好友,其他好友及時修改此用戶的在線狀態。
通信協議的實現
2.1.3.1基於TCP的通信
在進行登錄用戶驗證、添加好友、刪除好友等操作時,采用基於TCP的通信協議。
A.客戶端TCP通信設計
設計ClientToServer類,該類實現了Runnable接口,是一個線程。
主要方法:
[1] boolean sendLoginInfoToServer(User u) :登錄請求。
[2] void getProgerties():獲取配置文件中的服務器IP地址信息。
[3] void logout(): 下線,通知服務器該用戶下線。
[4]inttoRegister(UserInfoBean user):新用戶注冊,返回QQ號。
[5] void noticeUpdate():通知刷新好友信息。
B. 服務器TCP通信設計
1)設計ServerThread線程類:處理用戶連接服務器請求,並為其啟動單獨的服務(Server)線程。
主要方法:
[1] void run(): 重寫線程類Thread的方法,不斷的等待客戶端的連接請求。
[2] void pauseThread():暫停服務。
[3] void reStartThread():恢復服務。
2)設計Server線程類:處理每個上線用戶個各種服務請求。
主要方法:
[1] void run():不斷的等待用戶的請求信息,並判斷請求類型。
[2] void login():處理用戶登錄。
[3] void registerNewUser():處理注冊新用戶
[4] void queryUser():處理查詢用戶。
[5] void addFriend():添加好友。
[6] void deleteFriend():刪除好友。
[7] void updateOwnInfo():更新自己的信息。
[8] void logout():下線。
[9] void queryFriend():查詢好友信息。
2.1.3.2基於UDP的通信
在進行用戶聊天時,采用基於UDP的通信協議。
A.客戶端UDP通信設計
設計ClientToServerThread線程類:負責UDP通信。
主要方法:
[1]void run():循環等待監聽發來的數據。
[2]void getPropertieInfo():獲取通信的服務器的IP地址及本機通信端口。
[3]void sendData(byte buffer[]):發送數據。
[4]void Object ByteToObject(byte[] bytes):將Byte數據轉為Object類型。
[5]void ObjectToByte(Object obj):將Object型數據轉為Byte型。
[6]void closeSocket():關閉收發數據報套接字。
B. 服務器UDP通信設計
設計ClientToServerThread線程類:負責UDP通信,主要是轉發用戶發送的信息,並保存用戶的聊天記錄。
主要方法:
[1]void run():循環等待監聽發來的數據。
[2]void getPropertieInfo():獲取通信的服務器的IP地址及本機通信端口。
[3]void sendData(byte buffer[]):發送數據。
[4] void Object ByteToObject(byte[] bytes):將Byte數據轉為Object類型。
[5]void ObjectToByte(Object obj):將Object型數據轉為Byte型。
[6]void closeSocket():關閉收發數據報套接字。
數據訪問層的實現
2.1.4.1 打開數據庫連接類(ConnectionFactory)
[1]void getPropertiesInfo():從配置文件中獲取數據庫連接信息。
[2]Connection getConnection():打開數據庫連接。
2.1.4.2 關閉數據庫連接類(DbClose)
[1]void getPropertiesInfo():從配置文件中獲取數據庫連接信息。
[2]void close(Connection conn):關閉數據庫連接。
[3]void close(PreparedStatement pre):關閉數據庫語句
[4]void close(ResultSet rs):關閉結果集
[5]voidclose(Connection conn, PreparedStatement pre, ResultSet rs)
2.1.4.3 數據操作類(Dml)
[1]void insert(UserInfoBean user):增加新用戶,插入信息。
[2]void update(UserInfoBean user):更新用戶信息。
[3]void delete(int qq):刪除信息。
界面層的實現
2.1.5.1登錄界面
JLoginFrm登陸窗體主要用於用戶登陸,注冊和找回密碼。
內部類:
BackgroundPanel 繼承於JPanel主要用於設置窗體背景圖片
主要函數:
1.actionPerformed(ActionEvent e)主要對窗體的按鍵監聽
2.JLoginFrm()構造函數,控件的初始化。
2.1.5.2注冊界面
JRegisterFrm繼承與JFrame主要用於用戶基本信息的注冊。
主要函數:
1. Void setDay()根據不同的年份和月份設置天數
2.String getBir()以1-1月-2014形式得到用戶的生日
3.getUserInfo()得到用戶的所有信息
2.1.5.3 聊天界面
ChatPanel主要用於用戶間的聊天通信
主要函數:
1、setMessage()設置當前顯示所有會話的面板,不可編輯
2、setSendMessage()設置當前發送消息的面板,可編輯
3、sendMessage()發送消息,講發送消息面板的內容發送到會話面板 和對方。
4、sendFile()傳輸文件
5、sendImage()發送圖片
6、startShake()發送震動消息
2.1.5.4 主界面
主界面的主要內容有QQ頭像設置,包括昵稱、QQ號、簽名的顯示,用戶登錄狀態設置,還有好友列表顯示,像這些創建好友列表所需要的信息是從服務端獲得的;還有一些輔助界面,比如查看好友資料或者查看自己的資料界面,查找好友界面,添加好友界面等。
源碼中的一些主要類及類中的主要方法及其作用:
1.ColorConvertOp類:這個類主要負責顏色轉換的
[1] public ImageIcon getGrayPicture(String path)//該方法獲取圖片路徑,將轉換后的灰色ImageIcon返回。
[2] public class CombListRenderer extends JLabelimplements 2.ListCellRenderer//該類個性化設置combobox的單元格屬性
[1] publicComponent getListCellRendererComponent(JList list,Object obj,int row,booleansel,booleanhasFocus)
//該方法是重寫了ListCellRenderer中的getListCellRendererComponent,返回了一個自定義的Component
3、public class findFriendFrm extends JFrame
//該類負責查找好友界面
[1] public String getName()//獲得找到好友的昵稱或者QQ號
[2] public class InformationFrm extends JFrame
//該類負責顯示好友信息的界面
2.1.5.5 用戶信息界面
好友信息界面主要是將從服務端讀取的好友的個人信息顯示出來。
[1] publicInformationFrm(UserInfoBean userInfo)
//在該構造方法中必須傳入一個UserInfoBean 的對象,此對象中包含了好友的所有信息
[2] public class selectGroupFrm extends JFrame
//該類負責顯示添加好友的一個界面
三、實現效果
圖 5-1 登錄界面
圖 5-2 登錄界面
圖 5-3 注冊界面
圖 5-4 找回密碼界面
圖 5-5 主界面
圖 5-6 信息查看界面
圖 5-7 聊天界面
圖 5-8 消息記錄界面
圖 5-9 服務器登錄界面
圖 5 – 10 服務器管理界面
四、技術難點與解決方案
4.1通信模塊
在通信模塊,我們既使用了基於TCP的通信協議,也使用了基於UDP的通信協議,在登錄驗證、添加好友等通信部分,我們采用了基於TCP的通信協議,在聊天時,我們采用了基於UDP的通信協議,將兩種協議都進行了相應的練習。
4.2數據庫模塊
在數據庫建模時,使用了多張表來存儲數據,使其達到了第三范式,雖然,查詢數據的時候可能會涉及多個表的嵌套查詢,但每個表很單一,擴展靈活。
4.3界面模塊
4.3.1 登錄界面
登陸界面主要使用到自定義最大化,最小化和關閉按鈕,允許鼠標點擊窗體拖動。對輸入的字符進行判斷設置,只允許QQ號碼輸入數字。使用setUndecorated(true);
setResizable(false);設置去除邊框,和不允許改變窗體大小。使用addKeyListener()函數判斷字符輸入只允許輸入數字,使用addMouseMotionListener()方法來允許鼠標點擊任何地方拖動窗體。
4.3.2 主機界面
對一些組件的使用,如在好友顯示列表中需要用到:JTree和JTabbedPane
右鍵好友時會彈出好多菜單需要用到:JMenuItem,JMenu和JPopupMenu在顯示登錄狀態時需要用到:ComboBox但是系統默認的組件外觀往往達不到我們的審美要求,所以我們要對它們的外觀進行個性化設置,所以我們要對其進行重繪,以下是具體實現方法:重寫BasicTreeUI 中的setLeftChildIndent和setRightChildIndent方法,以達到對齊父子節點,重寫了DefaultTreeCellRenderer和DefaultMutableTreeNode來設置JTree帶圖片顯示節點,並且給節點增加了一些我們需要的東西,重寫ListCellRenderer 中的Component getListCellRendererComponent(JList list,Object obj,http://www.hm5656.com/introw,boolean sel,boolean hasFocus)增加在ComboBox顯示圖片的效果。
頭像灰色顯示效果:還有一些圖片處理效果的技術,如QQ頭像去色處理(灰色頭像),其中主要原理就是將頭像圖片中的像素數組取出來,利用一定的顏色變換公式對其顏色進行變換以達到灰顯效果。主要實現代碼見public classColorConvertOp中的 static public ImageIcon getGrayPicture(String path)throws IOException方法
五、總結
張的總結:
通過這次聊天程序課程設計,又有了許多收獲。最初,本來打算做大四學長的“我校淘”網站,但,后來通過與大四學長的交流、溝通,他說三周的時間太短了,因為我們之前沒有接觸過Java Web方面的知識,所以時間不夠,因此,先學習這方面的的知識。
聊天軟件,是我之前一直想完成的一個小軟件,但沒有機會去做,這次有機會做,我決定把它做好,做的像QQ一樣。剛開始,對於網絡通信、數據庫連接及操作這部分,我們之前沒練習過,因此,對於整體的設計都很難把握,我們參考了部分書籍,大概了解了其原理,之后就是確定需求,雖然我們對QQ都很熟悉,也都基本了解其大概需求,但在實際設計時,很多需求方面東西都是看不見的,必須自己查資料、思考、練習才能發掘。然后就是總體設計及人員分工,這一步也很關鍵,如何協調每個人,如何發揮每個人的優勢,這需要很多工作。
在整體設計完成后,我們考慮先開發出簡單的聊天軟件,然后逐步細化,因此,在詳細設計時,我們簡化了一些東西,先開發出一個基本原型,用以驗證技術並進一步明確需求。然后,對部分技術進行改進和細化,最后,再次基礎上不斷的迭代進行,由於我們的水平有限,我們最初的設計並不一定是好的設計,只有不斷的試驗和改進,才能開發出好的軟件,當然,前期的整體架構設計非常重要,這將很大程度上決定軟件的質量和適應需求變更的能力。總之,在試驗與改進中,我們學到了很多東西,不光是技術,還有合作。