【Elixir】Phoenix サーバーサイドからユーザーにリアルタイム通知する
Elixir Phoenix サーバーサイドからユーザーに簡単にリアルタイム通知することが可能です。
確認環境
- Elixir 1.14.2
- Phoenix 1.6.3
Elixir Phoenixでの通知システムの作成
ElixirとPhoenixを使用して、リアルタイムの通知システムを作成する方法を探求します。このシステムは、特定のユーザーに対してメッセージの通知を送ることができ、ログイン中の全画面に適用されます。さらに、サーバーから特定のユーザーに通知を送ることも可能です。
チャネルの生成
まず、新しいチャネルを生成します。Phoenixでは、mix phx.gen.channel
コマンドを使用してチャネルを生成ができます。この例では、Notifications
という名前のチャネルを生成します。
1
| mix phx.gen.channel Notifications
|
このコマンドを実行すると、以下のファイルが生成されます。
lib/sample_web/channels/notifications_channel.ex
test/sample_web/channels/notifications_channel_test.exs
lib/sample_web/channels/user_socket.ex
assets/js/user_socket.js
WebSocket追加
通知用のWebSocketを endpoint.ex
に追加します。
1
2
3
| socket "/socket", SampleWeb.UserSocket,
websocket: true,
longpoll: false
|
Javascriptの用意
app.js
に生成されたJavaScriptを追加します。
1
| import "./user_socket.js"
|
チャネルの設定
生成されたnotifications_channel.ex
です。
今回は notifications:lobby
というチャンネルで全体通知をしてみます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
| defmodule SampleWeb.NotificationsChannel do
use SampleWeb, :channel
# "notifications:lobby" が接続するための部屋
# "notifications:" <> user_id などにすることで特定のユーザのみの通知も可能になる
@impl true
def join("notifications:lobby", payload, socket) do
if authorized?(payload) do
# 認証OKであれば接続
{:ok, socket}
else
# エラー
{:error, %{reason: "unauthorized"}}
end
end
# PING
@impl true
def handle_in("ping", payload, socket) do
{:reply, {:ok, payload}, socket}
end
# 通知
@impl true
def handle_in("shout", payload, socket) do
broadcast(socket, "shout", payload)
{:noreply, socket}
end
# 認証
defp authorized?(_payload) do
true
end
end
|
この関数は、ユーザーがチャネルに参加時に呼び出されます。
ユーザーIDをチャネルのトピックに含めることで、特定のユーザーに対して通知を送ることができます。
JavaScript 側の設定
JavaScript側でメッセージの通知処理を作成します。
今回は console.log
を出すだけにします。
1
2
3
4
5
6
7
8
9
10
11
| // 接続先のチャンネル
let channel = socket.channel("notifications:lobby", {})
channel.join()
.receive("ok", resp => { console.log("Joined successfully", resp) })
.receive("error", resp => { console.log("Unable to join", resp) })
// 処理
channel.on("shout", payload => {
console.log("New message:", payload.message)
})
|
この関数は、クライアントから shout
というイベントが送られてきたときに呼び出されます。
イベントにはメッセージが含まれており、このメッセージはbroadcast_to!
関数を使用して特定のユーザーに送信されます。
サーバーサイドから通知する
以下のコードを使用することによってサーバーサイドからフロントに対して通知を行うことができます。
今回は全通知です。
1
2
3
4
5
6
7
8
9
10
11
| Sample.Endpoint.broadcast(
# 対象チャンネル
"notifications:lobby",
# 対象のhandle_in
"shout",
# payload
%{
title: title,
message: message
}
)
|
まとめ
ElixirとPhoenixを使用して接続ユーザーに通知を送るシステムを作成する方法です。
このシステムは、リアルタイムの通知を可能にし、ログイン中の全画面に適用されます。
さらに、サーバーから特定のユーザーに通知を送ることも可能です。
参考