[Elixir]Channelを使った実装とテストコード

Phoenixは、WebSocketを提供するためにChannelという機構を持っています。少し探せば色々参考になるコードもあるのですが、テストコードも書いてみたのでここに備忘録としてのせておきます。

Pathの設定

Phoenix v1.2 の時点では、以下の通り endpoint.ex 内でWebSocketのコネクションを成功させるパスとその処理先を決めます。

https://github.com/KazuCocoa/my_chat_ex/blob/master/lib/my_chat_ex/endpoint.ex#L4

例えば、

socket "/socket", MyChatEx.UserSocket
socket "/socket/other", MyChatEx.OtherSocket

とした時、 /socket にWebSocketで接続を確立するとその処理先は MyChatEx.UserSocket/socket/other に対しては MyChatEx.OtherSocket が処理先になります。

WebSocketの確立では、transportの指定が必要です。このtransportの指定により、Phoenix Frameworkでは処理対象がWebSocketか、Long pollingかを判定します。

これは、 user_socket.ex におけるChannel Routesの指定箇所で合わせて処理されます。具体的には、以下のようにwebsocketを指定します。

  transport :websocket, Phoenix.Transports.WebSocket

これにより、最終的には以下のパスが構築され、このパスへのWebSocketの通信がそのまま MyChatEx.UserSocket などの処理へ通されます。

http://localhost:4000/socket/websocket
ws://localhost:4000/socket/websocket

このパスは、たとえばChromeのinspectionにより確認可能です。

Channel

Channelにおける内部処理は use Phoenix.Channel によるコールバックの実装で最低限は実現可能になります。同期的に通信する応答や、非同期で行う通信など。

https://github.com/KazuCocoa/my_chat_ex/blob/dc536e573c9b01d313cc4aaad89cf76208a8da13/web/channels/my_room_channel.ex

Channelに対する認証

このChannelには、認証をかけることが容易に出来ます。これをうまく使うと、WebSocketの確立なども認証されていないものは弾く、という処理が容易に可能です。

https://github.com/KazuCocoa/my_chat_ex/blob/dc536e573c9b01d313cc4aaad89cf76208a8da13/web/channels/user_socket.ex#L24

https://github.com/KazuCocoa/myChatEx/blob/dc536e573c9b01d313cc4aaad89cf76208a8da13/web/router.ex#L28

Test code

Channelに対するテストコードは以下

https://github.com/KazuCocoa/myChatEx/blob/dc536e573c9b01d313cc4aaad89cf76208a8da13/test/channels/my_room_channel_test.exs

最後に

Elixir x Phoenixにて、このようなWebSocket実装などをBEAM VM上に構築できるというのは良いですね。それに特化した形でフレームワークのサポートもしていますし。

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s