Search code examples
pythonwebsocketarduinoclientesp8266

Arduino Client connects to server through websocketsocket but can't communicate with it


I have this client running on a esp8266 wifi board, here's the code:

#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>

ESP8266WiFiMulti WiFiMulti;
String line="";

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

    // We start by connecting to a WiFi network
    WiFiMulti.addAP("MYSSID", "MYPASSWORD");

    Serial.println();
    Serial.println();
    Serial.print("Wait for WiFi... ");

    while(WiFiMulti.run() != WL_CONNECTED) {
        Serial.print(".");
        delay(500);
    }

    Serial.println("");
    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());

    delay(500);
}

void loop() {
    const uint16_t port = 5021;
    const char * host = "192.168.x.yyy";
    
    Serial.print("connecting to ");
    Serial.println(host);

    // Use WiFiClient class to create TCP connections
    WiFiClient client;

    if (!client.connect(host, port)) {
        Serial.println("connection failed");
        delay(1000);
        return;
    }

  // This will send the request to the server
  Serial.println("Connected!!!!!");
  const char * frame = "009TEMSDS&000001001023";
  client.print(frame);
               
  delay(1000);

   while(client.available()){
    String line = client.readStringUntil('\r');
    Serial.print(line);
  }

  //Serial.println(line);
    Serial.println("closing connection");
    client.stop();
    
    delay(1000);
}

I want it to connect to a python websocket server on my computer:

#!/usr/bin/env python

import asyncio
import websockets
import threading

framesReceive = []

async def receiver(websocket, path):
    framesReceive = (await websocket.recv())
    print(framesReceive)
    # dictFrame = frameBreakdown(framesReceive)

    await websocket.send("pong")

# Socket Server thread
def ThreadServer():
    asyncio.set_event_loop(asyncio.new_event_loop())
    start_server = websockets.serve(receiver, "192.168.x.yyy", 5021)
    asyncio.get_event_loop().run_until_complete(start_server)
    asyncio.get_event_loop().run_forever()

threadServer = threading.Thread(target=ThreadServer, args=())
threadServer.start()

In a nutshell the message "009TEMSDS&000001001023" is not being sent, and the response "pong" is not being received.

Even if a connection is in fact being established(image)

and when i try to send the same message from a client within my computer it works as expected(image)

Am i missing something? Why is the client's message not being recieved?


Solution

  • The ESP8266 code you shared is not using a websockets client. It's using a raw TCP connection. WiFiClient just opens a TCP connection to a server; it provides neither HTTP nor websockets over that connection. You'll need another library that uses WiFiClient to do this.

    If you want to use websockets to communicate with your Python code you'll need to use a websocket client on the ESP8266. I have to wonder, why? Websockets are mostly used to get around limitations of web browsers - you do not need to use websockets for an ESP8266 to communicate with a Python script on the same network. The more common use case for websockets would be for Javascript running in a browser to communicate with a websocket server.

    There are a few different ESP8266 websocket client libraries out there; use Google to find one that is still supported and suits your needs. It's possible that this library might work for you.

    I would recommend that you simply rewrite your Python server to use accept a raw TCP connection and not worry about using websockets in this case.