2012-02-01 72 views
6

我是一個真正的Erlang新手(1周前開始),我試圖通過創建一個小而高效的聊天服務器來學習這種語言。 (當我說有效率的時候,我的意思是我有5臺服務器用來對數十萬連接的客戶端進行壓力測試 - 一百萬會很棒!)什麼是最好的,最有效的客戶端池技術與Erlang

我發現一些教程這樣做,唯一的是,每個教程我發現,是IRC喜歡的。如果一個用戶發送消息,除發件人以外的所有用戶都將收到該消息。 我想稍微改變一下,並使用一對一的討論。

什麼是搜索連接用戶的最有效的客戶端池? 我想過註冊過程,因爲它似乎盡我所需,但我真的不認爲這是更好的方式來做到這一點。 (或者最好的辦法就是這樣做)。

有沒有人會有這樣的建議嗎?

編輯:

每個連接的客戶端都會影響到一個ID。

當用戶連接時,它首先發送一個登錄命令給它的id。 當一個用戶要發送消息到另一個消息看起來像這樣

[ID-NUMBER][Message] %% ID-NUMBER IS A FIXED LENGTH

當我問「最有效的客戶池」,我實際上是尋找檢索最快的方式/添加/連接的客戶端列表,它可能是大(幾千 - 百年甚至幾百萬)在刪除一個客戶端

編輯2:

爲了回答一些問題:

  • 我使用原始套接字(使用telnet,現在與服務器通信) - 可能會移動後到SSL ...
  • 這是我自己的協議
  • 每一個客戶是一個催生的Pid
  • 每個客戶端的Pid都鏈接到它自己的監視器上(主要是爲了調試的原因 - 客戶端如果斷開連接,它應該通過自己從頭開始的認證來重新連接)
  • 我在開始編碼之前已經閱讀了幾本書,所以我還沒有掌握Erlang的每一個方面,但我不是沒有意識到這一點,我會在需要的時候閱讀更多關於它的內容。
  • 我真正想要的是存儲和搜索PID的最佳方式,以便將PID直接從進程發送到進程。

我應該使用列表編寫自己的搜索客戶端函數嗎?

還是應該使用ets?

甚至使用register/2取消註冊/ 1和whereis/1來維護我的客戶端列表,使用它的唯一ID作爲原子,這似乎是最簡單的方法,我真的不知道它是否是高效,但我很確定這是一個醜陋的解決方案;-)?

+0

我認爲這是一個很棒的問題,雖然有點波浪。 – 2012-02-01 15:31:16

+0

您可以針對'搜索連接用戶最有效的客戶端池是什麼?'這個更具體一點嗎?我沒有得到你的問題。 – Isac 2012-02-01 16:17:50

+0

@Isac:我編輯了我的帖子,希望你能找到更具體的 – TheSquad 2012-02-01 16:57:21

回答

1

我在做類似使用gproc作爲發佈訂閱(類似於頁面上的演示)你的聊天程序的東西。每個客戶都註冊爲ID。要查找特定的客戶端,請查看該客戶端ID。要訂閱客戶端,請將屬性添加到正在訂閱的客戶端ID的進程中。要發佈,請調用gproc:send(ClientId,Message)。這涵蓋了你的用例,更一般的基於聊天的聊天室,並且可以處理分佈式的無主進程註冊表。

我沒有測試,看看它是否擴展到數以百萬計,但它使用ETS做存儲和GPROC是烏爾夫Wiger堅如磐石的代碼。我不會指望能夠寫出更好的實現。

+0

謝謝我會研究它。是的,如果它是由Ulf Wiger寫的,那麼我會很難做到! +1給我迄今最尖銳的方式做到這一點! – TheSquad 2012-02-02 15:45:54

+0

它會比註冊流程更有效率(在這種情況下,瞭解註冊限制對我來說不是問題)? – TheSquad 2012-02-02 15:50:34

+0

這似乎正是我需要的!謝謝。我們只希望它能夠很好地擴展。 – TheSquad 2012-02-03 14:57:58

2

我也是一種新的二郎神(幾個月),所以我希望這可以讓你在正確的道路:)

首先,因爲你是個「新手」,你應該知道這些網站:

嘛,想着非持久性數據庫,我建議setsgb_sets模塊(文檔here)。

如果你想持久化,你應該嘗試dets(參見上面的文檔),但是我不能說明任何關於效率的事情,所以你應該進一步研究這個話題。

在本書Learn You Erlang中,有一章節data structures表示sets對於讀密集型系統更好,而gb_sets更適合平衡使用。

+0

謝謝我已閱讀你發佈的大部分內容,將查看Lear You Some Erlang。是的,是我的領導之一,只是看看是否有更多的選擇。 – TheSquad 2012-02-02 15:36:02

1

現在,Messaging系統是每個人在來Erlang時都想做的事情,因爲兩者自然融合在一起。然而,在繼續之前還有很多事情需要研究。消息傳遞基本上涉及以下事情:User Registration,User Authentication,Sessions Management,Logging,Message Switching/routinge.t.c.

現在,要做所有這些或大部分這些,需要有一個數據庫,當然是IN-MEMORY,這就是我要麼Mnesia要麼是ETS Tables。既然你是Erlang的新手,我想你還沒有真正掌握了這些。在某一時刻,你需要保持Who is communicating with whoWho is available for Chat e.t.c.因此,你可能需要查找一些東西並在某處寫東西。

另一件事是你沒有告訴我們客戶。它會是一個Web客戶端(HTTP),它是一個全新的協議,你正在通過原始套接字實現嗎?哪種方式,你將需要掌握一些名爲:Concurrency in Erlang。如果用戶連接並被分配了ID,如果您的設計是A process Per User,那麼您將不得不保存這些進程的Pid,或者根據一些標準註冊它們,並再次監視它們是否死於e.t.c.這將我帶到OTPSupervision trees。然而,有很多關於客戶端和服務器交互的信息,即需要e.t.c的網絡通信。或者它只是一個簡單的Erlang RPC項目,您正在爲自己的修訂做些什麼?



編輯

使用ETS Tables,或使用Mnesia RAM tables。不要想到註冊這些Pid或將它們存儲在列表,數組或集合中。看看this solution這是給this question

+1

其實我已經用boost-asio編寫了一個使用C++的整個服務器端通信協議。但是我有一些限制,我主要想要超越線程。我認爲Erlang是這樣做的語言!我已經編輯了我的帖子回答你的問題,當你有時間時對他們採取很多措施,謝謝。 +1 – TheSquad 2012-02-02 15:38:53

+1

我也編輯了答案 – 2012-02-03 07:00:20

相關問題