更新 几乎在那里我可以收到我想的消息。当代码可读时,我会把它放进去。也试着发送..
原始问题
我正在尝试将我的esp8266(@ 38400波特)($ 3.50 wifi芯片:))连接到Websocket。该芯片与Arduino pro mini连接。这个设置没问题就可以了。
由于一些代码(https://github.com/ejeklint/ArduinoWebsocketServer),我能够握手。
这就是程序必须要做的事情:
我正在测试websocket: http://www.websocket.org/echo.html
连接我的wifi模块 WS://192.168.1.104:8000
当我向我的Arduino发送3 x消息“aaaa”时,我收到了:
+ IPD,0,10:| | | q | | b | k | | c | | |
+ IPD,0,10:| | | | | ¡| 0 | P | Ç| À|问| 1 |
+ IPD,0,10:| | | _ | ò| ±| ? | > | | Ð| ^ | |
我该如何解码?
#include "sha1.h"
#include "Base64.h"
#include <SoftwareSerial.h>
#include <MemoryFree.h>
SoftwareSerial debug(8, 9); // RX, TX
void setup() {
Serial.begin(38400);
debug.begin(38400);
delay(50);
debug.println("start");
Serial.println("AT+RST");
delay(5000);
Serial.println("AT+CWMODE=1"); // NO CHANGE
delay(1500);
Serial.find("OK");
Serial.println("AT+CIPMUX=1");
Serial.find("OK");
delay(3000);
Serial.println("AT+CIPSERVER=1,8000");
boolean server = Serial.find("OK");
delay(3000);
Serial.println("AT+CIFSR"); // Display the ip please
boolean r = readLines(4);
debug.println("eind setup");
debug.println(server);
boolean found = false;
while(!found) // wait for the link
found = Serial.find("Link");
debug.println("link builded, end setup");
}
void loop() {
String key = "";
boolean isKey = Serial.find("Key: ");
if(isKey) {
debug.println("Key found!");
while(true) {
if(Serial.available()) {
char c = (char)Serial.read();
if(c == '=') {
doHandshake(key + "==");
key = "";
break;
}
if(c != '\r' || c != '\n') {
key = key + c;
}
}
}
// _________________________ PROBLEMO ____________________________________
while(true) { // So far so good. Handshake done Now wait for the message
if(Serial.available()) {
char c = (char)Serial.read();
debug.print(c);
debug.print(" | ");
}
}
}
// _________________________ /PROBLEMO ____________________________________
}
boolean readLines(int lines) {
boolean found = false;
int count = 0;
while(count < lines) {
if(Serial.available()) {
char c = (char)Serial.read();
if(c != '\r') {
debug.write(c);
} else {
count++;
}
}
}
return true;
}
bool doHandshake(String k) {
debug.println("do handshake: " + k);
char bite;
char temp[128];
char key[80];
memset(temp, '\0', sizeof(temp));
memset(key, '\0', sizeof(key));
byte counter = 0;
int myCo = 0;
while ((bite = k.charAt(myCo++)) != 0) {
key[counter++] = bite;
}
strcat(key, "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"); // Add the omni-valid GUID
Sha1.init();
Sha1.print(key);
uint8_t *hash = Sha1.result();
base64_encode(temp, (char*)hash, 20);
debug.print(temp);
int cc = -1;
while(temp[cc++] != '\0') {} // cc is length return key
cc = 165 + cc; // length return key + 165 keys for rest of header
Serial.print("AT+CIPSEND=0,");
Serial.println(129); // +30 // was 129
boolean found = false;
while(!found)
found = Serial.find(">"); // Wait until I can send
Serial.print("HTTP/1.1 101 Switching Protocols\r\n");
Serial.print("Upgrade: websocket\r\n");
Serial.print("Connection: Upgrade\r\n");
Serial.print("Sec-WebSocket-Accept: ");
Serial.print(temp);
Serial.print("\r\n\r\n");
return true;
}
答案 0 :(得分:1)
我没有使用websockets的经验,但我认为websockets使用UTF-8而Arduino终端使用ASCII。我没有在UTF-8和ASCII之间的代码转换中看到。
答案 1 :(得分:0)
我现在可以从websocket发送消息&gt;&gt; Arduino的。但发送不起作用:(。
boolean getFrame() {
debug.println("getFrame()");
byte bite;
unsigned short payloadLength = 0;
bite = Serial.read();
frame.opcode = bite & 0xf; // Opcode
frame.isFinal = bite & 0x80; // Final frame?
bite = Serial.read();
frame.length = bite & 0x7f; // Length of payload
frame.isMasked = bite & 0x80;
// Frame complete!
if (!frame.isFinal) {
return false;
}
// First check if the frame size is within our limits.
if (frame.length > 126) {
return false;
}
// If the length part of the header is 126, it means it contains an extended length field.
// Next two bytes contain the actual payload size, so we need to get the "true" length.
if (frame.length == 126) {
byte exLengthByte1 = Serial.read();
byte exLengthByte2 = Serial.read();
payloadLength = (exLengthByte1 << 8) + exLengthByte2;
}
// If frame length is less than 126, that is the size of the payload.
else {
payloadLength = frame.length;
}
// Check if our buffer can store the payload.
if (payloadLength > MAX_RECEIVE_MESSAGE_SIZE) {
debug.println("te groot");
return false;
}
// Client should always send mask, but check just to be sure
if (frame.isMasked) {
frame.mask[0] = Serial.read();
frame.mask[1] = Serial.read();
frame.mask[2] = Serial.read();
frame.mask[3] = Serial.read();
}
// Get message bytes and unmask them if necessary
for (int i = 0; i < payloadLength; i++) {
if (frame.isMasked) {
frame.data[i] = Serial.read() ^ frame.mask[i % 4];
} else {
frame.data[i] = Serial.read();
}
}
for (int i = 0; i < payloadLength; i++) {
debug.print(frame.data[i]);
if(frame.data[i] == '/r')
break;
}
return true;
}
// !!!!!!!!!! NOT WORKING
boolean sendMessage(char *data, byte length) {
Serial.print((uint8_t) 0x1); // Txt frame opcode
Serial.print((uint8_t) length); // Length of data
for (int i = 0; i < length ; i++) {
Serial.print(data[i]);
}
delay(1);
return true;
}
请参阅https://github.com/zoutepopcorn/esp8266-Websocket/blob/master/arduino_websocket.ino
现在唯一的问题是来自arduino的websocket格式&gt; websocket不行:(。但我认为这是另一个问题/问题。 WebSocket连接到&#39; ws://192.168.1.101:8000 /?encoding = text&#39;失败:一个或多个保留位开启:reserved1 = 0,reserved2 = 1,reserved3 = 1
答案 2 :(得分:0)
您正在查看的是第一个与HTTP标头连接的Web Socket框架(| | | q | | b | k | | c | | |)。 (+ IPD,0,10 :)用管道(|)分隔的数据是无法理解的,因为它不是ASCII,也不是UTF8。您必须在最后一个冒号(:)之后显示数据作为BINARY。那应该是完全合理的。我做的完全一样。只有当我将总数据显示为二进制时,我才“得到它”。 我正在使用网络上的“Web Sockets rock”演示。这是一个回声,只是将“Web套接字摇滚”发送到您指定的服务器。我将服务器地址更改为I.P.我的ESP8266并开始看框架。 我为自己做了一些分析(和你一样),看看ESP8266在成功握手后会发回什么。 (我先握手握手) 这是TeraTerm直接列出的“后握手” -
+IPD,0,21:r¨$v%ÍF%ËVÃW (NOTE: Garbage after the :)
我希望在那里找到“Web Sockets rock”。
这是转换为Binary的列表,我从接收缓冲区中提取 -
0 2B 0010 1011
1 49 0100 1001
2 50 0101 0000
3 44 0100 0100
4 2C 0010 1100
5 30 0011 0000
6 2C 0010 1100
7 32 0011 0010 (Ascii for 21 bytes to follow)
8 31 0011 0001 (Ascii for 21 bytes to follow)
9 3A 0011 1010 (Colon)
10 -7F 1000 0001 (Start of actual FRAME)
11 -71 1000 1111
12 72 0111 0010
13 -58 1010 1000
14 24 0010 0100
15 76 0111 0110
16 25 0010 0101
17 -33 1100 1101
18 46 0100 0110
19 25 0010 0101
20 1D 0001 1101
21 -35 1100 1011
22 4F 0100 1111
23 13 0001 0011
24 6 0000 0110
25 -78 1000 1000
26 56 0101 0110
27 19 0001 1001
28 11 0001 0001
29 -3D 1100 0011
30 57 0101 0111
字段描述 - (从结肠81后的第一个字节开始)
// First byte has FIN bit and frame type opcode = text
// Second byte mask and payload length
// next four bytes for masking key
// So total of 6 bytes for the overhead
// The size of the payload in this case is "F" = 15 (the 4th nibble)
// So total of bytes are (6+15) = 21
// The first byte is saying> FIN bit is set. This is last frame in sequence. The OP code is 1 = TEXT data.
// The second byte is saying> MASK bit is set. The following data will be masked. The data length is "F" = 15
// The 3rd, 4th, 5th, 6th bytes is the masking key. In this case 72, A8, 24, 76.