Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Connect Websocket client to Socket.IO server #136

Open
TannerGilbert opened this issue Jul 16, 2022 · 1 comment
Open

Connect Websocket client to Socket.IO server #136

TannerGilbert opened this issue Jul 16, 2022 · 1 comment
Labels
type: imperfection Perceived defect in any part of project

Comments

@TannerGilbert
Copy link

TannerGilbert commented Jul 16, 2022

I'm currently trying to connect my Arduino Portenta H7 to a Socket.IO server, but I'm unable to establish a connection.

Arduino code:

#include <SPI.h>
#include <Ethernet.h>
#include <ArduinoHttpClient.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(10, 0, 0, 100);

EthernetClient ethernet;

char serverAddress[] = "10.0.0.14/socket.io/?EIO=4&transport=websocket";  // server address
int port = 8080;

WebSocketClient client = WebSocketClient(ethernet, serverAddress, port);
int count = 0;

void setup() {

  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  Serial.println("Ethernet WebServer Example");

  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);

  // Check for Ethernet hardware present
  if (Ethernet.hardwareStatus() == EthernetNoHardware) {
    Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
    while (true) {
      delay(1); // do nothing, no point running without Ethernet hardware
    }
  }
  if (Ethernet.linkStatus() == LinkOFF) {
    Serial.println("Ethernet cable is not connected.");
  }
}

void loop() {
  Serial.println("starting WebSocket client");
  client.begin();

  while (client.connected()) {
    Serial.print("Sending hello ");
    Serial.println(count);

    // send a hello #
    client.beginMessage(TYPE_TEXT);
    client.print("hello ");
    client.print(count);
    client.endMessage();

    // increment count for next message
    count++;

    // check if a message is available to be received
    int messageSize = client.parseMessage();

    if (messageSize > 0) {
      Serial.println("Received a message:");
      Serial.println(client.readString());
    }

    // wait 5 seconds
    delay(5000);
  }

  Serial.println("disconnected");
}

Socket.IO Example Server:

import socketio
from aiohttp import web

sio = socketio.AsyncServer()
app = web.Application()
sio.attach(app)


async def index(request):
    with open("index.html") as f:
        return web.Response(text=f.read(), content_type="text/html")


@sio.on("*")
def catch_all(event, sid, data):
    print("Socket ID: ", sid)
    print(data)


app.router.add_get("/", index)

if __name__ == "__main__":
    web.run_app(app)

Versions:

  • python-socketio: 5x
  • Engine.IO: 4
  • Socket.IO 5

I also tried using arduinoWebSockets, but I couldn't get it to work with the Arduino Portenta H7. Any help is greatly appreciated.

@TannerGilbert
Copy link
Author

Got it to work with arduinoWebSockets and node.js.

Server:

const io = require('socket.io')(8888);
io.on('connection', (socket) => {
    console.info(`[${socket.id }] new connection`, socket.request.connection.remoteAddress);

    socket.on('message', function(message) {        
        console.log(message)
        socket.broadcast.emit("message", message);
    });

    socket.on('reconnect', function() {
        console.warn(`[${socket.id }] reconnect.`);
    });

    socket.on('disconnect', () => {
        console.error(`[${socket.id }] disconnect.`);
    });
});

Client:

#include <Arduino.h>

#include <Ethernet.h>
#include <ArduinoJson.h>
#include <WebSocketsClient.h>
#include <SocketIOclient.h>

byte mac[] = {
    0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(10, 0, 0, 100);

EthernetClient ethernet;

SocketIOclient socketIO;

void socketIOEvent(socketIOmessageType_t type, uint8_t *payload, size_t length)
{
  switch (type)
  {
  case sIOtype_DISCONNECT:
    Serial.println("[IOc] Disconnected!");
    break;
  case sIOtype_CONNECT:
    Serial.println("[IOc] Connected!");
    // join default namespace (no auto join in Socket.IO V3)
    socketIO.send(sIOtype_CONNECT, "/");
    break;
  case sIOtype_EVENT:
  {
    char *sptr = NULL;
    int id = strtol((char *)payload, &sptr, 10);
    Serial.print("[IOc] get event: ");
    // Serial.print(payload);
    Serial.print(" id: ");
    Serial.println(id);
    if (id)
    {
      payload = (uint8_t *)sptr;
    }
    DynamicJsonDocument doc(1024);
    DeserializationError error = deserializeJson(doc, payload, length);
    if (error)
    {
      Serial.print(F("deserializeJson() failed: "));
      Serial.println(error.c_str());
      return;
    }

    String eventName = doc[0];
    Serial.print("[IOc] event name: ");
    Serial.println(eventName.c_str());

    // Message Includes a ID for a ACK (callback)
    if (id)
    {
      // creat JSON message for Socket.IO (ack)
      DynamicJsonDocument docOut(1024);
      JsonArray array = docOut.to<JsonArray>();

      // add payload (parameters) for the ack (callback function)
      JsonObject param1 = array.createNestedObject();
      param1["now"] = millis();

      // JSON to String (serializion)
      String output;
      output += id;
      serializeJson(docOut, output);

      // Send event
      socketIO.send(sIOtype_ACK, output);
    }
  }
  break;
  case sIOtype_ACK:
    Serial.print("[IOc] get ack: ");
    Serial.println(length);
    break;
  case sIOtype_ERROR:
    Serial.print("[IOc] get error: ");
    Serial.println(length);
    break;
  case sIOtype_BINARY_EVENT:
    Serial.print("[IOc] get binary: ");
    Serial.println(length);
    break;
  case sIOtype_BINARY_ACK:
    Serial.print("[IOc] get binary ack: ");
    Serial.println(length);
    break;
  }
}

void setup()
{
  Serial.begin(115200);

  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);

  // Check for Ethernet hardware present
  if (Ethernet.hardwareStatus() == EthernetNoHardware)
  {
    Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
    while (true)
    {
      delay(1); // do nothing, no point running without Ethernet hardware
    }
  }
  if (Ethernet.linkStatus() == LinkOFF)
  {
    Serial.println("Ethernet cable is not connected.");
  }

  // server address, port and URL
  socketIO.begin("10.0.0.14", 8888, "/socket.io/?EIO=4");

  // event handler
  socketIO.onEvent(socketIOEvent);
}

unsigned long messageTimestamp = 0;
void loop()
{
  socketIO.loop();

  uint64_t now = millis();

  if (now - messageTimestamp > 2000 && socketIO.isConnected())
  {
    messageTimestamp = now;

    // creat JSON message for Socket.IO (event)
    DynamicJsonDocument doc(1024);
    JsonArray array = doc.to<JsonArray>();

    // add event name
    array.add("message");

    // add payload (parameters) for the event
    JsonObject param1 = array.createNestedObject();
    param1["now"] = (uint32_t)now;

    // JSON to String (serializion)
    String output;
    serializeJson(doc, output);

    // Send event
    socketIO.sendEVENT(output);

    // Print JSON for debugging
    Serial.println(output);
  }
}

@per1234 per1234 added the type: imperfection Perceived defect in any part of project label Jul 17, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: imperfection Perceived defect in any part of project
Projects
None yet
Development

No branches or pull requests

2 participants