Connect Websocket client to Socket.IO server
TannerGilbert opened this issue · 1 comments
TannerGilbert commented
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 commented
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);
}
}