Web Socket Server v13 RFC 6455 Клиент не получает сообщения - PullRequest
2 голосов
/ 18 января 2012

У меня тот же вопрос, который был задан в другом посте, за исключением того, что у меня проблема в версии 13 (RFS 6455). Кому-нибудь удалось реализовать сервер веб-сокетов с использованием этой версии? Я перепробовал все другие предложения, которые смог найти, но ни одно из них не сработало.

Похожие сообщения: Сервер веб-сокетов: функция onopen на веб-сокете никогда не вызывается .

Клиент - это JavaScript на Chrome 16. Сервер является консольным приложением C #.

Мой сервер может получить клиентское рукопожатие и успешно отправить ответ, но событие onopen / onmessage не запускается на клиенте.

Кажется, проблема для большинства людей в Интернете связана с самим сообщением о рукопожатии, но все примеры, которые я могу найти, относятся к версии -75 или -76.

Я следую инструкциям здесь: http://tools.ietf.org/html/rfc6455#page-39

Здесь я инициализирую ответ от моего рукопожатия.

handshake = "HTTP/1.1 101 Switching Protocols" + Environment.NewLine;
handshake += "Upgrade: websocket" + Environment.NewLine;
handshake += "Connection: Upgrade" + Environment.NewLine;
handshake += "Sec-WebSocket-Accept: ";

Здесь я получаю сообщение о рукопожатии клиента, генерирую ключ ответа и отправляю его обратно.

System.Text.ASCIIEncoding decoder = new System.Text.ASCIIEncoding();
string clientHandshake = decoder.GetString(receivedDataBuffer, 0, receivedDataBuffer.Length);
string[] clientHandshakeLines = clientHandshake.Split(new string[] { Environment.NewLine }, System.StringSplitOptions.RemoveEmptyEntries);

foreach (string line in clientHandshakeLines)
{
    if (line.Contains("Sec-WebSocket-Key:"))
    {
        handshake += ComputeWebSocketHandshakeSecurityHash09(line.Substring(line.IndexOf(":") + 2));
        handshake += Environment.NewLine;     
    }
}

byte[] handshakeText = Encoding.ASCII.GetBytes(handshake);
byte[] serverHandshakeResponse = new byte[handshakeText.Length];
Array.Copy(handshakeText, serverHandshakeResponse, handshakeText.Length);

ConnectionSocket.BeginSend(serverHandshakeResponse, 0, serverHandshakeResponse.Length, 0, HandshakeFinished, null);

Код на стороне клиента выглядит следующим образом.

ws = new WebSocket("ws://localhost:8181/test")
ws.onopen = WSonOpen;
ws.onmessage = WSonMessage;
ws.onclose = WSonClose;
ws.onerror = WSonError;

Пример клиентского рукопожатия

[0]: "GET /test HTTP/1.1"
[1]: "Upgrade: websocket"
[2]: "Connection: Upgrade"
[3]: "Host: localhost:8181"
[4]: "Origin: http://localhost:8080"
[5]: "Sec-WebSocket-Key: jKZrBlUEqqqstB+7wPES4A=="
[6]: "Sec-WebSocket-Version: 13"

Пример ответа сервера

[0]: "HTTP/1.1 101 Switching Protocols"
[1]: "Upgrade: websocket"
[2]: "Connection: Upgrade"
[3]: "Sec-WebSocket-Accept: mL2V6Yd+HNUHEKfUN6tf9s8EXjU="

Любая помощь будет отличной. Спасибо.

1 Ответ

2 голосов
/ 18 января 2012

Одна вещь, которую вы не опубликовали - это то, что Environment.NewLine и HandshakeFinished равны.

Заголовки должны соответствовать RFC 2616. Другими словами, каждая строка заголовка должна заканчиваться CR + LF (возврат каретки).+ перевод строки или ASCII-символ 13, за которым следует ASCII-символ 10).За последним заголовком должен следовать дополнительный CR + LF в дополнение к заголовку, указывающему конец строки заголовка.

Кроме того, хотя это еще не вызывает проблем, потому что код вашего клиента его не устанавливает,Вам также не хватает логики для обработки выбора суб-протокола.Если клиент отправляет заголовок Sec-WebSocket-Protocol, вы должны выбрать один из подпротоколов и вернуть его в заголовке ответа Sec-WebSocket-Protocol.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...