今回は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にデータを載せるのが良いみたいです。)
各ノードの設定
websocket-in ノードの設定画面を開くと以下のようです(「名前」のところはwebsocket in と自分で書き込みましたが。)
実際にURLを設定するには赤丸で示した編集ボタンを押さねばなりません。
編集ボタンを押したところが以下に。URLは、デフォルト設定のパスそのままの文字列をこれまた自分で書き込みましたです。実際外部デバイスからは、Node-REDサーバのIPアドレスとポート番号を使って以下のようにアクセスできることになります。
ws://192.168.2.121:1880/ws/example
テスト用のInjectノードは、Node-RED側から「プッシュ」配信するJSONオブジェクトを送出するものです。プロパティabc にデータ123が載っておると。
さて websocket out ノードについては以下のようにしました。これだけ。
WebSocket通信のお相手
WebSocket通信のお相手は、Windowsパソコン上のPython3.8で動かすスクリプトといたしました。必要なモジュールは websocketsです。Pythonの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())
動作確認
上記のスクリプトを動作させれば
-
- スクリプト側からNode-RED上のwebsocket-inノードに”Hello world!”が送信される(その後は2のアクションとられるまで「待ち」)
- Node-RED側のInjectノードのボタンを押すとスクリプト側にJSONオブジェクトが到来して表示される(そしてスクリプトの実行完了。)
2は1のレスポンスではなく、あくまでNode-RED側からの「プッシュ」であります。
まずはスクリプトからNode-RED側へ送られたオブジェクトの様子が以下に。
Injectノードから送られたJSONオブジェクトの着信がこちらに。
まあ、WebSocketうごいてるんでないかい。ちゃんと実験するにはWebSocket使った通信相手を立派に書けるように勉強しないといけない気もいたします。これは別の話か。知らんけど。