2013-07-08 2 views
3

У меня есть C-приложение, которое производит данные, которые я хочу нажать на веб-сайт, используя сервер-отправленные события.Отправка сервер-отправленных событий через сокет в C

Я реализовал базовый веб-сервер в C, который отправляет Http-заголовок после получения запроса Http, а затем данные через 1 с через сокет.

Я зарегистрировал свой сокет как источник событий, и я передаю правильный HTTP-заголовок (согласно Firebug), но по какой-то причине eventListener не вызывается.

var source = new EventSource('http://192.168.2.113:10001/'); 

source.addEventListener('message', function(e) { 
/* */ 
}, false); 

Я пытался посылать события из приложения PHP и он работал без каких-либо проблем, поэтому думаю, что проблема не на стороне яваскрипта.

Когда я только открываю http://192.168.2.113:10001/ в моем браузере, отображаются строки данных, которые я отправляю с интервалом в 1 секунду.

Я нашел только sse-реализации с использованием php или cgi, которые я не хочу использовать.

Мой ответ заголовок:

HTTP/1.1 200 OK\n 
Date: Fri, 05 Jul 2013 15:05:15 GMT\n 
Cache-Control: no-cache\n 
Connection: Keep-Alive\n 
Transfer-Encoding: chunked\n 
Content-Type: text/event-stream\n 
\n 

Данные события:

data: Testdata...\n\n 
+0

Можете ли вы привести несколько примеров части кода C, как отправлять sse? Мне это очень интересно, и я ищу пример для игры. Благодаря! – Jun

ответ

2

В кодировке chunked каждому фрагменту данных предшествует строка, описывающая размер куска. Вы не показываете, что предоставляете этот размер, поэтому данные вашего события не соответствуют формату кодирования chunked.

Длина указана в шестнадцатеричной форме, поэтому в вашем случае 18 байтов данных будут закодированы как 12 в шестнадцатеричном формате. Когда больше нет кусков (то есть, ответ завершен), то отправляется 0 размерный кусок.

Многие клиенты принимают простой \n как правильный терминатор блока данных, но HTTP RFC указывает, что будет использоваться \r\n. Итак, каждый \n в вашем заголовке должен быть изменен на \r\n. и ваши куски должны выглядеть следующим образом:

12\r\ndata: Testdata...\n\r\n 

Общее правило для HTTP-приложений: Будьте либералом о том, что вы принимаете, быть консервативным о том, что вы посылаете. Это правило означает, что вы должны написать свое приложение, чтобы не допускать излишней интерпретации спецификации, но при этом должны строго передавать данные, которые следует за спецификацией.

+0

Если заголовок также включает размер? Я использую проволочную акулу, и я вижу, что она также определяет длину в начале. Кроме того, есть конечный кусок с нулевым размером? – Timtianyang

+0

@Timtianyang: при использовании кодировки 'chunked' не требуется' Content-Length'. Да, завершающий кусок имеет размер '0', как указано в ответе. – jxh

2

Каждая строка в заголовке HTTP должен быть прекращен с помощью \r\n.

См rfc2616 Раздел 2.2 Основные правила

CR    = <US-ASCII CR, carriage return (13)> 
    LF    = <US-ASCII LF, linefeed (10)> 

HTTP/1.1 определяет последовательность CR LF как маркер конца строки для все элементы протокола, за исключением тела объекта

В вашем примере используется только \n, поэтому заголовки могут отображаться как часть одной строки для некоторых простых http-клиентов. Попробуйте изменить на каждую строку, которая не является частью объекта, используя \r\n

+2

также после последней строки HTTP-заголовка. Он должен быть завершен с помощью «\ r \ n» 2 раза –

+0

@DennyMathew. Похоже, что это делается правильно (см. '\ N' в строке после заголовка' Content-Type' в вопросе) – simonc

+0

,, oh k .. только что сделал утверждение только ... tnx –