【Java學習】聊天室專案(32)
聊天室專案需求:
1、使用者名稱登入註冊(判斷有沒有重複使用者名稱,可設定ip和埠)
2、上下線提醒
3、線上列表
4、私聊
5、公聊
6、傳送文字,檔案。
7、聊天記錄 儲存 查詢 刪除。
8、下線
選做功能
1、切換狀態(線上,隱身,忙碌)
2、建群
3、大檔案傳輸。(新建流傳輸)*
4、離線訊息*
5、個人資訊設定
6、語音聊天*
7、朋友圈
8、文字表情
9、增刪好友,修改好友備註名。
1.首先你得寫一個客戶端,一個伺服器端,利用TCP協議連線,先實現客戶與伺服器端聊天,我們開啟子執行緒專門負責接收訊息,主執行緒負責發訊息.如果你還不會 點選這裡
2.然後這只是初期,我們一步一步來,我們是不會和服務區聊天的,伺服器只是用來轉發訊息的,我們多個使用者連線到伺服器上,所有訊息通過伺服器轉發給接收者,所以我們得在伺服器端設定一個迴圈監聽,若有客戶端連線,則就為他開啟一個子執行緒,將他的名稱和他所對應的管道(socket)存到集合(可用hashMap雙列集合)中去,這樣的話,每一個客戶端自己都有一個主執行緒負責傳送訊息,都有一個子執行緒負責接收訊息,客戶端連線上伺服器後,伺服器為每個執行緒開啟一個子執行緒,給客戶端提供服務.
3.若李四和王五都已經連線了伺服器,當李四要給王五發訊息時候,先將訊息發給伺服器,經由伺服器轉發給王五,所以此時要規定訊息格式,要讓伺服器知道這個訊息是給王五的,不是轉發給趙六的,例如規定格式為 接收者#訊息內容#訊息標誌位#傳送者,類似的格式,這樣伺服器端根據已經定好的格式,對收到的字串進行按#擷取,就可以拿到接收者是誰,訊息是什麼,等資訊.
4.在改進一下,再伺服器端再寫一個註冊執行緒,再寫一個登陸執行緒,客戶端連線上伺服器的時候,讓他選擇是登陸還是註冊,進入不同的子執行緒,當登陸或註冊成功後,自動開啟伺服器端子執行緒,為客戶端提供服務,在客戶端連線的時候,先進行註冊,讓使用者端輸入使用者名稱,輸入密碼,(為後面寫登陸做準備)伺服器端就接受到後,(用Properties屬性集合)對這種使用者名稱密碼的鍵值對資料用檔案(以後可用資料庫)儲存起來,當註冊成功後,再開啟服務端子執行緒,為客戶端提供服務.
5.當使用者上線之後,應該對所用的現在使用者傳送上線提醒,某某某上線了.所以剛才當客戶端登陸的時候,將他們們的資訊儲存再集合裡面就用到了,就可以遍歷集合,給別的人,傳送上線提醒.
6.在客戶端註冊程式碼之後(此時已經連線上客戶端了,客戶端子執行緒也開啟了,為你提供服務了),客戶端主執行緒再寫一個switch-case可以用於功能的選擇,比如你要私聊,還是公聊,要發檔案,切換狀態,檢視聊天記錄,退出等功能.
下面我說一下寫這些功能我的想法,每個人的想法不一樣,求同存異啊.
首先需要定義一些常量,用於判斷該開啟那個功能,在客戶端請求伺服器的資料中加上這個常量,伺服器端收到資料後,對資料進行以之前規定好的#號拆分,根據拆分得到的常量(單獨寫一個類,對每一個功能都定義一些靜態常量,利用這些常量,來區別功能,讓伺服器知道,你發來的請求是幹什麼用的,或者使用列舉也可以)就可以判斷該是私聊,還是公聊,這種的功能選擇.
伺服器端的集合中存有每個線上的人的管道(socket),私聊就是,將訊息通過管道獲取流(getOutputStream)轉發給收信者,公聊是遍歷集合,轉發給所有線上的人.獲取線上列表就是將集合中的使用者名稱,拼接成一個字串當作伺服器的訊息,轉發回來.
要做隱身功能的話,可以在new一個單列集合arrayList或者hashSet,在使用者登陸成功或註冊成功時候,不僅將使用者名稱和對應的管道存到雙列集合中,而且再將使用者名稱存進單列集合中,在切換狀態的時候,只需要將單列集合中的使用者名稱刪除,在獲取線上列表的時候,將原來遍歷雙列集合變為現在遍歷單列集合,雙列集合不動,只用作公聊的時候用,隱身也是可以收發訊息的,只是別人獲取線上列表的時候獲取不到.
在收發檔案時候,利用一個小技巧,將前10kb用作每次傳送的指令訊息(接收者#訊息#訊息標誌位#傳送者)的位元組數,在將檔案的位元組數加到這10kb後面,當伺服器收到的時候,將緩衝區設定為10kb,都是先一次性讀取10kb訊息指令,當讀到的訊息之類中的訊息標誌位位發檔案的時候,就跳到收檔案的功能上,在這個方法中再次讀取檔案部分,這種方法可以滿足,傳送較小的檔案mb級別的.這其中用到了記憶體操作流(ByteArrayOutputStream())可以用來拼接位元組.如果傳送的檔案比較大,可以考慮先上傳到伺服器端儲存,再由接收者從伺服器端下載.
收發檔案會有一個問題,就是,你的客戶端子執行緒是收資訊的,當客戶端反饋回訊息,有人給你發來了一個檔案,此時你是沒法輸入資訊的,因為你的主執行緒現在停留再錄入訊息的狀態上,所以子執行緒沒法輸入訊息,此時可以寫一個共享變數,利用主執行緒的輸入,改變共享變數的值,子執行緒迴圈讀取共享變數,若共享變數變了,則讀取break,這樣以達到子執行緒獲取輸入的資料的方法,點選詳見
程式碼執行圖示:
程式碼太多,我打包在github中了
謝謝
相關文章
- 學習開源 java 專案 gunsJava
- Java新手學習Java專案打日誌Java
- 練手小專案一:JAVA聊天室原始碼Java原始碼
- STM32學習筆記——Keil uVision5建專案筆記
- Java專案中MongoDb學習和使用總結JavaMongoDB
- 【快速學習】docker構建java專案實踐DockerJava
- Maven 學習筆記——將普通的Java專案轉換成Maven專案(3)Maven筆記Java
- 專案學習Graphql(一)
- vue專案學習05Vue
- 專案學習經驗
- 【esp32 學習筆記】將lvgl融入esp-idf專案中筆記
- 學習 stm32
- 找不到Java的專案案例學習,可以看看這個Java
- 從零開始學習Linux部署Java web專案LinuxJavaWeb
- 傳智黑馬java基礎學習——day32Java
- Qt學習- (掃雷專案初學)QT
- Halo 開源專案學習(一):專案啟動
- 2018-10-16 java學習小專案合Java
- 學習java註解,初試啟動springboot專案JavaSpring Boot
- STM32學習程式
- 【esp32 專案】使用esp32的wifiWiFi
- B站java學習檔案Java
- 分享一個簡單的聊天室專案
- Go語言專案實戰:多人聊天室Go
- 碎片化學習Java(十五)Java switch得出星期數對應的運動專案Java
- 10個你能參與並學習的Java開源專案Java
- 開源專案學習方法ABC
- 【轉】UCM專案管理配置學習專案管理
- STM32 的學習方法
- STM32學習步驟
- ESP32開發學習
- ESP32學習跳轉
- Java學習筆記之檔案Java筆記
- [練手專案]Gin+websocket 的多人聊天室Web
- 多功能聊天室-專案規劃實現圖
- 專案管理學習筆記五:專案整體管理薦專案管理筆記
- STM32學習記錄(一):STM32概述
- Java學習日記(一)環境配置及專案結構講解Java