javascript — отправленные сервером события с использованием Poco :: Net :: HTTPRequestHandler

Я пытаюсь «поток» данных на страницу HTML5, используя отправленные сервером события.

Этот урок http://www.html5rocks.com/en/tutorials/eventsource/basics/ было очень полезно, чтобы заставить работать на стороне клиента.

Но для серверной части я делаю нечто похожее на пример HTTPServer в http://pocoproject.org/slides/200-Network.pdf

Учебник html5rocks.com дал мне следующую идею для кода обработчика запросов:

void MyRequestHandler::handleRequest (HTTPServerRequest &req, HTTPServerResponse &resp)
{
resp.setStatus(HTTPResponse::HTTP_OK);

resp.add("Content-Type", "text/event-stream");
resp.add("Cache-Control", "no-cache");

ostream& out = resp.send();

while (out.good())
{
out << "data: " << "some data" << "\n\n";
out.flush();

Poco::Thread::sleep(500)
}
}

и источник страницы HTML5:

<!DOCTYPE html>
<html>
<head>
<title>HTLM5Application</title>
</head>
<body>
<p id="demo">hello</p>
<script>
var msgCounter = 0;
var source;
var data;
if(typeof(EventSource) !== "undefined")
{
source = new EventSource('/stream');
document.getElementById("demo").innerHTML = "Event source created";
}
else
{
document.getElementById("demo").innerHTML = "Are you using IE ?";
}

source.addEventListener('message', function(e)
{
msgCounter++;
document.getElementById("demo").innerHTML = "Message received (" + msgCounter + ") !<br/>"+ e.data;
}, false);
</script>
</body>
</html>

Хорошо, что при открытии html-страницы данные передаются в потоковом режиме, и я получаю правильный вывод (текст между тегами обновляется, как и ожидалось.

Проблема в том, что когда я закрываю страницу в браузере, происходит сбой программы POCO, и в консоли появляется следующее сообщение:

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

Process returned 3 (0x3)   execution time : 22.234 s
Press any key to continue.

(Я использую Code :: Blocks, поэтому отображается возвращаемое значение и время выполнения)

Событие, когда я помещаю цикл while () между try {} catch (…) {}, программа все еще падает, не входя в catch (то же самое происходит, когда я помещаю весь контент main () между try / catch)

Основная программа содержит только эти инструкции:

int main(int argc, char* argv[])
{
MyServerApp myServer;
myServer.run(argc, argv);

return 0;
}

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

Заранее спасибо за вашу помощь 🙂

3

Решение

Для всех, кто заинтересовался, я смог решить эту проблему, зарегистрировав собственный обработчик ошибок, который просто игнорирует исключение, которое выдается при отключении SSE-клиента:

#include <Poco\ErrorHandler.h>

// Other includes, using namespace..., etc.

class ServerErrorHandler : public ErrorHandler
{
public:
void exception(const Exception& e)
{
// Ignore an exception that's thrown when an SSE connection is closed.
//
// Info: When the server is handling an SSE request, it keeps a persistent connection through a forever loop.
//       In order to handle when a client disconnects, the request handler must detect such an event. Alas, this
//       is not possible with the current request handler in Poco (we only have 2 params: request and response).
//       The only hack for now is to simply ignore the exception generated when the client disconnects :(
//
if (string(e.className()).find("ConnectionAbortedException") == string::npos)
poco_debugger_msg(e.what());
}
};

class ServerApp : public ServerApplication
{
protected:
int main(const vector<string>& args)
{
// Create and register our error handler
ServerErrorHandler error_handler;
ErrorHandler::set(&error_handler);

// Normal server code, for example:
HTTPServer server(new RequestHandlerFactory, 80, new HTTPServerParams);
server.start();

waitForTerminationRequest();
server.stop();

return Application::EXIT_OK;
}
};POCO_SERVER_MAIN(ServerApp);

Тем не менее, я должен сказать, что это безобразный взломать. Более того, обработчик ошибок является глобальным для приложения, что делает его еще менее желательным в качестве решения. Правильный способ будет обнаруживать отключение и обрабатывать его. Для этого Poco должен пройти SocketStream к обработчику запросов.

2

Другие решения

Вы можете изменить свой код, чтобы ловить исключения Poco:

try {
MyServerApp myServer;
return myServer.run(argc, argv);
}catch(const Poco::Exception& ex) {
std::cout << ex.displayText() << std::endl;
return Poco::Util::Application::EXIT_SOFTWARE;
}
0

По вопросам рекламы [email protected]