Я хотел отправить сообщение на свой пользовательский канал моего приложения Phoenix. Я присоединился к user_token с каналом как users:user_token
в user_channel.ex
. Мне удалось сделать это с другого контроллера, названного toy_controller
, вызвав метод широковещательной рассылки. Метод трансляции - в пользовательском канале. И я написал файл jQuery для обработки событий. Я искал что-то, что могло бы отправлять сообщения на тот же канал извне проекта, потому что я хотел делать некоторые вещи IoT. Я пробовал модуль Python под названием occamy.socket
и клиент JS Phoenix, который он использует для внутренних целей. Затем я всегда обнаруживал отключение. Я не могу определить точный адрес подключения к веб-сокету от Phoenix. Если я пробую использовать эту библиотеку Phoenix npm в самой папке проекта, она всегда говорит ReferenceError: window is not defined
. И, я думаю, это из-за части инициализации сокета в файле web/static/js/socket.js
, где он написан как
let socket = new Socket("/socket", {params: {token: window.userToken}})
, но я не уверен. То, что я пробовал, ниже
var Socket = require("phoenix-socket").Socket;
var socket = new Socket("ws://localhost:4000/socket");
В клиенте python я тоже пытался подключиться к этому адресу и получил ошибку отключения. Я хочу сделать это для целей Интернета вещей, где я хочу отслеживать данные датчиков пользователя. У каждого пользователя будут свои собственные датчики, за которыми нужно следить. Итак, я настроил канал topic:subtopic
канал как users:user_token
. Мне нужно отправлять сообщения с моего raspberry pi на этот канал, используя эти уникальные токены пользователей. Мои user_channel, user.js, app.js и socket.js приведены ниже.
//web/static/js/socket.js
import {Socket} from "phoenix"
let socket = new Socket("/socket", {params: {token: window.userToken}})
socket.connect()
export default socket
//web/static/app.js
import "phoenix_html"
import user from "./user"
#web/channels/user_channel.ex
defmodule Tworit.UserChannel do
use Tworit.Web, :channel
def join("users:" <> user_token, payload, socket) do
if authorized?(payload) do
{:ok, "Joined To User:#{user_token}", socket}
else
{:error, %{reason: "unauthorized"}}
end
end
def handle_in("ping", payload, socket) do
{:reply, {:ok, payload}, socket}
end
def handle_in("shout", payload, socket) do
broadcast socket, "shout", payload
{:noreply, socket}
end
def handle_out(event, payload, socket) do
push socket, event, payload
{:noreply, socket}
end
defp authorized?(_payload) do
true
end
def broadcast_change(toy, current_user) do
payload = %{
"name" => toy.name,
"body" => toy.body
}
Tworit.Endpoint.broadcast("users:#{current_user.token}", "change", payload)
end
end
//web/static/js/user.js
import socket from "./socket"
$(function() {
let ul = $("ul#em")
if (ul.length) {
var token = ul.data("id")
var topic = "users:" + token
// Join the topic
let channel = socket.channel(topic, {})
channel.join()
.receive("ok", data => {
console.log("Joined topic", topic)
})
.receive("error", resp => {
console.log("Unable to join topic", topic)
})
channel.on("change", toy => {
console.log("Change:", toy);
$("#message").append(toy["name"])
})
}
});