web socket client issue.
Posted: Mon Jan 16, 2023 11:11 am
The web socket client example didn't work with web socket server (https://www.piesocket.com/websocket-tester) until we sent header and data at once.
Please see the the current sdk5.0 implementation and our changes below:
Please see the the current sdk5.0 implementation and our changes below:
- //////////////////////////////////////////////
- // current SDK code
- //////////////////////////////////////////////
- static int _ws_write(esp_transport_handle_t t, int opcode, int mask_flag, const char *b, int len, int timeout_ms)
- {
- transport_ws_t *ws = esp_transport_get_context_data(t);
- char *buffer = (char *)b;
- char ws_header[MAX_WEBSOCKET_HEADER_SIZE];
- char *mask;
- int header_len = 0, i;
- int poll_write;
- if ((poll_write = esp_transport_poll_write(ws->parent, timeout_ms)) <= 0) {
- ESP_LOGE(TAG, "Error transport_poll_write");
- return poll_write;
- }
- ws_header[header_len++] = opcode;
- if (len <= 125) {
- ws_header[header_len++] = (uint8_t)(len | mask_flag);
- } else if (len < 65536) {
- ws_header[header_len++] = WS_SIZE16 | mask_flag;
- ws_header[header_len++] = (uint8_t)(len >> 8);
- ws_header[header_len++] = (uint8_t)(len & 0xFF);
- } else {
- ws_header[header_len++] = WS_SIZE64 | mask_flag;
- /* Support maximum 4 bytes length */
- ws_header[header_len++] = 0; //(uint8_t)((len >> 56) & 0xFF);
- ws_header[header_len++] = 0; //(uint8_t)((len >> 48) & 0xFF);
- ws_header[header_len++] = 0; //(uint8_t)((len >> 40) & 0xFF);
- ws_header[header_len++] = 0; //(uint8_t)((len >> 32) & 0xFF);
- ws_header[header_len++] = (uint8_t)((len >> 24) & 0xFF);
- ws_header[header_len++] = (uint8_t)((len >> 16) & 0xFF);
- ws_header[header_len++] = (uint8_t)((len >> 8) & 0xFF);
- ws_header[header_len++] = (uint8_t)((len >> 0) & 0xFF);
- }
- if (mask_flag) {
- mask = &ws_header[header_len];
- getrandom(ws_header + header_len, 4, 0);
- header_len += 4;
- for (i = 0; i < len; ++i) {
- buffer[i] = (buffer[i] ^ mask[i % 4]);
- }
- }
- if (esp_transport_write(ws->parent, ws_header, header_len, timeout_ms) != header_len) {
- ESP_LOGE(TAG, "Error write header");
- return -1;
- }
- if (len == 0) {
- return 0;
- }
- int ret = esp_transport_write(ws->parent, buffer, len, timeout_ms);
- // in case of masked transport we have to revert back to the original data, as ws layer
- // does not create its own copy of data to be sent
- if (mask_flag) {
- mask = &ws_header[header_len-4];
- for (i = 0; i < len; ++i) {
- buffer[i] = (buffer[i] ^ mask[i % 4]);
- }
- }
- return ret;
- }
- //////////////////////////////////////////////
- // changed code
- //////////////////////////////////////////////
- static int _ws_write(esp_transport_handle_t t, int opcode, int mask_flag, const char *b, int len, int timeout_ms)
- {
- transport_ws_t *ws = esp_transport_get_context_data(t);
- int header_len = 0, i;
- int poll_write;
- char *pData, *pMask = NULL;
- char* pBuffer = malloc(len+10); // allocation buffer with length of data plus maximal header length
- if(pBuffer == NULL) {
- ESP_LOGE(TAG, "Websocket transport: Failed to malloc buffer to sending...");
- return 0;
- }
- if ((poll_write = esp_transport_poll_write(ws->parent, timeout_ms)) <= 0) {
- ESP_LOGE(TAG, "Error transport_poll_write");
- return poll_write;
- }
- pBuffer[header_len++] = opcode;
- if (len <= 125) {
- pBuffer[header_len++] = (uint8_t)(len | mask_flag);
- } else if (len < 65536) {
- pBuffer[header_len++] = WS_SIZE16 | mask_flag;
- pBuffer[header_len++] = (uint8_t)(len >> 8);
- pBuffer[header_len++] = (uint8_t)(len & 0xFF);
- } else {
- pBuffer[header_len++] = WS_SIZE64 | mask_flag;
- /* Support maximum 4 bytes length */
- pBuffer[header_len++] = 0; //(uint8_t)((len >> 56) & 0xFF);
- pBuffer[header_len++] = 0; //(uint8_t)((len >> 48) & 0xFF);
- pBuffer[header_len++] = 0; //(uint8_t)((len >> 40) & 0xFF);
- pBuffer[header_len++] = 0; //(uint8_t)((len >> 32) & 0xFF);
- pBuffer[header_len++] = (uint8_t)((len >> 24) & 0xFF);
- pBuffer[header_len++] = (uint8_t)((len >> 16) & 0xFF);
- pBuffer[header_len++] = (uint8_t)((len >> 8) & 0xFF);
- pBuffer[header_len++] = (uint8_t)((len >> 0) & 0xFF);
- }
- if (mask_flag) {
- pMask = &pBuffer[header_len];
- getrandom(pMask, 4, 0);
- header_len += 4;
- }
- pData = &pBuffer[header_len];
- memcpy(pData, b, len);
- if (mask_flag) {
- for (i = 0; i < len; ++i) {
- pData[i] = (pData[i] ^ pMask[i % 4]);
- }
- }
- int ret = esp_transport_write(ws->parent, pBuffer, header_len+len, timeout_ms);
- free(pBuffer);
- return ret;
- }