ZeroMQ-Octave
2024年3月28日大约 3 分鐘
這一節將在 Octave 中使用 ZeroMQ 來進行簡單的訊息傳遞,包括請求/回應(Request/Reply)以及發布/訂閱(Publish/Subscribe)模式的應用範例。
安裝 ZeroMQ
如果是在 Windows 系統安裝 Octave,一般來說,應該已經同時安裝了 zeromq 套件,可在 Octave 中使用以下列指令確認:
>> pkg list
檢查列出的清單中,是否已包括 zeromq。如果沒有包括,可考慮重新安裝 Octave。
如果是使用 Ubuntu,可以依以下程序進行安裝:
- Install
libzmq-dev
apt install libzmq-dev
- 在 Octave 中安裝 ZeroMQ 套件:
pkg install -forge zeromq
使用 ZeroMQ
在 Octave 中使用 ZeroMQ 前,需要先加載它:
pkg load zeromq
你可以使用 help zeromq
命令來查看可用的函數和使用說明。
基本請求/回應模式
服務端程式碼
pkg load zeromq % 載入 zeromq 程式庫
more off % 輸出不要使用分頁模式
printf("Creating hello world server...\n");
sock = zmq_socket(ZMQ_REP); % 建立 Reply 端口
zmq_bind(sock, "tcp://*:5555"); % 監聽所有網路介面的 5555 埠
printf("Waiting for clients ...\n");
while (true)
recievedata = zmq_recv(sock, 10); % 接收最多十位元組的訊息
printf("Received %s\n", recievedata); % 列印接收到的訊息
zmq_send(sock, "World", 5); % 回應 World
endwhile
zmq_close(sock);
客戶端程式碼
pkg load zeromq % 載入 zeromq 程式庫
more off % 輸出不要使用分頁模式
printf("Connecting to hello world server...\n");
sock = zmq_socket(ZMQ_REQ); % 建立 Request 端口
zmq_connect(sock, "tcp://localhost:5555"); % 連接本地端的 5555 埠
for request_nbr = 1:10
printf("Sending Hello %d...\n", request_nbr);
zmq_send(sock, uint8("Hello"), 5); % 傳送 Hello
printf("Waiting for server response %d... (Ctrl-C to exit)\n", request_nbr);
recieved = zmq_recv(sock, 10); % 接收最多十位元組的訊息
printf("Received %d = %s\n", request_nbr, recieved);
endfor
zmq_close(sock);
基本發布/訂閱模式
服務端程式碼
pkg load zeromq % 載入 zeromq 程式庫
more off % 輸出不要使用分頁模式
publisher = zmq_socket(ZMQ_PUB); % 建立 Publish 端口
zmq_bind(publisher, "tcp://*:5556"); % 監聽本地端的 5556 埠
while (true)
dice_number = randi(6); % 隨機選出 1~6 的整數
data = sprintf("Dice %d", dice_number); % 準備傳送資料
zmq_send(publisher, data); % 發布骰子點數訊息
data = sprintf("Score %d", randi(100)); % 準備傳送資料
zmq_send(publisher, data); % 發布成績訊息
endwhile
zmq_close(publisher);
客戶端程式碼
pkg load zeromq % 載入 zeromq 程式庫
more off % 輸出不要使用分頁模式
subscriber = zmq_socket(ZMQ_SUB); % 建立 Subscribe 端口
zmq_connect(subscriber, "tcp://localhost:5556"); % 連接本地端的 5556 埠
msgfilter = "Dice"; % 過濾訊息前置字串
zmq_setsockopt(subscriber, ZMQ_SUBSCRIBE, msgfilter); % 設置過濾器
total = 0;
printf("Receiving 100 dice numbers...\n");
for update_nbr = 1:100
string = char(zmq_recv(subscriber, 128)); % 將收到的訊息轉成字串
[prefix, number] = sscanf (string, "%s %d", "C"); % 使用C格式讀取前置字串與點數
printf(" %d", number); % 列印點數
total += number; % 計算總和
endfor
printf("\n\nAverage = %.2f\n", total/100.0); % 印出骰子平均點數
%fprintf("Average temperature for zipcode '%s' was %dF\n", zipfilter, (total_temp / update_nbr));
zmq_close(subscriber);
以上示範了如何在 Octave 中使用 ZeroMQ 進行基本的訊息傳遞。
練習 1
- 在 Octave 中實際操作以上的範例程式。
- 在第二個範例中,發布其他幾種不同類型的訊息,然後在客戶端試著訂閱不同種類的訊息,並將接收到的訊息加以處理。
- 修改連接端口,以便可以在不同電腦之間進行通訊。