LoginSignup
3

More than 1 year has passed since last update.

posted at

updated at

Organization

p5.js Web Editor で WebSocket を扱ってみる(wscat でローカル環境にサーバーを準備して試したり、OBS連携を実行)

過去の記事では OBS の外部からの操作や、それを Slack と連携させてみたり、その他 MQTT とともに IoT系の話で使っている WebSocket。

●「websocket user:youtoy」の検索結果 - Qiita
 https://qiita.com/search?q=websocket+user%3Ayoutoy

この WebSocket を p5.js Web Editor 上で使って、何か面白い外部連携的なことができないかな、とふと思ったのがこの記事を書いたきっかけです。
それで、まずは WebSocket を利用するプログラムと、お手軽に試せそうな外部連携を試してみます。
(wscat を使った動作確認と、OBS のシーン切り替えをやってみます)

WebSocket について

リアルタイム通信でおなじみの WebSocket。
Web系の情報を調べるのにいつもお世話になる MDN のサイトでは、以下のページなどに情報が書かれています。

●WebSocket - Web API | MDN
 https://developer.mozilla.org/ja/docs/Web/API/WebSocket

冒頭に書いた MQTT だと、ブラウザ上で動かすのに MQTT.js等のライブラリが必要ですが、WebSocket であればライブラリ不要で呼び出せます。

ひとまず、シンプルな構成のものを試すため、上記のページのサンプルを見つつ実装をしてみます。

WebSocket の基本の処理

上記の MDN のページに書かれたサンプルを以下に転載してみます。

// WebSocket 接続を作成
const socket = new WebSocket('ws://localhost:8080');

// 接続が開いたときのイベント
socket.addEventListener('open', function (event) {
    socket.send('Hello Server!');
});

// メッセージの待ち受け
socket.addEventListener('message', function (event) {
    console.log('Message from server ', event.data);
});

上記の1つ目のブロックは、接続を行うための処理で、ローカルにポート番号 8080 でサーバーを立てている前提になっています。
上記の 2つ目のブロックは、接続が確立された際の処理と、その接続確立時にサーバーへメッセージを送る処理が書かれています。
3つ目のブロックは、サーバーにメッセージが送られたものを受けとる部分の処理です。

サーバーの準備(wscat を利用)

WebSocket用のサーバーの準備に関して、もし  npmコマンドが使える状態であれば、wscat を利用するのが手軽かもしれません。
今回はこの方法を使って進めます。

その他、以下の記事で扱った OBSの外部からの制御については、WebSocketプラグインを導入してそれを立ち上げれば、OBS のプラグインがローカルにサーバーを立ててくれたりします。

●OBS をスマホや M5GO(M5Stack)から遠隔制御 〜 MQTT や obs-websocket を利用 〜 - Qiita
 https://qiita.com/youtoy/items/23fb0e16f1a4428b5c9b

wscat を使って軽いお試し

とりあえず上で少し書いていた wscat を使ってサーバーを立ち上げてみます。

wscat を使った処理

以下の記事を書いた際には、wscat のインストール&実行に npx コマンドを使って一時的なパッケージインストールを行っていました。

●WebSocket のサーバー・クライアントをコマンドラインで簡単に実行する(npx と wscat) - Qiita
 https://qiita.com/youtoy/items/72bbd5f6b0893756da36

今回は、「ローカルインストールを用いて、それを npx コマンドで実行する」という別のやり方で進めてみます。

そこで今回は、グローバルインストールで wscat を準備して進めていきます。
まずは、適当なフォルダで以下を実行します。

$ npm install -g wscat

その後、以下のコマンドを使い、ポート番号 8080 を指定してサーバーを立ち上げます。

$ npx wscat -l 8080

以下は Mac のターミナル上で実行した例ですが、「8080ポートで待ち受け中」というメッセージが表示された状態になります。
サーバーを起動.jpg

p5.js Web Editor から WebSocketサーバーへメッセージ送信

それでは、p5.js Web Editor でプログラムを書いて、WebSocketサーバーへ接続してメッセージを送信してみます。

キャンバスや背景色の指定は残しつつ、 draw() の中で処理を行わないので一旦 noLoop(); を適用しています。
そしてメッセージ送信のトリガーはマウスクリックにして、クリック時にサーバーにメッセージが送られるという実装を加えています。

let socket;

function setup() {
  createCanvas(400, 400);
  background(220);
  noLoop();
  socket = new WebSocket("ws://localhost:8080");

  socket.addEventListener("open", function (event) {
    console.log("OK!");
  });
}

function draw() {}

function mousePressed() {
  if (socket) {
    socket.send("Hello Server!");
  }
  return false;
}

先ほどコマンドで立ち上げたサーバーはそのままで上記のプログラムを実行し、マウスのクリックイベントを 1回発生させると、以下のようになることが確認できます。
クライアントからの接続とメッセージ送信を行った状態.jpg

上の画像 3行目の出力で、p5.js Web Editor側からの接続が完了できたことと、4行目の出力で socket.send("Hello Server!"); を 1回実行してみた際(マスクのクリックをしてみた際)の出力がサーバー側に届いていることが確認できました。

p5.js Web Editor で WebSocketサーバーからのメッセージを受信する

今度は、p5.js Web Editor がメッセージを受けとる側の処理を試してみます。
そのためには、p5.js Web Editor へメッセージを送る役割のものが必要になりますが、先ほど立ち上げた wscat の WebSocketサーバーがその役割を担えるので、それで進めます。

MDN のサイトのサンプルを見つつ、p5.js Web Editor 上でメッセージを受信する側のプログラムも実装してみます。

let socket;


function setup() {
  createCanvas(400, 400);
  background(220);
  noLoop();

  socket = new WebSocket("ws://localhost:8080");

  socket.addEventListener("open", function (event) {
    console.log("OK!");
  });

  socket.addEventListener("message", function (event) {
    console.log("Message from server ", event.data);
  });
}

function draw() {}

function mousePressed() {
  if (socket) {
    socket.send("Hello Server!");
  }
  return false;
}

追加したのは、 socket.addEventListener("message", function (event) {...} の部分です。

それでは、WebSocketサーバーが立ち上がった状態で、上記のプログラムも実行しつつ、サーバー側からメッセージを送ってみます。

先ほどの状態で、サーバー側の最後の行が「>」と表示された状態になっていますが、そこで「Hello!!」など適当な文字列を入力して実行してみます。
サーバー側からのメッセージ送信.jpg

そうすると、サーバーからクライアントへのメッセージ送信が行われます。
p5.js Web Editor側のコンソールを確認してみると、以下のような表示がされているのを確認できました。
p5.js側のコンソール.jpg

サーバー側で入力したメッセージを受信できているのが分かります。

wscat でのクライアントの実行について補足

今回、p5.js Web Editor へメッセージを送る際、wscat で用意したサーバーを用いました。

wscat には、コマンドでクライアントを準備する仕組みもあります。
それを一時的なインストール(※ npx によるインストール)やローカルでのインストール(※ 上記のやり方)を用いた場合、以下のコマンドでサーバーに接続した際に「code: 1006, reason: ""」というメッセージが出て、クライアントが終了してしまう状態になりました。

$ npx wscat -c ws://localhost:8080

現状、wscat でクライアントを準備したい場合、公式のインストール方法で書かれている以下のグローバルインストールを用いるのが無難なようです。

$ npm install -g wscat

上記でインストールした場合、サーバー・クライアントを実行するコマンドは以下となります。

# サーバー側
$ wscat -l 8080
# クライアント側
$ wscat -c ws://localhost:8080

OBS と p5.js Web Editor を連携させてみる

あともう 1つお試しをしてみます。
具体的には OBS のシーン切り替えを p5.js Web Editor から実行してみます。

OBS のプラグインを準備する

そのためには、過去の記事でも扱った以下のプラグインを使いますが、詳細は過去の記事の説明などをご覧ください。

●obs-websocket - Remote-control OBS Studio from WebSockets | OBS Forums
 https://obsproject.com/forum/resources/obs-websocket-remote-control-obs-studio-from-websockets.466/
●Palakis/obs-websocket: Remote-control OBS Studio through WebSockets
 https://github.com/Palakis/obs-websocket

OBS にプラグインを導入すると、OBS のメニューの「ツール」の中に上記のプラグインに関するメニューが追加されます。
スクリーンショット_2021-08-14_14_36_46.jpg

これを開いて、適宜設定を変更して利用します。
「サーバーポート」は他の別のプログラム等で使われてなければ、デフォルト設定で大丈夫ですが、何らか衝突が起こった際は変更をしておきましょう。
また、「認証を有効にする」の項目は、利用手順が少し複雑になるので今回はチェックを外しています。
Websocket_サーバー設定.jpg
そもそも今回は  OBS をローカルで動作させており、OBS上から動作開始をさせている間だけ動くもので、その PC に外部から接続できる経路がない状態なので、この設定を外しています。
(OBS を第3者が利用可能な、クラウド上で動作させている状況などといった場合は、条件が変わってきますので適宜設定を変更してください)

OBS のシーンを複数準備する

今回は OBS のシーン切り替えを p5.js Web Editor から行います。

その切り替え対象となる複数のシーンを、OBS上で準備します。
自分は、過去の記事を書いた際に用意したものを流用します。
OBSのシーン.jpg
ここでの設定に関して、「シーンの名称」は、この後で利用することになります。

p5.js Web Editor のプログラム

上記の通り OBS上で 3つのシーンを用意しました。
その切り替えは、マウスクリックでなく数字キーの入力で行う形にしてみます。

以下の公式リファレンスの中の「key」のほうで判別する処理を書いていきます。
●reference | keyCode
 https://p5js.org/reference/#/p5/keyCode
keyCode.jpg

また、シーン切り替えを行う際は JSON を送る必要があります。
以下の記事に書いた、公式の仕様で規定されたシーン切り替え用のフォーマットで送信してみます。
●Node-RED を使って OBS を遠隔操作してみた話(obs-websocket を利用)|豊田 陽介|note
 https://note.com/youtoy/n/nf404040a91c0

{
   "request-type":"SetCurrentScene",
   "message-id":"(適当に決めたID)",
   "scene-name":"(OBS上で設定したシーンの名前)"
}

プログラムは以下の通りです。
"(適当に決めたID)""(OBS上で設定したシーンの名前)" という部分が 3箇所ありますが、ここは適宜書きかえてご利用ください。

let socket;
const sceneJSON = [
  {
    "request-type": "SetCurrentScene",
    "message-id": "(適当に決めたID1)",
    "scene-name": "(OBS上で設定したシーンの名前1)",
  },
  {
    "request-type": "SetCurrentScene",
    "message-id": "(適当に決めたID2)",
    "scene-name": "(OBS上で設定したシーンの名前2)",
  },
  {
    "request-type": "SetCurrentScene",
    "message-id": "(適当に決めたID3)",
    "scene-name": "(OBS上で設定したシーンの名前3)",
  },
];

function setup() {
  createCanvas(400, 400);
  background(220);
  noLoop();

  socket = new WebSocket("ws://localhost:4445");

  socket.addEventListener("open", function (event) {
    console.log("OK!");
  });

  socket.addEventListener("message", function (event) {
    console.log("Message from server ", event.data);
  });
}

function draw() {}

function keyPressed() {
  switch (key) {
    case "1":
      socket.send(JSON.stringify(sceneJSON[0]));
      break;
    case "2":
      socket.send(JSON.stringify(sceneJSON[1]));
      break;
    case "3":
      socket.send(JSON.stringify(sceneJSON[2]));
      break;
    default:
      break;
  }
}

OBS を起動してプラグインを実行した状態で、さらに上記を実行して数字キー(1 or 2 or 3)を押すと、OBS上のシーンが切り替わるのを確認できました。

まとめ

今回、p5.js Web Editor上のプログラムで WebSocket を扱い、wscat で立てたローカルの WebSocket との通信や、プラグインを導入した OBS の操作を行ってみました。

とりあえず今回は過去のリソースなどを利用し、手軽に実行できそうな例でやってましたが、「ガジェット・ハードウェア連携」や「PC と スマホのそれぞれのブラウザ間での連携」などで活用すると面白いことができそうです。

また、リアルタイム通信系の JavaScript実装は、個人的には MQTT をよく使っていたので、以前よく使ったこともある MQTT.js のブラウザ版の処理を用いたものも試せればと思います。

●「mqtt user:youtoy」の検索結果 - Qiita
 https://qiita.com/search?q=mqtt+user%3Ayoutoy

【追記】 MQTTバージョンも記事にしました! & お試し

MQTT を使った場合の実装方法について、記事を書きました!

●p5.js Web Editor で MQTT を扱ってみる(MQTT.js や shiftr.io Desktop を利用) - Qiita
 https://qiita.com/youtoy/items/7c58de69b4b20543a5b5

また、このようなことを MQTTバージョンのほうで試したりしました。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
3