Closed elastra21 closed 2 years ago
Arduino IDE Version: 2.0.0-rc6
Try using Arduino IDE v1.8.19, not the beta-and-buggy v2.0.0-rcx
Its was OK here WebSocketClientSocketIO_WiFi on Portenta_H7 using WiFi
FYI, just tested using Arduino IDE v1.8.19 and still OK now.
Start WebSocketClientSocketIO_WiFi on PORTENTA_H7_M7
WebSockets_Generic v2.15.0
Connecting to SSID: HueNet1
SSID: HueNet1
WebSockets Client IP Address: 192.168.2.119
signal strength (RSSI):-29 dBm
Connecting to WebSockets Server @ IP address: 192.168.2.30, port: 8080
[WS] [WS-Client][connectedCb] Connected to Host:192.168.2.30, Port:8080
[WS] [wsIOc] Connected to url:/socket.io/?EIO=4
[IOc] Connected to url: /socket.io/?EIO=4
[WS] [wsIOc] get pong
[IOc] Get PONG
[WS] [wsIOc] connected: len = 30
[WS] [wsIOc] data: {"sid":"dqs_yYqGre5KIQ1QAAAB"}
["event_name",{"now":30001}]
[WS] [wsIOc] get event: len = 53
[WS] [wsIOc] get data: ["Send Message io.emit Broadcasted : ",{"now":30001}]
[IOc] Get event: ["Send Message io.emit Broadcasted : ",{"now":30001}]
[WS] [wsIOc] get event: len = 33
[WS] [wsIOc] get data: ["Send Message : ",{"now":30001}]
[IOc] Get event: ["Send Message : ",{"now":30001}]
[WS] [wsIOc] get ping send pong:3
[IOc] Get PING
Server launched on port 8080
Connected
dqs_yYqGre5KIQ1QAAAB
JWT token test: {
host: '192.168.2.30:8080',
connection: 'keep-alive',
authorization: '1234567890',
'user-agent': 'arduino-WebSocket-Client'
}
Message from Client : { now: 30001 }
Message from Client : { now: 60002 }
Message from Client : { now: 90003 }
Message from Client : { now: 120004 }
Thanks for responding, I tried. with the Arduino v1.8.19 to see if works but no, I'm still getting the same error. I don't know what I'm doing wrong. I downloaded the example Server and tested with ESP32 and ESP8266 without problems but this one it's driving me crazy.
?
It's possible that you haven't applied the patch mentioned in [Portenta_H7] WiFi WebServer extremely slow from core v2.7.2 - v3.0.1 #441
Try to use the fix in Drastically speedup client.read() operation #439 by changing in these 2 files
It's very bad that Arduino is so slow to fix the worst and breaking bugs in the core by releasing a new core version
#include "MbedClient.h"
#ifndef SOCKET_TIMEOUT
#define SOCKET_TIMEOUT 1500
#endif
arduino::MbedClient::MbedClient()
: _status(false),
_timeout(0) {
}
uint8_t arduino::MbedClient::status() {
return _status;
}
void arduino::MbedClient::readSocket() {
while (1) {
event->wait_any(0xFF, 100);
uint8_t data[SOCKET_BUFFER_SIZE];
int ret = NSAPI_ERROR_WOULD_BLOCK;
do {
if (rxBuffer.availableForStore() == 0) {
yield();
continue;
}
mutex->lock();
if (sock == nullptr || (closing && borrowed_socket)) {
goto cleanup;
}
ret = sock->recv(data, rxBuffer.availableForStore());
if (ret < 0 && ret != NSAPI_ERROR_WOULD_BLOCK) {
goto cleanup;
}
if (ret == NSAPI_ERROR_WOULD_BLOCK || ret == 0) {
yield();
mutex->unlock();
continue;
}
for (int i = 0; i < ret; i++) {
rxBuffer.store_char(data[i]);
}
mutex->unlock();
_status = true;
} while (ret == NSAPI_ERROR_WOULD_BLOCK || ret > 0);
}
cleanup:
_status = false;
return;
}
void arduino::MbedClient::getStatus() {
event->set(1);
}
void arduino::MbedClient::setSocket(Socket *_sock) {
sock = _sock;
configureSocket(sock);
}
void arduino::MbedClient::configureSocket(Socket *_s) {
_s->set_timeout(_timeout);
_s->set_blocking(false);
if (event == nullptr) {
event = new rtos::EventFlags;
}
if (mutex == nullptr) {
mutex = new rtos::Mutex;
}
mutex->lock();
if (reader_th == nullptr) {
reader_th = new rtos::Thread(osPriorityNormal - 2);
reader_th->start(mbed::callback(this, &MbedClient::readSocket));
}
mutex->unlock();
_s->sigio(mbed::callback(this, &MbedClient::getStatus));
_status = true;
}
int arduino::MbedClient::connect(SocketAddress socketAddress) {
if (sock && reader_th) {
// trying to reuse a connection, let's call stop() to cleanup the state
char c;
if (sock->recv(&c, 1) < 0) {
stop();
}
}
if (sock == nullptr) {
sock = new TCPSocket();
_own_socket = true;
}
if (sock == nullptr) {
return 0;
}
if (static_cast<TCPSocket *>(sock)->open(getNetwork()) != NSAPI_ERROR_OK) {
return 0;
}
address = socketAddress;
nsapi_error_t returnCode = static_cast<TCPSocket *>(sock)->connect(socketAddress);
int ret = 0;
switch (returnCode) {
case NSAPI_ERROR_IS_CONNECTED:
case NSAPI_ERROR_OK:
{
ret = 1;
break;
}
}
if (ret == 1) {
configureSocket(sock);
_status = true;
} else {
_status = false;
}
return ret;
}
int arduino::MbedClient::connect(IPAddress ip, uint16_t port) {
return connect(SocketHelpers::socketAddressFromIpAddress(ip, port));
}
int arduino::MbedClient::connect(const char *host, uint16_t port) {
SocketAddress socketAddress = SocketAddress();
socketAddress.set_port(port);
getNetwork()->gethostbyname(host, &socketAddress);
return connect(socketAddress);
}
int arduino::MbedClient::connectSSL(SocketAddress socketAddress) {
if (sock == nullptr) {
sock = new TLSSocket();
_own_socket = true;
}
if (sock == nullptr) {
return 0;
}
if (beforeConnect) {
beforeConnect();
}
if (static_cast<TLSSocket *>(sock)->open(getNetwork()) != NSAPI_ERROR_OK) {
return 0;
}
address = socketAddress;
restart_connect:
nsapi_error_t returnCode = static_cast<TLSSocket *>(sock)->connect(socketAddress);
int ret = 0;
switch (returnCode) {
case NSAPI_ERROR_IS_CONNECTED:
case NSAPI_ERROR_OK:
{
ret = 1;
break;
}
case NSAPI_ERROR_IN_PROGRESS:
case NSAPI_ERROR_ALREADY:
{
delay(100);
goto restart_connect;
}
}
if (ret == 1) {
configureSocket(sock);
_status = true;
} else {
_status = false;
}
return ret;
}
int arduino::MbedClient::connectSSL(IPAddress ip, uint16_t port) {
return connectSSL(SocketHelpers::socketAddressFromIpAddress(ip, port));
}
int arduino::MbedClient::connectSSL(const char *host, uint16_t port, bool disableSNI) {
if (!disableSNI) {
if (sock == nullptr) {
sock = new TLSSocket();
_own_socket = true;
}
static_cast<TLSSocket *>(sock)->set_hostname(host);
}
SocketAddress socketAddress = SocketAddress();
socketAddress.set_port(port);
getNetwork()->gethostbyname(host, &socketAddress);
return connectSSL(socketAddress);
}
size_t arduino::MbedClient::write(uint8_t c) {
return write(&c, 1);
}
size_t arduino::MbedClient::write(const uint8_t *buf, size_t size) {
if (sock == nullptr)
return 0;
sock->set_blocking(true);
sock->set_timeout(SOCKET_TIMEOUT);
int ret = NSAPI_ERROR_WOULD_BLOCK;
do {
ret = sock->send(buf, size);
} while ((ret != size && ret == NSAPI_ERROR_WOULD_BLOCK) && connected());
configureSocket(sock);
return size;
}
int arduino::MbedClient::available() {
int ret = rxBuffer.available();
return ret;
}
int arduino::MbedClient::read() {
mutex->lock();
if (!available()) {
mutex->unlock();
return -1;
}
int ret = rxBuffer.read_char();
mutex->unlock();
return ret;
}
int arduino::MbedClient::read(uint8_t *data, size_t len) {
mutex->lock();
int avail = available();
if (!avail) {
mutex->unlock();
return -1;
}
if ((int)len > avail) {
len = avail;
}
for (size_t i = 0; i < len; i++) {
data[i] = rxBuffer.read_char();
}
mutex->unlock();
return len;
}
int arduino::MbedClient::peek() {
return rxBuffer.peek();
}
void arduino::MbedClient::flush() {
}
void arduino::MbedClient::stop() {
if (mutex != nullptr) {
mutex->lock();
}
if (sock != nullptr && borrowed_socket == false) {
if (_own_socket) {
delete sock;
} else {
sock->close();
}
sock = nullptr;
}
closing = true;
if (mutex != nullptr) {
mutex->unlock();
}
if (reader_th != nullptr) {
reader_th->join();
delete reader_th;
reader_th = nullptr;
}
if (event != nullptr) {
delete event;
event = nullptr;
}
if (mutex != nullptr) {
delete mutex;
mutex = nullptr;
}
_status = false;
}
uint8_t arduino::MbedClient::connected() {
return _status;
}
IPAddress arduino::MbedClient::remoteIP() {
return SocketHelpers::ipAddressFromSocketAddress(address);
}
uint16_t arduino::MbedClient::remotePort() {
return 0;
}
void arduino::MbedClient::setTimeout(unsigned long timeout) {
_timeout = timeout;
}
/*
MbedClient.h - Client implementation using mbed Sockets
Copyright (c) 2021 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef MBEDCLIENT_H
#define MBEDCLIENT_H
#include "Arduino.h"
#include "SocketHelpers.h"
#include "api/Print.h"
#include "api/Client.h"
#include "api/IPAddress.h"
#include "TLSSocket.h"
#include "TCPSocket.h"
#include "rtos.h"
#ifndef SOCKET_BUFFER_SIZE
#define SOCKET_BUFFER_SIZE 256
#endif
namespace arduino {
class MbedClient : public arduino::Client {
private:
// Helper for copy constructor and assignment operator
void copyClient(const MbedClient& orig) {
auto _sock = orig.sock;
auto _m = (MbedClient*)&orig;
_m->borrowed_socket = true;
_m->stop();
this->setSocket(_sock);
}
public:
MbedClient();
// Copy constructor, to be used when a Client returned by server.available()
// needs to "survive" event if it goes out of scope
// Sample usage: Client* new_client = new Client(existing_client)
MbedClient(const MbedClient& orig) {
copyClient(orig);
}
MbedClient& operator=(const MbedClient& orig) {
copyClient(orig);
return *this;
}
virtual ~MbedClient() {
stop();
}
uint8_t status();
int connect(SocketAddress socketAddress);
int connect(IPAddress ip, uint16_t port);
int connect(const char* host, uint16_t port);
int connectSSL(SocketAddress socketAddress);
int connectSSL(IPAddress ip, uint16_t port);
int connectSSL(const char* host, uint16_t port, bool disableSNI = false);
size_t write(uint8_t);
size_t write(const uint8_t* buf, size_t size) override;
int available();
int read();
int read(uint8_t* buf, size_t size);
int peek();
void flush();
void stop();
uint8_t connected();
operator bool() {
return sock != nullptr;
}
void setSocket(Socket* _sock);
Socket* getSocket() { return sock; };
void configureSocket(Socket* _s);
IPAddress remoteIP();
uint16_t remotePort();
void setTimeout(unsigned long timeout);
friend class MbedServer;
friend class MbedSSLClient;
friend class MbedSocketClass;
using Print::write;
protected:
virtual NetworkInterface* getNetwork() = 0;
Socket* sock = nullptr;
void onBeforeConnect(mbed::Callback<int(void)> cb) {
beforeConnect = cb;
}
private:
RingBufferN<SOCKET_BUFFER_SIZE> rxBuffer;
bool _status = false;
bool borrowed_socket = false;
bool _own_socket = false;
bool closing = false;
mbed::Callback<int(void)> beforeConnect;
SocketAddress address;
rtos::Thread* reader_th = nullptr;
rtos::EventFlags* event = nullptr;
rtos::Mutex* mutex = nullptr;
unsigned long _timeout;
void readSocket();
void getStatus();
};
}
#endif
Also check the following Arduino Forum thread
Be sure that you're using WiFiWebServer releases v1.8.0
Good news.
It's very bad that Arduino is so slow to fix the worst and breaking bugs in the core by releasing a new core version
The new ArduinoCore-mbed releases v3.1.1 has just been released to fix the issues.
You can use that new release without manually applying the patch yourself.
Thank you verry much for the support, it works with the ArduinoCore-mbed v3.1.1, I didn't tried the the manual patch but the new release work perfect.
And again thank you so much for your time.
Arduino Portenta not connect to SocketIO example
I'm trying to connect a Arduino Portenta as SocketIO client to the SocketIO server example in this repo and it keeps disconnecting. After a few tries a check if the problem was the portenta or the library so I ran the same example with a ESP-32 and a ESP-8266 and both works but when I try with Portenta keep Disconnecting and it's weird becuase in the Server logs never shows a connection but with ESP32 or ESP8266 shows each time that a client is Connected.
Steps to Reproduce
Information
Arduino Portenta
Example