分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow
也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!
- 作者:邹祁峰
- 邮箱:Qifeng.zou.job@hotmail.com
- 博客:http://blog.csdn.net/qifengzou
- 日期:2015.12.13~2015.12.14
- 转载请注明来自"祁峰"的CSDN博客
1 引言
![](https://i-blog.csdnimg.cn/blog_migrate/a5ec9becce4bda43f0128afef9d0e904.png)
2 改造LWS
2.1 支持libev
![](https://i-blog.csdnimg.cn/blog_migrate/2afc14b14ff78433883eb7c061328412.jpeg)
图2 开启LIBEV
2.2 改造libev
从图1中的改造后的架构图中可以看出,改造后的WS接入层需要管理与终端的ws连接,同时需要管理与路由层各服务器的TCP连接,还得负责相邻层次间数据的转发工作。而目前LWS并未支持多线程,如果采用多线程的方式改造WS接入层,将可能出现无法预估的后果。因此,本人决定使用单进程单线程的方式,并使用LWS架构接管WS接入层与路由层之间的TCP连接。而要实现让LWS架构接管WS接入层与路由层之间的TCP连接,则需要对LWS库进行如下改造:
2.2.1 函数定义
由于LWS库的Makefile编译选项中设置了-fvisibility=hidden,因此,如果想让LWS库中实现的函数能被库外调用,则在函数实现时必须使用LWS_VISIBLE进行显示说明。在LWS库中的libev.c中添加如下函数:[注:关于libev的用法, 请自行查询]
/****************************************************************************** **函数名称: lws_libev_timer_start **功 能: 添加计时器 **输入参数: ** context: lws上下文 ** timer: 计时器 **输出参数: NONE **返 回: VOID **实现描述: 将计时器加入到libev loop对象 **注意事项: **作 者: # Qifeng.zou # 2015.12.10 # ******************************************************************************/LWS_VISIBLE void lws_libev_timer_start(struct lws_context *context, ev_timer *timer){ ev_timer_start(context->io_loop, timer);}/****************************************************************************** **函数名称: lws_libev_timer_stop **功 能: 停止计时器 **输入参数: ** context: lws上下文 ** timer: 计时器 **输出参数: NONE **返 回: VOID **实现描述: 将计时器从libev loop中删除 **注意事项: **作 者: # Qifeng.zou # 2015.12.10 # ******************************************************************************/LWS_VISIBLE void lws_libev_timer_stop(struct lws_context *context, ev_timer *timer){ ev_timer_stop(context->io_loop, timer);}/****************************************************************************** **函数名称: lws_libev_io_start **功 能: 开启IO帧听 **输入参数: ** context: lws上下文 ** io: IO对象 **输出参数: NONE **返 回: VOID **实现描述: 将io对象加入到libev loop中 **注意事项: **作 者: # Qifeng.zou # 2015.12.10 # ******************************************************************************/LWS_VISIBLE void lws_libev_io_start(struct lws_context *context, ev_io *io){ ev_io_start(context->io_loop, io);}/****************************************************************************** **函数名称: lws_libev_io_stop **功 能: 停止IO帧听 **输入参数: ** context: lws上下文 ** io: IO对象 **输出参数: NONE **返 回: VOID **实现描述: 将io对象从libev loop中删除 **注意事项: **作 者: # Qifeng.zou # 2015.12.10 # ******************************************************************************/LWS_VISIBLE void lws_libev_io_stop(struct lws_context *context, ev_io *io){ ev_io_stop(context->io_loop, io);}
代码1 函数定义
2.2.2 函数声明
完成以上函数的定义后,还需按照如下的格式在libwebsockets.h中进行函数声明。如下所示:
LWS_VISIBLE LWS_EXTERN void lws_libev_timer_start(struct lws_context *context, ev_timer *timer);LWS_VISIBLE LWS_EXTERN void lws_libev_timer_stop(struct lws_context *context, ev_timer *timer);LWS_VISIBLE LWS_EXTERN void lws_libev_io_start(struct lws_context *context, ev_io *io);LWS_VISIBLE LWS_EXTERN void lws_libev_io_stop(struct lws_context *context, ev_io *io);
代码2 函数声明
完成对LWS库中libev的改造后,重新编译和安装LWS库,这时便可利用以上函数将外部建立的TCP连接注入到LWS框架,让LWS框架中的libev接管外部TCP连接的数据接收、数据发送、超时处理等处理。WS接入层与路由层之间的TCP连接,就是通过这种方式让LWS框架接管的。[注意:一定要按照以上格式声明函数,否则可能导致依赖此库的程序无法访问声明的函数]
3 使用LWS
3.1 注册协议回调
终端向WS服务器发起ws连接请求时,一般会在协议头中通过Sec-WebSockets-Protocol指明协议名。而开源 libwebsockets库通过对外提供注册协议回调的接口为用户自定义协议提供服务,注册协议回调的接口中将会指明协议名、以及对应的处理回调、自定义数据的大小等字段。其注册的方式如下所示:/* 注册协议回调配置表 */struct libwebsocket_protocols g_aws_protocols[] ={
{ "chat", /* 协议名:其与Sec-Websockets-Protocol字段对应 */ aws_callback_im_hdl, /* 回调函数:协议对应的回调处理函数 */ sizeof(aws_im_session_data_t), /* 自定义数据空间大小:每个ws连接均会分配一个自定义数据空间 */ 0,