首先,讓我們來澄清socket.io和RethinkDB換刀之間的關係。 Socket.io用於客戶端(瀏覽器)和服務器(Node.js)之間的實時通信。 RethinkDB更新是服務器(Node.js)監聽數據庫更改的方式。客戶端無法直接與RethinkDB通信。
實時應用程序的一個非常典型的架構是讓RethinkDB更改訂閱訂閱數據庫中的更改,然後使用socket.io將這些更改傳遞給客戶端。客戶端通常也會發送可寫入數據庫的消息,具體取決於您的應用程序邏輯。
是的,您可以通過socket.io發送所有消息,然後將所有消息傳遞給所有客戶端,然後將這些消息寫入數據庫以實現持久性。這也是事實,這是更快的,但這種方法有許多缺點。
1.數據庫真理
被發現的最簡單的問題,單一來源如下:
- 如果您的應用程序不能寫東西到 數據庫會發生什麼?
- 如果試圖插入數據庫的數據無效或重複,會發生什麼情況?你編寫應用程序邏輯來處理這個問題嗎?
- 如果Node.js服務器在發出 寫查詢之前發生故障,會發生什麼情況?
這些只是一些簡單的例子,在這些例子中,由於您的體系結構,您將丟失或失去同步數據。只是爲了重申這一點,你將失去數據,因爲你的真相的主要來源是內存。您的Node.js應用程序中的數據與您的數據庫之間也可能有差異。
問題是,數據庫應該始終是您的唯一真理來源,並且您應該只在數據寫入磁盤時才確認數據。我不確定每晚有人能否在晚上睡覺。
2。高級查詢
如果您只是通過socket.io將所有客戶端的所有新消息傳遞給所有客戶端,那麼您現在必須在客戶端中擁有一些非常複雜的邏輯,以便過濾出所有實際上非常重要的數據。考慮到你通過網絡傳遞大量無用的數據,客戶端實際上不會使用它們。
另一種方法是編寫一個訂閱某些渠道(或類似的東西)的發佈/訂閱系統,以過濾出對客戶來說非常重要的數據。
RethinkDB通過提供它自己的查詢語言來解決此問題,您可以附加到更改供稿。例如,如果客戶需要我的users
表中年齡在20至30歲之間的所有用戶,他們居住在加利福尼亞州,距舊金山10英里,並且在過去6個月內購買過書籍,可以使用ReQL(RethinkDB的查詢語言)表示,並且可以爲該查詢設置更換進料,以便僅當相關的更改時纔會通知客戶端。這對於Socket.io和Node.js來說很難做到。
3.擴展
即RethinkDB解決的是,它是一個更靈活的解決方案,只是在內存中存儲的一切最後一個問題(通過Socket.io和Node.js的)。由於RethinkDB是從頭開始構建的,因此您可以擁有包含分片和副本的20多個RethinkDB節點的集羣。您編寫的每個RethinkDB查詢都是默認分發的。現在,您可以擁有20多個無狀態的Node.js節點,並且都在監聽更新。因爲數據庫是真相的中心來源,所以這不是問題。
另一種方法是將自己限制在一臺服務器上,擁有一些其他的pub/sub系統(例如建立在像Reddis之類的東西上),只有一個數據庫可以輪詢......可能有更多的例子,但你可以看到我要去哪裏。
我很想聽聽,如果這回答了你的問題,如果我得到你的出發到來。開始時如何構建應用程序有點困難,但它對於大多數實時體系結構來說確實是一個優雅的解決方案。
非常有幫助:) 對於高級查詢,請考慮多房間聊天應用程序,並將消息發送給房間中的客戶。我不能只聆聽1份換貨(所有聊天)並只發送給那個房間的客戶嗎? ('room')()函數()函數(函數(err,row)){r.table('chat')。 + row.new_val.id,row.new_val); // 1 room }); });' ...所以高級查詢與此特定用例無關,因爲它們將涉及觀察一個每個房間更換飼料,這是相當浪費的。我們也不需要在這個客戶端有'非常複雜的邏輯'。 – user3096484
「,所以高級查詢與此特定用例無關,因爲它們涉及每個房間觀看一次換貨,這相當浪費。」換刀實際上很便宜,所以最好設置更具體的不同換刀,而不是設置一個換刀,以便以後處理應用邏輯。 –
「我不能只聆聽1次換貨(所有聊天)並只發送給那個房間的客戶嗎?」是的,你也可以這樣做。如果你只想要一個聊天消息的話,那很好。話雖如此,我會在需要時立即轉而編寫ReQL查詢+更換,而不是將其添加到應用程序層。同樣,更換進度查詢相當便宜,不用擔心要慷慨地開放它們。 –