6
1

More than 3 years have passed since last update.

WebsocketとPhoenixとwscatでチャットの動作確認

Last updated at Posted at 2020-07-18

はじめに

PhoenixのChannelを使ったチャットの作成をするとき、jsでフロントの部分を作成していることが多かったが、jsのページを用意したりしなくても動作確認ができるようにしようと思ってwscatを使ってみました。

まだ1対1のチャットを作成しようとしてる途中なので、1対1のチャットとしてはまだ機能ができていませんが、とりあえずwscatで動いてくれたので記事を書きました。(private_chatなのにlobbyがあって個別のchannelを用意できていない)

ezgif.com-video-to-gif.gif

このように、2つのクライアントがChannelに接続されており、チャットの状態を共有しています。
左側のクライアントでチャットを送信すると右側にも反映されます。

Websocketについて

このチャットで使うようなWebsocketというのは、通信で使われるプロトコルの一種です。
いつも使っているようなHTTPは、クライアントからサーバーへリクエストを送ってデータをもらうというのが基本の型です。
リアルタイムなチャットを作成する際は、リクエストを送らずにデータを受信できるようにしたいので、HTTPではなく双方向通信が可能なWebsocketを使います。

Phoenix側のコード

mix phx.newで何かしらのプロジェクトは作成してあるとして、Channelの部分を書いていきます。

web/channels/user_socket.ex
defmodule PappapWeb.UserSocket do
  use Phoenix.Socket

  ## Channels
  # channel "room:*", PappapWeb.RoomChannel
  channel "private_chat:*", PappapWeb.PrivateChatChannel

  ...
end
web/channels/private_chat_channel.ex
defmodule PappapWeb.PrivateChatChannel do
  use Phoenix.Channel

  # This function is called when client connects to this server.
  def join("private_chat:lobby", _msg, socket) do
    {:ok, socket}
  end

  def join("private_chat:" <> _private_room_id, _auth_msg, _socket) do
    {:error, %{reason: "unauthorized"}}
  end

  def handle_in("new_msg", %{"body" => body}, socket) do
    broadcast!(socket, "new_msg", %{body: body})
    {:noreply, socket}
  end
end

Websocketでサーバーに接続するときに、join/3が呼び出されます。
join/3の第一引数の"private_chat:lobby"というのは、topicと呼ばれます。
このtopicが一致しているチャンネルに接続すると、いずれかのクライアントが送信したメッセージがもう片方にも送信されます。

wscat

wscatは、Websocketのサーバー/クライアントで、コマンドラインから利用できます。
npmでインストールして利用することができます。


npm i -g wscat

インストールが完了したら、このようにしてwscatを動かしてみることができます。

wscat -c http://localhost:4000/socket/websocket/

オプションの-cを指定すると、wscatをwebsocketを利用するクライアントとして動かすことができます。

では、実際にサーバーを起動して動かしてみます。

動作確認

まずはPhoenixのサーバーを起動します。

mix phx.server

サーバーが正常に起動できたら、次はwscatを使ってWebsocketでサーバーに接続します。

wscat -c http://localhost:4000/socket/websocket/

image.png

このように表示されたら接続成功です。
次は、チャットルームに入ってみます。

{"topic":"private_chat:lobby","ref":1, "payload":{},"event":"phx_join"}

このリクエストをwscatを使ってサーバーへ送信します。
topicの部分が、さっきphoenixに書いたjoin/3の引数のものと一致すれば成功すると思います。
次は、チャットを送信します。

{"topic":"private_chat:lobby","ref":1, "payload":{"body": {"msg": "hello"}},"event":"new_msg"}

wscatでこのリクエストを送信することで、チャットをサーバーへ送信できると思います。
ターミナルを2つ以上開いて、同時にwscatでサーバーに接続して同じトピックのチャンネルに接続すると、リアルタイムでチャットの様子を見ることができると思います。
ぼくはiTerm2を使っているので、Command+dで画面を分割して様子を見ました。

さいごに

まだ完全なチャットは全然できていませんが、
とりあえずjsのページ以外からWebsocketを動かしてみることができました。

参考リンク

https://qiita.com/south37/items/6f92d4268fe676347160
https://tricknotes.hateblo.jp/entry/20120227/p1

6
1
0

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
  3. You can use dark theme
What you can do with signing up
6
1