博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
webtail——websocket
阅读量:6230 次
发布时间:2019-06-21

本文共 2449 字,大约阅读时间需要 8 分钟。

前面介绍了服务器端如何监听和增量读取文件,这里通过基于boost asio的websocketpp,实现了一个简单的websocket服务端,能够和浏览器进行通信,将读取到的文件通过websocket协议进行实时传送。

关于websocket的简单介绍,可以参考。websocket协议,在中定义。

websocketpp对websocket和简单的http都进行了比较好的封装,只要实现几个handler,就可以完成对连接、消息等的操作和控制。主要需要处理的,可能有以下的handler:

[cce lang=”cpp”]
typedef lib::function<void(connection_hdl)> open_handler;
typedef lib::function<void(connection_hdl)> close_handler;
typedef lib::function<void(connection_hdl)> http_handler;
typedef lib::function<void(connection_hdl,message_ptr)> message_handler
[/cce]
分别处理连接创建,连接关闭,http请求和消息请求。其中connection_hdl是连接的weak_ptr。

这里对websocket使用很简单,唯一的需求,就是维护已经建立的连接(既创建连接的时候记录,关闭连接的时候移出),然后通过将自己的回调注册到文件监控类中,实时的将消息推送到websocket客户端。

首先,维护一个set,用来保存当前已经建立的所有连接:

[cce lang=”cpp”]
typedef std::set<websocketpp::connection_hdl,boost::owner_less<websocketpp::connection_hdl> > ConnectionSet;
[/cce]
然后在建立连接的时候插入到这个set中:
[cce lang=”cpp”]
void WebSocketServer::onOpen ( websocketpp::connection_hdl hdl )
{
boost::lock_guard<boost::mutex> lock(_mutex);
_conns.insert(hdl);
}
[/cce]
在连接关闭的时候,移除连接:
[cce lang=”cpp”]
void WebSocketServer::onClose ( websocketpp::connection_hdl hdl )
{
boost::lock_guard<boost::mutex> lock(_mutex);
_conns.erase(hdl);
}
[/cce]
另外,定义一个让filewatcher调用的回调:
[cce lang=”cpp”]
void WebSocketServer::write ( const std::string& content )
{
boost::lock_guard<boost::mutex> lock(_mutex);
BOOST_AUTO(it, _conns.begin());
for(; it != _conns.end(); ++it) {
_s.send(*it, content, websocketpp::frame::opcode::text);
}
}
[/cce]
这个回调很简单,就是当有读取到内容的时候,遍历连接集合,向每个连接发送具体的内容。

最后,为了方便用户访问,当发现是标准http请求的时候,我们返回一个简单的html,用于显示和建立websocket连接。如果不指定具体的http_handler,websocketpp在发现请求是http的时候,会返回http的426错误(Upgrade Required)。

[cce lang=”cpp”]
void WebSocketServer::httpHandler ( websocketpp::connection_hdl hdl )
{
server::connection_ptr connPtr = _s.get_con_from_hdl(hdl);;

connPtr->set_status(websocketpp::http::status_code::ok);

connPtr->set_body(htmlContent);
}
[/cce]

另外,还有一个小坑。按照websocketpp的example,在启动的时候都是直接调用server的listen函数,而且使用的都是只有端口号的那个实现。实际使用过程中,发现这个只有端口号的实现,直接使用了ipv6协议。虽说如果本机同时支持ipv6和ipv4的情况下,两个协议对应的端口都会监听,但是遇到了服务器上关闭了ipv6,会导致boost asio抛出address_family_not_supported异常,导致应用被迫退出。为了兼容这种方式,对这个异常进行了抓取,重新降级尝试ipv4协议,这样能够很好的在只有ipv4的服务器上进行使用。

[cce lang=”cpp”]
try{
_s.listen(port);
} catch(boost::system::system_error const& e) {
if(e.code() == boost::asio::error::address_family_not_supported) {
_s.listen(boost::asio::ip::tcp::v4(), port);
}
} catch (…) {
throw;
}
[/cce]

转载自:https://coolex.info/blog/411.html

你可能感兴趣的文章
nagios客户端未启动报错
查看>>
南京大学周志华教授当选欧洲科学院外籍院士
查看>>
《OpenGL ES应用开发实践指南:Android卷》—— 1.3 初始化OpenGL
查看>>
马士兵教学语录
查看>>
计算机网络与Internet应用
查看>>
标签制作软件中如何导出标签模板为PDF文件?
查看>>
[CF919E]Congruence Equation
查看>>
Java IO最详解
查看>>
关于错误error C4430 error C2365 error C2078 error C2440 error C2143的处理。
查看>>
用python写一个抽奖程序
查看>>
npm使用入门(package.json)
查看>>
You are beautiful
查看>>
inline和宏之间的区别
查看>>
hibernate篇章五--Hibernage工作原理
查看>>
MongodDB学习笔记(二)(复制)
查看>>
oracle在线迁移同步数据,数据库报错
查看>>
Java中1.0 / 0.0 会输出什么?
查看>>
linux性能剖析工具
查看>>
DP ZOJ 3872 Beauty of Array
查看>>
jQuery Ajax实例 ($.ajax_$.post_$.get)
查看>>