跳至主要內容

ZeroMQ-Octave

Jia-Yin大约 3 分鐘coursecomm

這一節將在 Octave 中使用 ZeroMQ 來進行簡單的訊息傳遞,包括請求/回應(Request/Reply)以及發布/訂閱(Publish/Subscribe)模式的應用範例。

安裝 ZeroMQ

如果是在 Windows 系統安裝 Octave,一般來說,應該已經同時安裝了 zeromq 套件,可在 Octave 中使用以下列指令確認:

>> pkg list

檢查列出的清單中,是否已包括 zeromq。如果沒有包括,可考慮重新安裝 Octave。

如果是使用 Ubuntu,可以依以下程序進行安裝:

  1. Install libzmq-dev
apt install libzmq-dev
  1. 在 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

  1. 在 Octave 中實際操作以上的範例程式。
  2. 在第二個範例中,發布其他幾種不同類型的訊息,然後在客戶端試著訂閱不同種類的訊息,並將接收到的訊息加以處理。
  3. 修改連接端口,以便可以在不同電腦之間進行通訊。