2010-11-17 2 views
4

Я пытался написать фрагмент кода для открытия веб-сокета.Не удается открыть веб-сокет

var ws = null; 


var close = function() { 
if (ws) { 
    console.log('closing ...'); 
    ws.close(); 
} 
} 

var onOpen = function() { 
console.log('opening...'); 
ws.send('hello. im connected'); 
}; 

var onClose = function() { 
    console.log('closed'); 
}; 

var onMessage = function(event) { 
var data = event.data; 
console.log('message: ' + data); 
}; 

close(); 

var url = 'ws://localhost:9999'; 
ws = new WebSocket(url); 
ws.onopen = onOpen; 
ws.onclose = onClose; 
ws.onmessage = onMessage; 

console.log('ws: ' + ws); 


if (ws) 
{ 
console.log('url:' + ws.url); 
console.log('readyState:' + ws.readyState); 
ws.send(msg); 
} 
else 
alert('no ws'); 

Но, увидев консоль, то readyState было продолжать быть «СОЕДИНЕНИЕ», который вызывает команду метания исключения сокета().

Я попробовал расширение https://chrome.google.com/extensions/detail/pfdhoblngboilpfeibdedpjgfnlcodoo и получил ту же проблему. Сервер довольно прост, который принимает входящий сокет и выписывает его на консоль.

Там начальный дрожание рук, но readyState клиента до сих пор хранится равным 0.

Вот рука встряхивания:

GET/HTTP/1.1 
Upgrade: WebSocket 
Connection: Upgrade 
Host: localhost:9999 
Origin: http://localhost:8080 
Sec-WebSocket-Key1: Qb 15 05 6 Gq 9 26 u0 6 
Sec-WebSocket-Key2: 8096 C0587|7. 

У меня есть что-то конкретное на сервере, чтобы позволить быть открыт клиент?

Спасибо, ребята.

+0

Вы разбираете рукопожатие на стороне сервера и отправляете хэш из двух ключей? –

+0

Вы чувствуете, что ваш вопрос был достаточно отвечен? (если так вы можете выбрать ответ). Если нет, мы можем помочь вам решить ваш вопрос? – kanaka

ответ

1

Ваш блок, показывающий рукопожатие, является неполным. Должна быть пустая строка, за которой следует 8 байтов дополнительных данных (или key3).

Сервер должен построить обратное рукопожатие, который будет выглядеть примерно так:

HTTP/1.1 101 Web Socket Protocol Handshake\r 
Upgrade: WebSocket\r 
Connection: Upgrade\r 
Sec-WebSocket-Origin: http://localhost:8080\r 
Sec-WebSocket-Location: ws://localhost:9999/\r 
Sec-WebSocket-Protocol: sample\r 
\r 
[16 byte md5 hash] 

16 байт хэш, что сервер возвращает рассчитываются следующим образом:

  • взять числа из key1 и преобразовать их в число. Разделите это число на количество пробелов данных key1. Это дает вам 4-байтовый ключ1.

  • сделать то же самое с данными ключа2, чтобы получить номер ключа2.

  • создать массив из 16 байтов, упаковок в число key1 (4 байта), за которым следует номер ключа2 (4 байта), за которым следует 8 байтов дополнительных данных, полученных от клиента (8 байтов).

  • md5 суммировать массив по 16 байт, чтобы получить новый массив по 16 байт. Это то, что написано клиенту для завершения ответа на рукопожатие.

До тех пор, пока сервер не вернет рукопожатие, клиент покажет «ПОДКЛЮЧЕНИЕ».

Ответ сервера рукопожатия описан более подробно в разделе 5.2 Обновление с WebSockets version 76 standards document

на основе второго вопроса (в разделе ответов):

Если все, что вы пытаетесь сделать, это отправить данные из расширения, то вы можете рассмотреть просто использование запроса POST XMLHttpRequest (AJAX). Поскольку вы получаете что-либо от запроса, я подозреваю, что латентность не так важна для вашего приложения. XMLHttpRequest должен легко поддерживать расширения как для Firefox, так и для Chrome.

С другой стороны, если задержка важна или если ваш сервер, на котором отправляются данные, является исключительно сервером сокета, добавление поддержки WebSockets не будет намного сложнее, чем добавление поддержки HTTP (на самом деле, возможно, Полегче).Поддержка WebSockets также должна поддерживать расширения как в Chrome, так и в firefox (4.0 и далее).

0

Спасибо.

Я не знал, что это 2 способа связи.

Я кодировал расширение Chrome, которое открывает сокет и отправляет данные в конкретное приложение. Я сделал это с FF, используя нижнюю розетку:

var transportService = Components.classes["@mozilla.org/network/socket-transport-service;1"].getService(Components.interfaces.nsISocketTransportService); 
var transport = transportService.createTransport(null,0,"localhost",9999,null); 

Есть ли способ, который использует аналогичный подход в Chrome? или я должен использовать WebSocket с двумя способами общения? Я не хочу, чтобы это было сложно, поскольку мне нужно изменить приложение-получатель, чтобы вернуть рукопожатие.

Спасибо.

Смежные вопросы