1

我將在java中實現客戶端 - 服務器應用程序。客戶端和服務器通過TCP相互通信。只有一箇中央服務器處理所有客戶端消息。設計模式:客戶端 - 服務器

我不使用RMI的通信,它們使用TCP的套接字進行通信,並且客戶端可以通過服務器的另一個客戶端通信。這意味着服務器轉發來自客戶端A的消息到客戶端B.

現在即時通訊坐在這裏和揣摩如何設計的服務器應用程序。

因此,服務器一直在監聽接通連接。沒關係。對於每一個連接到服務器的新客戶端(撥號),服務器都會創建一個新的Socket,並使用線程來讓它們同時工作。

每個用戶使用一個客戶端,每個客戶端必須使用用戶名和密碼進行身份驗證。

林尋找一個設計模式來實現服務器上,其存儲/處理Socket連接到客戶端。

我的第一個想法是創建一個名爲ClientManager大Singleton對象包含地圖。所以服務器可以調用類似ClientManger.getSocketBy(用戶名)來獲得所需用戶(客戶端)的套接字。

這可以解決從客戶端A的消息的 「轉發」 到客戶端B.

對於expample: 用戶A(客戶端A)希望將消息發送到用戶B(客戶端B)。因此,服務器接收來自用戶A(客戶端A)的消息,並調用ClientManager.getSocketBy(用戶B)以獲取到用戶B的通信套接字,然後通過該套接字發送消息。

但在服務器端這個「設計」在我看來,簡單的,因爲它可以爲這樣的事情一個很好的設計,和我在想念着類似活動,觀察員等

另一種可能丟處理用戶B套接字連接instad直接調用Socket.send()方法的線程的事件。

但是,必須有一個更好的辦法...

有沒有實現這樣的事情,你可以推薦一種設計模式,一種常見的方式?我想知道即時信使服務器如何實現這一點?順便說一下:即時消息不實現即時消息,可擴展性不是最重要的事情,因爲沒有1000個客戶端在同一時間與服務器通信。一個乾淨的軟件設計對我來說更重要。

林實現用於通信的自己的協議(基於XML)。有沒有一種方法/設計模式如何在對象中包裝協議,或者我沒有辦法(從軟件架構師視圖)除外字符串/ XML解析?

回答

2

你有兩個問題我想。

第一個是關於什麼「設計模式」用於您的路由。你表明你在做什麼,但你沒有說明你正在經歷(或預期經歷)的問題,只是說它太簡單了。模式是解決常見問題的常見方式,但是一個程序太簡單並不是我見過的模式:)

第二個問題是關於從使用它的客戶端分離協議的實現。現在是一個很好的問題,你肯定應該做的。您將要創建一個公開字段的Message對象(如To,From,Content等)。您的服務器需要將原始xml數據傳遞給某些類型的解析器,該解析器充當消息對象的Factory。

Message msg = protocol.CreateMsg(byte[] xmlBuffer) 

可以通過分配不同的一個到每個TCP/IP端口或通過用默認協議開始,然後具有在客戶端和服務器協商一個不同的協議支持附加協議。

EDIT1:

我不會套接字映射到用戶,說實話。我會將您與用戶交流的方式抽象爲一個對象,可能是Connection或Channel。然後,您可以使用TcpConnection或CorbaConnection或其他類來繼承Connection。理想情況下,您正在執行如下操作:

string destUserId = msg.To; User destUser = UserManager.Find(destUserId); 連接conn = destUser.Connection; if(conn!= null) conn.Send(msg);

請注意,沒有提及連接或協議實現的詳細信息。

+0

之間的映射所以我不想運行在「反模式」... 例如,將用戶映射到Socket的Singleton ClientManager對我來說聽起來有點奇怪,要擁有這樣一箇中心對象,必須有更好的方法......我真的想看到(代碼)另一個項目將如何實現類似的東西... – sockeqwe

+0

我添加了一個編輯,我同意你不想將套接字綁定到用戶。 – tcarvin

+0

連接的抽象是應該明確使用的東西! 我不確定像UserManager這樣的中心類是不是一個好主意,但說實話我不知道替代方案。你知道任何? 如果用戶有連接或連接有用戶。 我的意思是,我應該使用Connection c = ConnectionManager.find(destUserId); 或您描述的方式UserManager.find(destUserId);連接c = UserManager.find(destUserId).getConnection()。 由於安全原因,可能映射到Connection會更好,因爲用戶可能包含不應該以這種方式訪問​​的信息。 – sockeqwe

1

您嘗試了服務定位器模式嗎?但Java已經實現了你的核心內容,爲什麼「重新發明輪子」。您可以使用CORBA或基於TCP/UDP的框架之一,如ICE,如果您不喜歡RMI,並且這將真正幫助您構建您的分佈式應用程序。

+0

謝謝你的答覆,但我不能使用CORBA,RMI或ICE等技術。 而我的問題是,如何在服務器端設計用戶之間的通信通道(一個插座,RMI,冰,或其他) – sockeqwe