Limbo: 簡單訪問遠程數據庫

簡單高效的項目協做工具 Teambition 自誕生以來,一直致力於用技術重塑人們的工做方式,但願爲人們的工做方式帶來最好的協做體驗,除了 Teambition 以外,咱們還有日程管理工具 「今天」,這一次,咱們又有新的產品線 「簡聊」 要上線了,正如它的slogan「簡聊一下,輕鬆協做」所表達的,它是一款slack風格的,基於企業的簡單聊天工具。雖然說簡單,但倒是爲效率和協做而生的企業IM工具,它繼承了 Teambition 企業級基因,打通了項目協做工具 Teambition ,用戶能夠直接經過 Teambition 帳號登陸。它以話題爲中心的羣組討論聊天模式,用slack的方式促進交流,將企業內溝通、任務、人員、文件等各類要素和流程打通。有利於基於目標向,提高專一度,完成任務,過濾出團隊聊天中最有效的信息。若是有些話題討論須要其餘外部人員的參與,只須要發送郵件便可邀請對方加入話題討論。node

歡迎你們試用咱們的 「簡聊」,第一個版本上線不免頗有多不足,請你們踊躍提需求和意見,幫助咱們前進。git

許晶鑫是本次負責 「簡聊」 開發的工程師,如下這篇文章是他在開發 「簡聊」 這款應用的過程當中的經驗談。github


Limbo: 簡單訪問遠程數據庫

簡聊一下 輕鬆協做

對於 nodejs 生態來講,使用 mongoose 做爲 Model 模塊是再好不過的一件事,其一大特色就是簡潔優雅的 Schema 定義,提供了每一個鍵值的類型驗證,數據驗證,索引聲明,虛擬鍵,並自帶實例化方法的擴展,大大節省了開發的成本。可是在考慮開放數據的時候,一切就顯得不那麼美好了。mongodb

在打造 「簡聊」 這款應用的過程當中,咱們就實實在在的遇到了這樣的問題。因爲須要使用 Teambition 的用戶和團隊數據,而且當 「簡聊」 更新了用戶數據以後,在 Teambition 中能實時的將這些更新推送到用戶那裏。按照慣例,咱們最初使用的是 restful 接口。數據庫

第一階段,使用 restful 接口

restful 接口的應用面最廣,可是仍然存在不少不足,好比接口在參數和結構上限制較多,在考慮修改接口 api 的時候,每每會顧慮客戶端的兼容性,而一旦客戶端程序有新的需求,則需等待接口的更新。另外一個麻煩的地方是須要作簽名校驗,對於內部的應用來講,咱們徹底能夠經過防火牆來控制特定 ip 對端口的訪問,簽名在此處就顯得有點多餘。後端

第二階段,單獨拆封 Schema

而後咱們想到了將 Schema 拆封成一個單獨的倉庫,nodejs 有良好的模塊管理,在不一樣的應用中,咱們只須要將這些模塊引入進來,既作到同步更新,又作到 DRY。相對於 restful 接口的缺點就是,對於數據的調用入口過多,並且應用之間互相是不知情的。例如在 「簡聊」 中有更新用戶數據,在 Teambition 中就沒法得知,並推送給其餘客戶端。api

第三階段,遠程過程調用(rpc)

這個階段和 restful 接口其實相似,咱們在 Teambition 的後端進程中將一些接口方法暴露出來,這樣咱們的客戶端程序就能經過簡單的 rpc 方式調用這些接口。例如咱們導出了 user.update 方法,在客戶端代碼中使用 rpc.call('user.update', params, callback) 便可調用相應的過程。這樣的調用行爲與使用本地代碼無異,多是目前能找到的最簡單直接的方式了。restful

第四階段,rpc 與 mongoose 的結合

事情能夠變得更簡單,因爲目的主要是爲了操做數據庫,因此咱們開發了一個模塊 limbo,將 mongoose model 中全部方法暴露出來,以命名空間來劃分,實現了在客戶端與服務端程序一致的使用體驗。tcp

例如咱們在服務端程序中使用 limbo 鏈接 mongodb,只須要作以下聲明:(如下的代碼都以 coffeescript 做爲示例)mongoose

limbo = require 'limbo'

# 定義 Schema
UserSchame = (Schema) ->
  # 這裏的 Schema 即 mongoose.Schema
  new Schema
    name: String
    email: String

# use 方法用做區分不一樣數據庫鏈接的命名空間,通常參數選擇數據庫名就行
db = limbo.use('test').connect('mongodb://localhost:27017/test').load 'User', UserSchema

使用方式就與 mongoose 一致了

user = db.user
# user 是一個 limbo 中用於封裝 model 的一個對象,你能夠直接使用 user.model 來直接調用 mongoose model
user.findOne _id: 'xxxx'
user.create name: 'xxx', email: 'yyy'

下面是 limbo 中最激動人心的地方,你能夠導出一個 collection 中的全部方法到 rpc server 中,只須要經過一個簡單的聲明

limbo.use('test').bind(7001).enableRpc()

下面咱們就要提到如何在客戶端程序中調用這些方法

# 在客戶端也須要初始化一個 limbo 命名空間,須要與服務端一致,連接改成服務端的域名和端口號
db = limbo.use('test').connect('tcp://localhost:7001')

# 下面有兩種方式來使用 rpc
# 1. 使用 call 方法
db.call 'user.findOne', _id: 'xxxx', ->
# 2. 使用方法鏈
db.user.findOne _id: 'xxxx', ->
# 第二種方式存在一個延遲,必需要在 limbo 與服務端程序握手成功以後纔可使用,
# 不然會拋出一個對象不存在的異常,不過在通常的應用中,
# 初始化所需的時間都會長於這個連接所需時間,因此延遲能夠忽略不計了

能夠看出,上面的第二種方式與服務端在本地使用 mongoose 的方式如出一轍,這種黑魔法式的調用方式應該是廣大碼農喜聞樂見的。

limbo 另外一個值得稱道的功能是能夠在服務端程序監聽這些遠程調用的事件,這得益於 nodejs 的 event 對象,limbo 自己就繼承於 EventEmitter 對象,因此咱們在每次遠程調用後會觸發一個事件給服務端程序,而在服務端只須要簡單的監聽這個事件便可

limbo.on 'test.user.findOne', (user) -> ...

正是這種 rpc 加事件反饋的機制,讓 「簡聊」Teambition 能夠實現簡單實時的數據交換。咱們將 limbo 託管在 github 上開源,是深知它還存在不少能夠改進的地方,因此難免庸俗的說一句,歡迎 issue 和 pr~


最後,歡迎使用咱們的新產品 「簡聊」 ,一款基於話題的輕量級協做應用。

相關文章
相關標籤/搜索