一、Socket.D 的主要特性
首先,Scoket.D 是高效一個二進制的網絡通訊協議(官方的講法是:基於事件和語義消息流的網絡應用協議),能夠滿足很多場景下使用。其次,Scoket.D 是溫和的響應式(採用回調風格)。
1、三種通訊模式
- send 只是發送(發送後不管了)
發送一個請求,無需爲這個請求發送答覆報文。適用於監控埋點,日誌上報等,這種場景下無需回執,丟失幾個請求無傷大雅。
- sendAndRequest(發送並請求,要求一個“答覆”)
發送一條請求消息,響應方收到後發回一個答覆消息。傳統的 HTTP 就是典型的 sendAndRequest。
- sendAndSubscribe(發送並訂閱,可接收N個“答覆”)
發送一個訂閱消息,響應方收到後發回N個答覆報文。傳統的 MQ 是典型的 sendAndSubscribe。
2、雙向監聽雙向會話
Server 可以監聽 Client 發來的消息;Client 也可以監聽 Server 發來的消息。形成的 Session,更是可以相互對發消息。
3、其它
- 二進制協議,緊湊高效
- 有語議、有事件
- 多路複用
- 靈活的傳輸層切換: TCP/UDP/WebSocket等
- 支持自動分等高級特性
4、與其它協議對比
感觀上像是各協議的優點提純。簡單且強大,非常有未來感!
對比項目 | socket.d | http | websocket | rsocket | socket.io |
---|---|---|---|---|---|
發消息(Qos0) | 有 | 無 | 有 | 有 | 有 |
發送並請求(Qos1) | 有 | 有 | 無 | 有 | 無 |
發送並訂閱 | 有 | 無 | 無 | 有 | 無 |
答覆或響應 | 有 | 有 | 無 | 有 | 無 |
單連接雙向通訊 | 有 | 無 | 有(不便) | 有 | 有(不便) |
數據分片 | 有 | / | 無 | 有 | 有 |
斷線自動重連 | 有 | / | 無 | 有 | 有 |
有元信息 | 有 | 有 | 無 | 有 | 無 |
有事件(或路徑) | 有 | 有 | 無 | 無 | 有 |
有流(或消息關聯性) | 有 | 無 | 無 | 有 | 無 |
Broker 模式集羣 | 有 | 無 | 無 | 有 | 無 |
異步 | 異步 | 同步 | 異步 | 異步 | 異步 |
接口體驗 | 經典 | 經典 | 經典 | 響應式(複雜) | 經典 |
基礎傳輸協議 | tcp, udp, ws | tcp | http | tcp, udp, ws | ws |
二、Socket.D 的內部實現
1、幀的設計
socket.d 是以幀爲單位進行傳輸。大的幀還會自動分片成小幀進行傳輸(超過 16MB 自動分裂重組,大小可配置),到達接收端後再自動聚合。
- 幀的邏輯結構
frame: {flag, message: {sid, event, entity: { metaString, data}}}
幀的數據邏輯結構:幀裏有標誌和消息;消息裏有流標識、事件、實體;實體裏有元信息字符串和數據。
- 完整的標準幀碼
[len:int][flag:int][sid:str(<64)][\n][event:str(<512)][\n][metaString:str(<4k)][\n][data:byte(<16m)]
字段 | 類型 | 大小 | 說明 |
---|---|---|---|
len | int | 4字節 | 幀長度(包括它自己的 4字節佔位) |
flag | int | 4字節 | 標誌(相當於協議指令) |
sid | String | 64字節以內 | 流標識。格式爲: guid |
event | String | 512字節以內 | 事件。格式爲:可見字符 string |
metaString | String | 4Kb以內 | 元信息字符串。格式爲:通用的 uri queryString |
data | byte[] | 16Mb以內 | 數據。格式爲: byte[] |
注意:當使用 udp 傳輸時,幀長度不能超過 2k (聽說,實際不能超過 1.4k )
- 簡化的輔助幀碼(Ping, Pong, Close),取消了 message 部分
[len:int][flag:int]
2、數據實體——Entity
基於幀之上,一般開發者接觸到的是 Entity, 它類似一個HTTP報文,可以是一個Request,也可以是一個Response。由兩個部分組成:
- MetaString 元信息字符串,類似 HTTP 的 header。格式:字符串
- Data 數據,類似 HTTP 的 body。格式:二進制
3、玩法
Socket.D 有很多玩法,傳統的 RPC 自然不在話下,用來做 IM 也未嘗不可,開發 MQ 也很簡單(FolkMQ 就是用它開發的)。某些特性也可以用來做代理或者網絡穿透。
IoT的場景,比如小明的家裏有個智能空調,小明想在外面通過手機 APP 來控制空調開關,如何優雅地描述這個控制問題?最精煉的解決方案就是"小明調用空調上開關的API"。
另外最經典的玩法就是Broker了,Broker類似一種“軟路由”的方案,可以讓服務的發佈訪問變得簡單。發佈服務只要連接到Broker,調用方通過反向請求的方式來讓Broker透明轉發即可,摒棄了傳統的註冊中心,端口管理等常見的服務治理手段。
4、關於 Socket.D Broker
Broker 有很多優勢,發佈服務不需要監聽端口,無需 Sidecar,服務註冊變得簡單,無需 zk、etcd 之類,LoadBalance 變得簡單,也更安全,沒監聽端口後很難攻擊。也有很多劣勢,網絡上多了一跳,性能是有一定損耗的,Broker 是中心化設計,類似我們平時全局的 Nginx 一樣,但是 Broker 的優雅啓停顯然更加複雜,受限於整個 Broker 集羣的瓶頸等等。上帝爲你關閉了一扇門,就一定會爲你打開一扇窗。
三、響應式編程,難嗎?
響應式編程是個老話題了,它早已無處不在,甚至你在Excel裏SUM求和,本質上也是種響應式的思維。響應式本質上就是響應變化的數據流。Socket.D 這個協議本身就是以響應式之名,將其擴展到網絡層面。
但是,響應式接口對一般程序員,不太友好。Socket.D 是響應式,但採用"經典的回調界面"。
四、總結
Socket.D 是個很有趣的網絡協議,未來應該會普及流行。它解決問題的思路和設計很令人耳目一新。如果大家有興趣,可以去它的官網瞭解下。