如何从Arduino连接到Action Cable Websocket?

时间:2018-12-13 05:35:43

标签: ruby-on-rails websocket arduino actioncable arduino-esp8266

我用Python Flask构建了一个应用程序,该应用程序通过将以表格形式选择的颜色广播给websocket通道的所有成员来控制Arduino上的LED灯。我现在在Rails中重建并尝试确定Arduino如何指定要加入的通道。我已经开始连接到WebSocket,并且似乎正在从Rails中获得以下信息:[WSc] Received text: {"type":"ping","message":1544679171}

现在,我只需要确定如何发送请求以从ArduinoChannel专门流式传输,但是我不确定该如何处理。我尝试将参数添加到webSocket.begin中,但这似乎没有任何影响。

以下是我的Arduino代码供参考:

#include <ESP8266WiFi.h>
#include <WebSocketsClient.h>
#include <ArduinoJson.h>
#include <EEPROM.h>

// Initialize pins
int redpin = D0;
int greenpin = D2;
int bluepin = D4;

//// Connecting to the internet
const char* ssid = "**************";
const char* password = "******";

// Setting up the websocket client
WebSocketsClient webSocket;

// Set up the WiFi client;
WiFiClient client;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);

  pinMode(redpin, OUTPUT);
  pinMode(bluepin, OUTPUT);
  pinMode(greenpin, OUTPUT);


  delay(10);
  WiFi.begin(ssid, password);
  while(WiFi.status()!= WL_CONNECTED) {
    Serial.print(".");
    delay(500);  
  }
  Serial.println("");
  Serial.print("IP Address: ");
  Serial.print(WiFi.localIP() + "\n");
  Serial.print(WiFi.macAddress() + "\n");

  // Initializing the WS2812B communication
  setRgb(255,80,90);

  // Initializing the websocket connection

  webSocket.begin("192.168.1.93",3000, "/cable" );
//  webSocket.sendTXT('{"command":"subscribe","identifier":"{\"channel\":\"ArduinoChannel\"}"', 0);
  webSocket.onEvent(webSocketEvent);
  webSocket.setReconnectInterval(5);

}
void loop() {
  // put your main code here, to run repeatedly:
  webSocket.loop();

} 

void webSocketEvent(WStype_t type, uint8_t *payload, size_t length) {
  switch(type) {
    Serial.write(type);
    case WStype_DISCONNECTED:
      Serial.printf("[WSc] Disconnected!\n");
      break;
    case WStype_CONNECTED:
      Serial.printf("[WSc] Connected to url: %s\n", payload);
      break;
    case WStype_TEXT:
      Serial.printf("[WSc] Received text: %s\n", payload);
      DynamicJsonBuffer jBuffer;
      JsonObject &root = jBuffer.parseObject(payload);
      setRgb(root["r"],root["g"],root["b"]);
      break;
  }
}

  void setRgb(uint8_t r, uint8_t g, uint8_t b) {
  analogWrite(redpin, r);
  analogWrite(bluepin, b);
  analogWrite(greenpin, g);
  delay(10);
}

1 个答案:

答案 0 :(得分:1)

TL; DR:

  

我如何发送请求以从ArduinoChannel专门流式传输

要从ArduinoChannel接收流,您需要通过Websocket连接从Arduino客户端发送以下字符串数据来“订阅”:

"{\"command\":\"subscribe\",\"identifier\":\"{\\\"channel\\\":\\\"ArduinoChannel\\\"}\"}"

...与您注释掉的sendTXT代码几乎相同,但是可能您只是在错误地“转义”了双引号。

参考:

我追溯到ActionCable here的JS客户端版本

  1. App.cable.subscriptions.create('ArduinoChannel')
    
  2. Subscriptions.prototype.create = function create(channelName, mixin) {
      var channel = channelName;
      var params = (typeof channel === "undefined" ? "undefined" : _typeof(channel)) === "object" ? channel : {
        channel: channel
      };
      // params = { channel: "ArduinoChannel" }
      var subscription = new Subscription(this.consumer, params, mixin);
      return this.add(subscription);
    };
    
  3. function Subscription(consumer) {
      var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
      var mixin = arguments[2];
      classCallCheck(this, Subscription);
      this.consumer = consumer;
      this.identifier = JSON.stringify(params);
      extend(this, mixin);
    }
    
  4. Subscriptions.prototype.add = function add(subscription) {
      this.subscriptions.push(subscription);
      this.consumer.ensureActiveConnection();
      this.notify(subscription, "initialized");
      this.sendCommand(subscription, "subscribe");
      return subscription;
    };
    
  5. Subscriptions.prototype.sendCommand = function sendCommand(subscription, command) {
      var identifier = subscription.identifier;
      // command =  "subscribe"; identifier = JSON.stringify(params) = '{"channel":"ArduinoChannel"}';
      return this.consumer.send({
        command: command,
        identifier: identifier
      });
    };
    
  6. Consumer.prototype.send = function send(data) {
      // data = { command: 'subscribe', identifier: '{"channel":"ArduinoChannel"}' }
      return this.connection.send(data);
    };
    
  7. Connection.prototype.send = function send(data) {
      if (this.isOpen()) {
        // JSON.stringify(data) = '{"command":"subscribe","identifier":"{\"channel\":\"ArduinoChannel\"}"}'
        this.webSocket.send(JSON.stringify(data));
        return true;
      } else {
        return false;
      }
    };