ブロックを積みながら(72) Node-RED、websocket in/out ノード

Joseph Halfmoon

今回はNode-REDのWebSocket-in/out ノードの試用です。世の動きに鈍い年寄りにはWebSocketは最近の流行?いや双方向でモダンなWebアプリケーションには必須のプロトコルだと。今回は最低線のフローをNode-RED上に実装、Pythonスクリプトとの間で通信できることを確認してみました。

※「ブロックを積みながら」投稿順 index はこちら

※Node-REDは Raspberry Pi 3 model B+ (Raspberry Pi OS, 32bit)上で動作させています。

Node-RED上に実装した「最低線」フロー

なんといってもWebSocketが「従前のhttp通信」と異なるのは、接続されたらコネクションを張り続け、サーバ側のタイミングで「プッシュ」できることかと。

以下は実際にコネクションを1つ張っている状態の今回実験用のフローです。ノードの下に緑のconnected 1 という表示が見えてますな。

websocket in ノードは、所定のURLにWebSocketプロトコルで接続されるのを待ち受け、受信したパケットをDebugウインドウへと垂れ流すだけのものです。ただこれでコネクションが成立して維持されると。

一方、websocket outノードは websocket in ノードとは切り離されて置かれています。しかしinノードで成立したコネクションはこちらにも伝わってます。Injectノードのボタンを押されるとJSONオブジェクトが載ったmsgがoutノードに送られてくるのですが、そのとき「接続中の」通信先全てに、もれなくJSONオブジェクトが配信されるという塩梅(特定の接続先にのみ送信するにはinノードが受信したmsgを加工してpayloadにデータを載せるのが良いみたいです。)

flow

各ノードの設定

websocket-in ノードの設定画面を開くと以下のようです(「名前」のところはwebsocket in と自分で書き込みましたが。)

実際にURLを設定するには赤丸で示した編集ボタンを押さねばなりません。

websocketInSetting0

編集ボタンを押したところが以下に。URLは、デフォルト設定のパスそのままの文字列をこれまた自分で書き込みましたです。実際外部デバイスからは、Node-REDサーバのIPアドレスとポート番号を使って以下のようにアクセスできることになります。

ws://192.168.2.121:1880/ws/example

websocketInSetting1

テスト用のInjectノードは、Node-RED側から「プッシュ」配信するJSONオブジェクトを送出するものです。プロパティabc にデータ123が載っておると。

InjectSetting

さて websocket out ノードについては以下のようにしました。これだけ。

websocketOutSetting

WebSocket通信のお相手

WebSocket通信のお相手は、Windowsパソコン上のPython3.8で動かすスクリプトといたしました。必要なモジュールは websocketsです。Pythonのwebsocketsのドキュメンテーションが以下に。

websockets

この年寄りはWebSocket通信分かっていないので、上記ホームページの冒頭に掲げられているExampleスクリプトをコピーさせていただき、以下のようにチョイ直ししたもので通信相手をでっち上げましたです。

import asyncio
import websockets

async def hello():
    async with websockets.connect("ws://192.168.2.121:1880/ws/example") as websocket:
        await websocket.send("Hello world!")
        message = await websocket.recv()
        print(message)

asyncio.run(hello())
動作確認

上記のスクリプトを動作させれば

    1. スクリプト側からNode-RED上のwebsocket-inノードに”Hello world!”が送信される(その後は2のアクションとられるまで「待ち」)
    2. Node-RED側のInjectノードのボタンを押すとスクリプト側にJSONオブジェクトが到来して表示される(そしてスクリプトの実行完了。)

2は1のレスポンスではなく、あくまでNode-RED側からの「プッシュ」であります。

まずはスクリプトからNode-RED側へ送られたオブジェクトの様子が以下に。

Debug

Injectノードから送られたJSONオブジェクトの着信がこちらに。

pythonExample

まあ、WebSocketうごいてるんでないかい。ちゃんと実験するにはWebSocket使った通信相手を立派に書けるように勉強しないといけない気もいたします。これは別の話か。知らんけど。

ブロックを積みながら(71) Node-RED、rpi-gpio in ノード へ戻る

ブロックを積みながら(73) Node-RED、Execした結果をDashboardに表示 へ進む