Adobe XDのWebSocket機能をNode-RED経由で試すメモ

この記事は Adobe XD Plugins Advent Calendar 2018 の4日目の記事です。
昨日は ten_A_cclab さんの、 XDオートメーションに関する雑感 でした。
さて、私ですが、Adobe XDのWebSocket機能をNode-RED経由で試してみたいと思います。
Adobe XDプラグイン機能によるfetchで外部サーバーのNode-REDにやりとりするメモ – 1ft-seabass.jp.MEMO
今回やりたいこと
Adobe XDプラグイン機能によるfetchで外部サーバーのNode-REDにやりとりするメモで、外部に接続するための仕組みは整ったので、今回はWebSocketでどう連携していくか試していきたいと思います。
このように、Adobe XDでプラグイン機能から外部ネットワークアクセス(Network API)を試してみるメモで紹介したHTTPと同じようにWebSocketは外部サーバーとやり取りができます。
重要な点としては、一度接続されればチャットでのやり取りのように、向こう側(外部サーバー側)からデータを受信することも可能なところです。
Node-REDでWebSocketの受け手を作る
Node-REDではこのような仕組みを作ります。
Node-REDはさくらのクラウドで構築していて、スタートアップスクリプトでシンプルに作成できます。
作り方も記事がありますので、詳しく知りたい方は さくらのクラウドのスタートアップスクリプトでNode-REDをインストールするメモ を参考にしてみてください。
ただ、今回は、このフロー図を見つつ「あー、 /adobexd というWebSocketの窓口でAdobeXDがやりとりするんだな」くらいで把握いただいていれば問題ないです!
フローデータのJSONファイル置いておきます。
[{"id":"e6d3dba.6ff6128","type":"websocket in","z":"dcac63b0.a8ba1","name":"","server":"53b10c13.d87304","client":"","x":430,"y":280,"wires":[["ae1382fb.2b4d2"]]},{"id":"e82747d3.b7bd38","type":"websocket out","z":"dcac63b0.a8ba1","name":"","server":"53b10c13.d87304","client":"","x":740,"y":340,"wires":[]},{"id":"ae1382fb.2b4d2","type":"debug","z":"dcac63b0.a8ba1","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":730,"y":280,"wires":[]},{"id":"ef2fe0e2.ab759","type":"inject","z":"dcac63b0.a8ba1","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":440,"y":340,"wires":[["e82747d3.b7bd38"]]},{"id":"e83ffb68.b74588","type":"comment","z":"dcac63b0.a8ba1","name":"外部サーバー","info":"","x":430,"y":220,"wires":[]},{"id":"53b10c13.d87304","type":"websocket-listener","z":"","path":"/adobexd","wholemsg":"false"}]
AdobeXDのほうを作る
さて、プラグインの方を作ってみましょう。
Overview · Adobe XD Plugin Reference
から調べていきます。やっぱり充実してますね!
WebSocketまわりの様子
WebSocket · Adobe XD Plugin Reference
こちらを見てみます。
2018/12/03 時点で
しっかり準備されています。
manifest.json
manifestでは「WebSocket Open」「WebSocket Close」「WebSocket Send Select Text」を動かすためのuiEntryPointsを設定しています。
{
"id": "NODE_RED_WEBSOCKET",
"name": "Adobe XD WebSocket Node-RED plugin",
"host": {
"app": "XD",
"minVersion": "13.0.0"
},
"version": "1.0.0",
"uiEntryPoints": [
{
"type": "menu",
"label": "WebSocket Send Select Text",
"commandId": "wsSendCommand"
}
,
{
"type": "menu",
"label": "WebSocket Open",
"commandId": "wsOpenCommand"
}
,
{
"type": "menu",
"label": "WebSocket Close",
"commandId": "wsCloseCommand"
}
]
}
main.js
WebSocket - Web API | MDN を参考にしつつ、以下のようにコードを書きました。
const { Text, Color } = require("scenegraph"); // XD拡張APIのクラスをインポート
// Adobe XDがNode-REDの該当URLにアクセスする
const wsurl = "ws://WEBSOCKET_SERVER_URL/adobexd";
let socket;
async function wsOpenFunction(selection) {
// WebSocket.send でデータ取得
// WebSocket 接続を作成する
if( socket ){
// 多重起動を防ぐ
console.log("WebSocket opened already!!!");
} else {
socket = new WebSocket(wsurl);
// WebSocket 接続をはじめる
socket.addEventListener('open', function (event) {
socket.send('Hello Server!');
console.log("WebSocket started");
});
// メッセージを待ち受ける
socket.addEventListener('message', function (event) {
console.log('Message from server ', event.data);
});
// WebSocket 接続を終了を検知
socket.addEventListener('close', function (event) {
console.log("WebSocket closed");
// WebSocketを消す
socket = null;
// 丁寧にremoveEventListenerすべき??
});
}
}
async function wsCloseFunction(selection) {
console.log("WebSocket close...");
socket.close();
}
async function wsHandlerFunction(selection) {
console.log("wsHandlerFunction was called!"); // Developer Consoleに出力
// 選択オブジェクトの取得
console.log(selection.items.length + " items are selected");
// selectList
const selectList = [];
// 選択したテキストを取得
for(let i = 0 ; i < selection.items.length ; i++ ){
const item = selection.items[i];
// 全テキストデータを順番に突っ込んでおく
selectList.push(item.text);
}
// WebSocket送信
socket.send(selectList);
}
module.exports = {
commands: {
wsSendCommand: wsHandlerFunction,
wsOpenCommand: wsOpenFunction,
wsCloseCommand: wsCloseFunction,
}
};
WEBSOCKET_SERVER_URLのところは、自分の設定したNode-REDのサーバーを設定しています。Node-REDの場合は1880というポートで待ち受けるのですがそのときはポートも忘れないようにしましょう。ここはWebSocketを立ててるサーバーによって変わってくるでしょう。設定合わせてお使いください。
ということで、このプラグインが無事インストールされていると、
このように、「WebSocket Open」「WebSocket Close」「WebSocket Send Select Text」機能が作られます。
動かしてみる
プラグインを動かしてみましょう。
WebSocket Open
まず、WebSocketを接続してみましょう。
WebSocket Openをクリックします。
Node-REDでできた先ほどのサーバーに connected 1 となって無事つながります。
そして、Adobe XDからNode-REDへメッセージが飛んでいます!
また、Node-REDから injectノードよりタイムスタンプのデータを送るのもAdobe XDが受け止めています!
さすがWebSocketレスポンス早い!
WebSocket Send Select
では選択したテキストを送ってみましょう。
このようにテキストを選択して「WebSocket Send Select 」をクリックします。
すると、まず送ったよとメッセージがDeveloper Consoleに出てきます。
Node-REDで受信されて、選択されたテキストがカンマ区切りで送られています。これは、リストを配列で入れたので展開してくれたのでしょう。JSON.stringfyを駆使すればJSON状に送ることも可能でしょう。
WebSocket Close
最後にクローズです。
WebSocket Closeをクリックします。
Developer consoleでも、WebSocket終了イベントが反応して、ちゃんとWebSocketがクローズされます。
Node-REDでも切断されたとステータスが変わりました。ちゃんと動いてる!
ということでAdobe XDでWebSocketが動いた!
Adobe XDでWebSocketで動きましたね!
雑感を書いておきます。
- Adobe XDでのWebSocketはイベントを受け取るaddEventListenerもあり素直に動く模様
- ドキュメントにsendしか書かれてないので、受信ダメなのかな?と思ったけど、なんら問題なかった
- .xdファイルを立ち上げるたびにウィンドウ単位で初期処理が走る模様
- WebSocketのインスタンスを追えるようにしておかないと管理しづらくなりそう
- ウィンドウごとの横断的な変数管理をできるのだろうか?
- WebSocketはHTTPをくらべてレスポンスが早い
- ちゃんと起動している間は終了しない限り生き続ける
- ドキュメントには明記されてないが WebSocket.readyState みたいなプロパティも使える模様
- WebSocket.readyState - Web API | MDN
- Known issues · Adobe XD Plugin Reference の2018/12/03時点では WebSocket.extensions が使えないという補足があるので各プロパティや関数ごとに細かくいろいろあるぽい
といったところを感じることができました。
WebSocketができると、AdobeXDからデータを送るだけでなく、リアルタイムに相互にやり取りができるようになるので、操作と連携できたり色々できそうですね!
引き続き調べていきます!
それでは、よき Node-RED & Adobe XD & WebSocket Lifeを!