我正在尝试使用服务器发送的事件将数据“流式传输”到HTML5页面。
本教程http://www.html5rocks.com/en/tutorials/eventsource/basics/对于让客户端工作非常有帮助。
但对于服务器端,我正在执行与http://pocoproject.org/slides/200-Network.pdf
中的HTTPServer示例类似的操作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,这就是显示返回值和执行时间的原因)
当我在try {} catch(...){}之间放置while()循环时,程序仍然在没有进入catch的情况下崩溃(同样的事情发生在我把整个main()的内容放在try之间/ catch)
主程序仅包含以下说明:
int main(int argc, char* argv[])
{
MyServerApp myServer;
myServer.run(argc, argv);
return 0;
}
我想知道可能导致崩溃的原因以及我如何解决这个问题。
提前感谢您的帮助:)
答案 0 :(得分:2)
对于任何感兴趣的人,我能够通过注册我自己的错误处理程序来处理这个问题,该错误处理程序只是忽略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
传递给请求处理程序。
答案 1 :(得分:0)
您可以更改代码以捕获Poco Exceptions:
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;
}