Elixir/PhoenixのChannelにRaspberry Pi(node.js)から接続してみる



Elixir/Phoenixアプリケーションが動いているサーバにRaspberry PiからWebSocketでの接続をしてみます。
PhoenixにはChannelという便利な機能があるので、今回は特にこのChannelに接続する方法を書いていきます。
Raspberry Piの方はnode.jsから利用します。
PhoenixのChannelを外部のアプリケーションから利用する場合にはphoenix-jsというパッケージを利用すれば簡単に出来ます。
www.npmjs.com

#!/usr/bin/env_node

var phoenix = require('phoenix-js');
var socket = new phoenix.Socket('wss://192.168.0.1/websocket');

socket.connect();
var channel = socket.channel('websocket:api');

channel.join()
  .receive('ok', resp => {
    console.log(`> joining channel  ${channel.topic}`);
  })
  .receive("error", reason => console.log(`Error joining channel: ${reason}`));

とりあえずこれで動かしてみます。

pi@raspberrypi:~/dev $ node client.js
/home/pi/dev/node_modules/phoenix-js/dist/cjs/main.js:451
    this.transport = opts.transport || window.WebSocket || LongPoll;
                                       ^

ReferenceError: window is not defined
    at new Socket (/home/pi/dev/node_modules/phoenix-js/dist/cjs/main.js:451:40)
    at Object.<anonymous> (/home/pi/dev/client.js:43:14)
    at Module._compile (module.js:409:26)
    at Object.Module._extensions..js (module.js:416:10)
    at Module.load (module.js:343:32)
    at Function.Module._load (module.js:300:12)
    at Function.Module.runMain (module.js:441:10)
    at startup (node.js:139:18)
    at node.js:968:3

エラー。なるほど。
PhoenixのChanelではWindowオブジェクトのWebSocketを利用しているので、それが見つからないというエラー。
であれば、node.jsからWebSocketを利用することができるパッケージを探してみればよさそうです。

www.npmjs.com

ありました。
PhoenixのSocketを生成する時に、transport オプションを追加してみます。

var socket = new phoenix.Socket('wss://192.168.0.1/websocket', {transport: require('websocket').w3cwebsocket});

これでリトライ。

pi@raspberrypi:~/dev $ node client.js
> joining channel websocket:api

無事に繋がりました。


Raspberry Pi 3でつくる IoTプログラミング

Raspberry Pi 3でつくる IoTプログラミング

Programming Phoenix: Productive |> Reliable |> Fast (English Edition)

Programming Phoenix: Productive |> Reliable |> Fast (English Edition)