I wanted to send a message to my user channel of my Phoenix Application. I have joined a user_token with the channel as users:user_token
in the user_channel.ex
. I was successful doing it from another controller called the toy_controller
by calling a broadcast method. The broadcast method is in the user channel. And I have written a jQuery file to handle the events. I was looking for something which can send messages to the same channel from outside of the project, because I wanted to do some IoT stuff. I have tried a python module called occamy.socket
and the JS client of Phoenix that it uses inteally. Then, I found a disconnection always. I can't figure out the exact address of the websocket connection from Phoenix. If I am trying it with that Phoenix npm library in that project folder itself, it says ReferenceError: window is not defined
always. And, I think it is because of the initialization part of the socket in the web/static/js/socket.js
file where it's written as
let socket = new Socket("/socket", {params: {token: window.userToken}})
, but I am not sure. The thing that I have tried is below
var Socket = require("phoenix-socket").Socket;
var socket = new Socket("ws://localhost:4000/socket");
In the python client, I was also trying to connect to this address and got a disconnection error. I want to do it for IoT purposes, where I want to monitor sensor data of a user. Each user will be having their own sensors to be monitored. So, I have configured the channel topic:subtopic
channel as users:user_token
. I need to send messages from my raspberry pi to this channel using those unique tokens of the users. My user_channel, user.js, app.js and 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"
files are given below.
#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"]) }) }
});