使用 Arduino WiFiClient / WiFiClientSecure 处理 Websocket(客户端)传入帧

问题描述 投票:0回答:1

我开始为 Arduino 编写一个 websocket 库。 目前它已经工作了一半。我创建了一个 node.js websocket 服务器,在其中测试客户端。 我的问题出在数据处理部分,它将垃圾打印到串行,我不知道为什么。 连接和文本发送部分工作正常,服务器正常接收文本数据。但是当服务器发送一些文本数据时,我得到的只是垃圾。可能是处理函数中的屏蔽或其他逻辑出了问题。

这是

processData()
processCompleteFrame()
函数。

void HsHSocketClient::processData() {
    static uint8_t fragmentedOpcode;
    static String fragmentedPayload;

    while (client.available()) {
        uint8_t opcode = client.read();
        bool fin = (opcode & 0x80) != 0;
        opcode &= 0x0F;
        uint8_t payloadLen = client.read() & 0x7F;

        if (payloadLen == 126) {
            payloadLen = (client.read() << 8) | client.read();
            payloadLen -= 2;  // Subtract 2 to account for the two additional bytes read for length
        } else if (payloadLen == 127) {
            payloadLen = (client.read() << 24) | (client.read() << 16) | (client.read() << 8) | client.read();
            payloadLen -= 8;  // Subtract 8 to account for the eight additional bytes read for length
        }

        uint8_t maskingKey[4];
        client.readBytes(maskingKey, 4);

        Serial.print("[Ws] - Masking Key: ");
        for (size_t i = 0; i < 4; ++i) {
            Serial.print(maskingKey[i], HEX);
            Serial.print(" ");
        }
        Serial.println();

        uint8_t payload[payloadLen];
        client.readBytes(payload, payloadLen);
        for (size_t i = 0; i < payloadLen; ++i) {
            payload[i] ^= maskingKey[i % 4];
        }

        Serial.print("[Ws] - Unmasked Payload: ");
        for (size_t i = 0; i < payloadLen; ++i) {
            Serial.print(payload[i], HEX);
            Serial.print(" ");
        }
        Serial.println();

        if (fin) {
            if (fragmentedPayload.length() > 0) {
                fragmentedPayload += String(payload, payloadLen);
                processCompleteFrame(fragmentedOpcode, fragmentedPayload.c_str(),payloadLen);
                fragmentedPayload = "";
            } else {
                processCompleteFrame(opcode, reinterpret_cast<const char*>(payload),payloadLen);
            }
        } else {
            fragmentedOpcode = opcode;
            fragmentedPayload += String(payload, payloadLen);
        }
    }
}

void HsHSocketClient::processCompleteFrame(uint8_t opcode, const char* payload, size_t payloadLen) {
    Serial.print("[Ws] - Received frame, Opcode: 0x");
    Serial.println(opcode, HEX);

    Serial.print("[Ws] - Payload Hex: ");
    for (size_t i = 0; i < payloadLen; ++i) {
        Serial.print(payload[i], HEX);
        Serial.print(" ");
    }
    Serial.println();

    if (opcode == 0x1) {  // Text frame
        Serial.print("[Ws] - Received text frame: ");
        Serial.println(payload);
    }else if (opcode == 0x2) {  // Binary frame
        Serial.print("[Ws] - Received binary frame: ");
        Serial.println(payload);
    } else if (opcode == 0x8) {  // Close frame
        Serial.print("[Ws] - Received close frame: ");
        Serial.println(payload);
        sendCloseFrame();
        client.stop();
    } else if (opcode == 0x9) {  // Ping frame
        Serial.print("[Ws] - Received ping frame: ");
        Serial.println(payload);
    } else if (opcode == 0xA) {  // Pong frame
        Serial.print("[Ws] - Received pong frame: ");
        Serial.println(payload);
    } else {
        Serial.print("[Ws] - Received unknown frame: ");
        Serial.println(payload);
    }
}

node.js ws 服务器代码,没什么花哨的

wss.on('connection', function(ws) {
    console.log("Client connected!");

    ws.on('error', console.error);
  
    ws.on('message', function(data) {
        let msg;
        try {
            msg = JSON.parse(data);
        } catch (error) {
            msg = data;
        }
      console.log('received: %s', msg);
    });

    ws.on("close", function() {
        console.log("Client disconnected!");
    });
  
    setInterval(() => {
        ws.send('Test message');
    }, 5000);
});

我在序列中得到的数据:

[Ws] - Connecting to server: 192.168.10.104:80
[Ws] - Connected to server
[Ws] - Masking Key: 54 50 2F 31 
[Ws] - Unmasked Payload: 7A 61 F 0 64 61 F 62 23 39 5B 52 3C 39 41 56 74 0 5D 5E 20 3F 4C 5E 38 23 22 3B 1 20 48 43 35 34 4A B 74 27 4A 53 27 3F 4C 5A 31 
24 22 3B 17 3F 41 5F 31 33 5B 58 3B 3E 15 11 1 20 48 43 35 34 4A 3C 5E 3 4A 52 79 7 4A 53 7 3F 4C 5A 31 24 2 70 
[Ws] - Masking Key: 65 70 74 3A 
[Ws] - Unmasked Payload: 45 34 4D E 33 3B 3D 59 3C 14 23 77 57 40 43 5D 1 22 
3B 6D 1 35 46 6B 6 22 3F 63 58 7D 7E 37 6F 5B 66 BA B5 39 8F 5 C9 1 88 5 A1 B8 37 5 75 70 74 3A 64 70 74 3A 6E 71 74 3A ED CC F4 5 FF 5D 66 BA 95 39 8F 5 
51 2C 88 5 6 70 74 3A 75 70 74 3A F1 2C 88 5 64 70 74 3A 45 73 8F 5 1B C1 60 
[Ws] - Masking Key: 54 65 73 74 
[Ws] - Unmasked Payload: 74 8 16 7 27 4 14 11 60 39 8F 4B 
[Ws] - Received frame, Opcode: 0x3
[Ws] - Payload Hex: 7A 61 F 0 64 61 F 62 23 39 5B 52
[Ws] - Received unknown frame: za
[Ws] - Masking Key: 54 65 73 74 
[Ws] - Unmasked Payload: 74 8 16 7 27 4 14 11 60 39 8F 4B 
[Ws] - Received frame, Opcode: 0x1
[Ws] - Payload Hex: 74 8 16 7 27 4 14 11 60 39 8F 4B 
[Ws] - Received text frame: '`9�K
[Ws] - Masking Key: 54 65 73 74 
[Ws] - Unmasked Payload: 74 8 16 7 27 4 14 11 60 39 8F 4B 
[Ws] - Received frame, Opcode: 0x1
[Ws] - Payload Hex: 74 8 16 7 27 4 14 11 60 39 8F 4B
[Ws] - Received text frame: '`9�K
c++ websocket client arduino-esp32
1个回答
0
投票

事实证明我不需要做任何遮蔽

void HsHSocketClient::processData() {
    static uint8_t fragmentedOpcode;
    static uint8_t fragmentedPayload[1024];
    static size_t fragmentedPayloadLen = 0;

    while (client.available()) {
        uint8_t opcode = client.read();
        bool fin = (opcode & 0x80) != 0;
        opcode &= 0x0F;
        uint8_t payloadLen = client.read() & 0x7F;

        if (payloadLen == 126) {
            payloadLen = (client.read() << 8) | client.read();
            payloadLen -= 2;
        } else if (payloadLen == 127) {
            payloadLen = (client.read() << 24) | (client.read() << 16) | (client.read() << 8) | client.read();
            payloadLen -= 8;
        }

        uint8_t payload[payloadLen];
        client.readBytes(payload, payloadLen);

        if (fin) {
            if (fragmentedPayloadLen > 0) {
                processCompleteFrame(fragmentedOpcode, (char*)fragmentedPayload, fragmentedPayloadLen);
                fragmentedPayloadLen = 0;
            } else {
                processCompleteFrame(opcode, (char*)payload, payloadLen);
            }
        } else {
            fragmentedOpcode = opcode;
            fragmentedPayloadLen = payloadLen;
            memcpy(fragmentedPayload, payload, payloadLen);
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.