1

私のPhoenixアプリケーションのユーザーチャンネルにメッセージを送信したかったのです。私はのusers:user_tokenというチャンネルのuser_tokenに参加しました。私はブロードキャストメソッドを呼び出すことによってtoy_controllerという別のコントローラから成功させました。ブロードキャスト方法はユーザーチャネルにあります。イベントを処理するjQueryファイルを作成しました。私は、プロジェクトの外部から同じチャンネルにメッセージを送ることができるものを探していました。なぜなら、IoTのものをやりたかったからです。私はoccamy.socketと呼ばれるPythonモジュールとPhoenixのJSクライアントを内部的に使用しようとしました。それから、私はいつも断線を見つけました。私はPhoenixからwebsocket接続の正確なアドレスを知ることができません。そのプロジェクトフォルダ自体のPhoenix npmライブラリで試してみると、常にReferenceError: window is not definedと表示されます。そして、私はそれがあるため、それがPhoenixチャンネルプロジェクト外のクライアントからのメッセージを送信します。

let socket = new Socket("/socket", {params: {token: window.userToken}})        

として書かれていますweb/static/js/socket.jsファイル内のソケットの初期化部分であると思うが、私はわかりません。私が試してみました事は、私もこのアドレスに接続しようと切断エラーを得たのpythonのクライアントで

var Socket = require("phoenix-socket").Socket; 
var socket = new Socket("ws://localhost:4000/socket"); 

を下回っています。私は、ユーザーのセンサーデータを監視するためにIoTの目的でそれを実行したいと考えています。各ユーザーには、監視対象のセンサーがあります。だから、チャネル topic:subtopicusers:user_tokenとして設定しました。私はラズベリーパイからこのチャンネルにメッセージを送る必要があります。私の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 
 
\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"]) 
 
    }) 
 
    } 
 
});

答えて

0

最後に、私はPythonプログラムから非同期にメッセージを送受信できました。これは、PythonのWebSocket asyncioモジュールを使用します。私はトピックに参加するための 'phx_join'のようなphoenixチャンネルに必要なさまざまなイベントを把握しました。そこで、以下のプログラムが働いた。

import asyncio 
import websockets 
import json 
import time 
from random import randint 
import serial 

from pyfirmata import Arduino, util 

board = Arduino('/dev/ttyACM1') 

it = util.Iterator(board) 
it.start() 
board.analog[0].enable_reporting() 
board.analog[1].enable_reporting() 
board.analog[2].enable_reporting() 
board.analog[3].enable_reporting() 

import RPi.GPIO as gpio 

gpio.setmode(gpio.BCM) 
gpio.setup(14, gpio.OUT) 


async def main(): 
    async with websockets.connect('ws://IP_addr:4000/socket/websocket') as websocket: 
     data = dict(topic="users:user_token", event="phx_join", payload={}, ref=None) 
     #this method joins the phoenix channel 
     await websocket.send(json.dumps(data)) 

     print("Joined") 

     while True: 
      msg = await retrieve() # waits for data from arduino analog pins 
      await websocket.send(json.dumps(msg)) # sends the sensor output to phoenix channel 

      print("sent") 
      call = await websocket.recv() # waits for anything from the phoenix server 
      control = json.loads(call) 

      # I have sent values from 2 buttons for swicthing a led with event 'control' 

      if(control['event'] == "control"): 
       event(control['payload']['val']) #swiches the led as per the input from event 'control' 


      print("< {}".format(call)) 

def event(val): 
    if(val == "on"): 
     gpio.output(14, True) 
    if(val == "off"): 
     gpio.output(14, False) 

async def retrieve(): 
    #analog read 
    load = board.analog[0].read() 
    pf = board.analog[1].read() 
    reading = board.analog[2].read() 
    thd = board.analog[3].read() 
    output = {"load": load, "pf": pf, "reading": reading,"thd": thd} 

    msg = dict(topic="users:user_token", event="sensor_output", payload=output, ref=None) # with 
    #event "sensor_outputs" 
    #the phoenix server displays the data on to a page. 

    print(msg) 
    return(msg) 

asyncio.get_event_loop().run_until_complete(main()) 
asyncio.get_event_loop().run_forever() 
関連する問題