2012-01-17 3 views
2

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

Публикация вопроса: Websocket server: onopen function on the web socket is never called.

Клиент - это 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; 

Sample Client Рукопожатие

[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=" 

Любая помощь будет большим. Благодарю.

ответ

2

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

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

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

+0

Спасибо за ответ. – Joy

+0

Вот что мне нужно. Environment.NewLine - «\ r \ n», но у меня был только один в самом конце сообщения. Я добавил второй, и мой клиент теперь получает сообщение с сервера. Я отправлю сообщение, если у меня возникнут проблемы с протоколом WebSocket. Еще раз спасибо! – Joy