Ich wollte eine Nachricht an meinen Benutzerkanal meiner Phoenix-Anwendung senden. Ich habe ein user_token mit dem Kanal als users:user_token
in der user_channel.ex
verbunden. Ich habe es erfolgreich von einem anderen Controller namens toy_controller
getan, indem ich eine Broadcast-Methode aufgerufen habe. Die Broadcast-Methode befindet sich im Benutzerkanal. Und ich habe eine jQuery-Datei geschrieben, um die Ereignisse zu behandeln. Ich suchte nach etwas, das Nachrichten von außerhalb des Projekts an denselben Kanal senden kann, weil ich etwas IoT-Zeug machen wollte. Ich habe versucht, ein Python-Modul namens occamy.socket
und den JS-Client von Phoenix, die es intern verwendet. Dann habe ich immer eine Trennung gefunden. Ich kann die genaue Adresse der Websocket-Verbindung von Phoenix nicht herausfinden. Wenn ich es mit dieser Phoenix npm-Bibliothek in diesem Projektordner selbst versuche, heißt es immer ReferenceError: window is not defined
. Und ich glaube, es ist wegen der Initialisierung Teil der Buchse in der web/static/js/socket.js
Datei ist, wo es alsPhoenix Channel sendet Nachrichten von einem Client außerhalb des Projekts
let socket = new Socket("/socket", {params: {token: window.userToken}})
geschrieben, aber ich bin nicht sicher. Die Sache, die ich versucht habe, ist unter
var Socket = require("phoenix-socket").Socket;
var socket = new Socket("ws://localhost:4000/socket");
Im Python-Client, wurde ich auch an diese Adresse zu verbinden versucht und bekam einen Trennungsfehler. Ich möchte es für IoT-Zwecke tun, wo ich Sensordaten eines Benutzers überwachen möchte. Jeder Benutzer muss seine eigenen Sensoren überwachen lassen. Also, ich habe den Kanal topic:subtopic
Kanal als users:user_token
konfiguriert. Ich muss Nachrichten von meinem raspberry pi an diesen Kanal senden, indem ich diese einzigartigen Token der Nutzer benutze. Mein user_channel, user.js, app.js und socket.js sind unten angegeben.
//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
\t \t
// 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 => {
\t console.log("Change:", toy);
\t $("#message").append(toy["name"])
})
}
});