Socket types
Thread safety: ZeroMQ的socket是非線程安全的,並且ZeroMQ本身不建議在多個線程中傳遞同一個Socket,即使保證了線程同步。
Socket types: ZeroMQ一共具有12種類型的socket,5種消息模式。
-
請求/應答模式:ZMQ_REQ、ZMQ_REP、ZMQ_DEALER、ZMQ_ROUTER
-
發布/訂閱模式:ZMQ_PUB、ZMQ_SUB、ZMQ_XPUB、ZMQ_XSUB
-
管道模式:ZMQ_PUSH、ZMQ_PULL
-
配對模式:ZMQ_PAIR
-
本地模式:ZMQ_STREAM
目前只用到前兩種模式,此文檔暫時只闡述前兩種。
請求/應答模式
ZMQ_REQ
一般用於客戶端發送請求消息,此類型的socket必須嚴格遵循先發送后接收的順序,即:
如果發生異常或者當前沒有可用的服務(連接),socket會阻塞,直到有可用的服務(新連接到來),再把消息發送出去。REQ類型的socket不會丟棄消息。
ZMQ_REP發送消息時會自動在消息頂部插入一個空幀。
特點總結:
-
可兼容的Socket types: ZMQ_REP, ZMQ_ROUTER
-
數據傳輸: 雙向
-
發送/接收模式: 發送à接收à發送…
-
發送路由策略: Round-robin(循環隊列)
-
接收路由策略: Last peer
-
進入mute狀態后: 阻塞
ZMQ_REP
一般用於服務端接收消息,此類型的socket必須嚴格遵循先接收后發送的順序,即:
從客戶端接收請求消息使用了公平隊列,回應客戶端時,所有的reply都會被路由到最后下達請求的客戶端。
如果發生異常或者當前沒有可用的客戶端連接,所有消息都會毫無提示的被丟棄,不會發生阻塞。
特點總結:
-
可兼容的Socket types: ZMQ_REQ, ZMQ_DEALER
-
數據傳輸: 雙向
-
發送/接收模式: 接收à發送à接收…
-
發送路由策略: Last peer
-
接收路由策略: Fair-queued(公平隊列)
ZMQ_DEALER
DEALER是一種用於請求/答應模式的更高級的擴展Socket,它可以自由的收發消息,沒有ZMQ_REP/ZMQ_REQ那樣的限制。
對於每一個連接,接收消息也是使用了公平隊列,發送使用了循環隊列(RR)。
ZMQ_DEALER受ZMQ_RCVHW和ZMQ_SNDHW兩個閥值影響(可通過zmq_setsockopt函數設置),一旦發送或接收隊列達到閥值,Socket就會進入mute狀態,此時對DEALER的任何zmq_send操作都會阻塞,直到mute狀態結束。
如果當前沒有有效的連接,zmq_send操作也會阻塞,直到有新的連接到來為止。
DEALER發生阻塞並不會丟棄消息。
注意:如果ZMQ_DEALER連接到ZMQ_REP,每一個消息包必須包含一個空幀,然后再緊跟着數據包體。
特點總結:
-
可兼容的Socket types: ZMQ_ROUTER, ZMQ_REP, ZMQ_DEALER
-
數據傳輸: 雙向
-
發送/接收模式: 無限制
-
發送路由策略: Round-robin(循環隊列)
-
接收路由策略: Fair-queued(公平隊列)
-
進入mute狀態后: 阻塞
ZMQ_ROUTER
ZMQ_ROUTER是一種用於請求/答應模式的更高級的擴展Socket,它可以自由的收發消息。
當ZMQ_ROUTER接收到消息時,會自動在消息頂部加入來源地址標識符,接收消息使用了公平隊列。當發送消息時,ZMQ_ROUTER又會自動去掉這個標識符,並且根據這個標識符路由到相應的端點。
如果此地址標識的端點不存在,默認會毫無征兆的丟棄消息,除非將ZMQ_ROUTER_MANDATORY 選項設置為1。
當隊列達到閥值時,Socket就會進入mute狀態,此時所有后續發送到此Socket的消息都會被丟棄,直到mute狀態結束。同樣的,如果對端的接收隊列達到了閥值,消息也會被丟棄。
如果ZMQ_REQ連接到ZMQ_ROUTER,從ZMQ_ROUTER接收到ZMQ_REQ的消息時,除了會在消息前加上來源地址標識符之外,還會加上一個空幀與原消息分隔,即:
因此消息可以包含多個地址標識符和多個數據包體,如:
地址和數據體之間必須用空幀分隔;
發送回應消息給ZMQ_REQ時,必須至少包含一個空幀;
發送消息時,ZMQ_ROUTER會根據第一個地址標識符路由到對應的端點;
特點總結:
-
可兼容的Socket types: ZMQ_DEALER, ZMQ_REQ, ZMQ_ROUTER
-
數據傳輸: 雙向
-
發送/接收模式: 無限制
-
接收路由策略: Fair-queued(公平隊列)
-
進入mute狀態后: 丟棄消息
發布/訂閱模式
ZMQ_PUB
ZMQ_PUB類型的Socket以發布者的身份向訂閱者分發消息,消息以扇出的形式發送給所有訂閱者連接。
ZMQ_PUB類型的Socket沒有實現zmq_recv函數,所以不能對其調用zmq_recv函數!
當ZMQ_PUB Socket達到閥值時進入mute狀態,此時后續發送的消息會被丟棄,知道mute狀態結束。
對ZMQ_PUB Socket調用zmq_send永遠不會發生阻塞。
-
可兼容的Socket types: ZMQ_SUB, ZMQ_XSUB
-
數據傳輸: 單向
-
發送/接收模式: 只能發送
-
接收路由策略: Fan out(扇出)
-
進入mute狀態后: 丟棄消息
ZMQ_SUB
ZMQ_SUB類型的Socket以訂閱者的身份接收消息。初始的ZMQ_SUB Socket沒有訂閱任何消息,可以通過設置ZMQ_SUBSRIBE選項來指定需要訂閱的消息。
ZMQ_SUB Socket沒有實現zmq_send函數,所以不能對其調用zmq_send函數!
特點總結:
-
可兼容的Socket types: ZMQ_PUB, ZMQ_XPUB
-
數據傳輸: 單向
-
發送/接收模式: 只能接收
-
接收路由策略: Fair-queued(公平隊列)
Socket options(部分)
概要:通過zmq_setsockopt和zmq_getsockopt函數來設置/讀取指定選項。
ZMQ_SNDHWM
設置指定Socket的發送消息隊列的高水位標識(閥值),ZMQ會嚴格限制發送隊列的上限數。0表示無限制。
如果達到了這個限制,socket就會進入異常狀態,ZMQ此時會采取適當的措施——阻塞或丟棄消息,這取決於socket的類型。
Note: ZMQ不保證socket一定能接受ZMQ_SNDHWM這么多的消息,甚至可能會低60%-70%,這取決於socket上的信息流。
-
Option value type: int
-
Option value uint: message
-
Default value: 1000
-
Applicable socket types: all
ZMQ_RCVHWM
設置指定Socket的接受消息隊列的高水位標識(閥值),ZMQ會嚴格限制接受隊列的上限數。0表示無限制。
如果達到了這個限制,socket就會進入異常狀態,ZMQ此時會采取適當的措施——阻塞或丟棄消息,這取決於socket的類型。
-
Option value type: int
-
Option value uint: message
-
Default value: 1000
-
Applicable socket types: all
ZMQ_SUBSCRIBE
ZMQ_SUBSCRIBE選項會在ZMQ_SUB Socket上建立一個消息過濾器。初始的ZMQ_SUB Socket會過濾掉所有的消息,因此必須設置這個選項,否則將收不到任何消息。
如果設置一個0長度(option_value)的空值(option_value),ZMQ_SUB Socket會接受所有的消息。設置一個非空值將接受指定的消息。可以在同一個ZMQ_SUB Socket上設置多個過濾器,它將會接受至少一個匹配的消息。
-
Option value type: binary data
-
Option value uint: N/A
-
Default value: N/A
-
Applicable socket types: ZMQ_SUB
ZMQ_UNSUBSCRIBE
此選項用來刪除ZMQ_SUB Socket上通過ZMQ_SUBSCRIBE設置過的消息過濾器。如果Socket有多個實例有相同的過濾器,只刪除其中一個。
-
Option value type: binary data
-
Option value uint: N/A
-
Default value: N/A
-
Applicable socket types: ZMQ_SUB
ZMQ_IDENTITY
此選項用來設置Socket的身份標識,只能用於請求/答應模式。ROUTER Socket可以根據這個身份標識來路由信息。
身份標識的長度規定在1-255 bytes. 由二進制零開頭的標識符為ZMQ保留使用。
如果兩個身份標識相同的Socket連接到同一個對端(ROUTER),結果行為是未定義的。
-
Option value type: binary data
-
Option value uint: N/A
-
Default value: NULL
-
Applicable socket types: ZMQ_REQ, ZMQ_REP, ZMQ_ROUTER, ZMQ_DEALER
ZMQ_RCVTIMEO
設置Socket的receive操作的超時。
如果為0,則zmq_recv會立即返回,如果沒有接收到消息,會返回一個EAGAIN錯誤;
如果為-1,Socket會阻塞到有可用消息為止;
如果為其他值,Socket要么阻塞達到指定的時間還沒接收到可用的消息,返回一個EAGAIN錯誤,要么在指定時間前接收到可用消息。
-
Option value type: int
-
Option value uint: milliseconds
-
Default value: -1(infinite)
-
Applicable socket types: all
ZMQ_SNDTIMEO
設置Socket的Send操作的超時。
如果為0,則zmq_send會立即返回,如果消息沒有發送成功,會返回一個EAGAIN錯誤;
如果為-1,Socket會一直阻塞到消息消息發送完畢;
如果為其他值,Socket要么阻塞達到指定的時間還沒發送完成,返回一個EAGAIN錯誤,要么在指定時間前發送完消息。
-
Option value type: int
-
Option value uint: milliseconds
-
Default value: -1(infinite)
-
Applicable socket types: all
