如何從零開始寫一個即時通訊軟件(附源碼)

       即時通訊,即發送了消息後對方馬上收到,一般用tcp或者udp協議來傳輸消息。我也是第一次深入學習tcp和udp的使用,編碼過程中遇到很多難題,自己辛辛苦苦百度,解決了一個又一個困難,但是個人的聽聞是有限的,希望能拋磚引玉,聽取到大家更好的解決辦法。

       項目地址:http://download.csdn.net/detail/qq_27311165/9911099

       首先,這個項目的服務器大部分bean用Spring來託管,Spring託管了項目的dao層和業務層(QQService)還有helper模塊(UDPHelper、TCPConnectionManager這兩個單例),而且都是單例。單例就可能牽扯到線程安全問題,dao都是單例,jdbc中,如果多個線程同時執行靜態方法DriverManager.getConnection()會拋出異常,所以將該靜態方法封裝到DBHelper的getConnection()方法中,加上synchronized使線程同步,因爲dao的方法除了dbHelper.getConnection();外其他都是訪問局部變量和參數,每個線程調用dao的方法時都有自己的局部變量和參數,所以dao現在是線程安全的。服務器其他部分經過我不停地取證,應該也是線程安全的。             客戶端,因爲我想急於驗證它和服務器的通訊,所以寫得非常簡便。客戶端讀者也可以用另外的語言編寫,只要發送的tcp和udp報文能被服務器解析(“報文規定.txt”已經在壓縮包中)。

       數據庫只有3張表user、friend、unreadmsg。

CREATE TABLE user(
   userid            INT(8)            PRIMARY KEY        AUTO_INCREMENT,
   username            VARCHAR(20)    NOT NULL        unique,
   password            VARCHAR(20)    NOT NULL,
   isonline            boolean        NOT NULL,
   
    nickname        VARCHAR(20)    NOT NULL,            #暱稱,網名
    sex                VARCHAR(4),
    birthday        DATE,
    hometown        VARCHAR(20),
    livein            VARCHAR(20),
    motto            VARCHAR(100)                    #座右銘,個性簽名
) ;
CREATE TABLE friend(
    id                INT(20)            PRIMARY KEY        AUTO_INCREMENT,
   username            VARCHAR(20)    NOT NULL,
   friendname        VARCHAR(20)    NOT NULL,
   friendnickname        VARCHAR(20)    NOT NULL,
   fgroup            VARCHAR(20)    NOT NULL,            #好友分組名,可以一個好友一個組
   note                VARCHAR(20)        #好友備註
) ;
CREATE TABLE unreadmsg(        #只有未讀消息纔有資格存進數據庫
    id                INT(20)            PRIMARY KEY        AUTO_INCREMENT,
   sendername        VARCHAR(20)        NOT NULL,
   receivername        VARCHAR(20)        NOT NULL,
   msgtype            int(4)            NOT NULL,
   sendtime            VARCHAR(25)        NOT NULL,            #發送者發送到服務器時,服務器把當前時間賦給它
   msg                VARCHAR(200)    NOT NULL
) ;

        先來分析一下即時通訊軟件,什麼數據要被存到數據庫,用戶的信息肯定是要存到數據庫的,所以有了user表,用戶肯定要有自己的好友,friend表中username是自己的用戶名,後面4個字段分別表示好友用戶名、好友暱稱、好友所在分組名、備註名字。就這樣,我們就可以用一條記錄表示一個好友。最後是unreadmsg,未讀消息,如果好友不在線,就先把消息存到數據庫,等好友上線後,服務器從數據取出消息發給好友。

        目前服務器和客戶端大部分是用tcp通信,只有發消息給好友時才用udp通信。爲了方便使用tcp,客戶端把Socket封裝到了TCPConnection這個單例類;爲了方便使用udp,客戶端把Socket封裝到了UDPHelper這個單例類。

         客戶端可以在任何地方使用
TCPConnection.getInstance().sendAndWaitResponse(String msg);    //只往服務器發消息,且等待迴應

TCPConnection.getInstance().justSend(String msg);               //只往服務器發消息,不等待迴應

UDPHelper.getInstance().send(String content);                            //只往服務器發消息
發送消息給服務器。

          我突然不想寫了,請自己參考其中的妙處。下載完壓縮包後

請把Spring配置文件下
        <property name="dbpassword">
            <value>xxx</value>
        </property>
的xxx改爲你的數據庫密碼
請把客戶端的TCPConnection類的
    private TCPConnection() {
        try {
            client = new Socket("192.168.1.106", 8888);
            .....
"192.168.1.106"改爲你服務器的ip地址,才能正常運行。

          一個路由器就是一個局域網,已經能正常運行。qq.sql腳本里創建6個默認用戶。目前實現的功能:聊天、聊天記錄保存(在record目錄下保存)、上線未讀消息提醒。請期待後續更新。

         下面是截圖,一張是運行截圖,一張是聊天記錄文件的截圖,你可能需要兩臺電腦登錄兩個賬號才能開聊。(一臺開啓服務器和一個客戶端,另一臺開另一個客戶端)


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章