c_socket.io_server笔记之长轮询超时(timeout)处理

标签: socket io server | 发表时间:2013-03-27 08:57 | 作者:nieyong
出处:http://www.blogjava.net/

不吐不快

当你习惯了现有WEB服务器,诸如nginx、apache,JAVA应用服务器Tomcat等,你就不能不注意HTTP请求的响应超时时间,需要小心,尤其是反向代理时。当你可以自由控制请求timeout超时时,那是怎样一个快意。
在libev中使用timeout,没有像java那样封装的完善,一切都很原始,但确实锋利多了。

长轮询

一般长轮询需要定义超时时间,一旦超时,服务器端会主动断开连接。无论是xhr形式的长轮询,还是jsonp长轮询,在服务器端处理没有多大差别,输出数据有异。

输出头部

一般优先输出头部,告诉浏览器,需要保持长连接,当然,这需要浏览器支持http 1.1协议,并且明确的注明当前连接为一直保持着:keep-alive:

char heaer_str[200] = "";
strcat(heaer_str, "HTTP/1.1 200 OK\r\n");
strcat(heaer_str, "Content-Type: text/plain; charset=UTF-8\r\n");
strcat(heaer_str, "Connection: keep-alive\r\n");
strcat(heaer_str, "\r\n");
write_msg(client, heaer_str);

定时器启动,等待

连接什么时候关闭,需要在代码中手动控制,除非浏览器端在发出请求等待响应期间出现异常,无故断开了连接。设服务器端设定好连接持续时间为30秒,那么就应该启动一个定时器,除非所使用的语言层面提供了内置支持。

client->timeout.data = client;
ev_timer_init(&client->timeout, timeout_cb, 30.0, 0); //30s
ev_timer_start(loop, &client->timeout);

定时器start之后,触发的函数timeout_cb:

 1     static void timeout_cb(EV_P_ struct ev_timer *timer, int revents) {
 2         if (EV_ERROR & revents) {
 3             fprintf(stderr, "error event in timer_beat\n");
 4             return ;
 5         }
 6     
 7         if (timer == NULL) {
 8             fprintf(stderr, "the timer is NULL now !\n");
 9             return;
10         }
11     
12         client_t *client = timer->data;
13     
14         if (client == NULL) {
15             fprintf(stderr, "Timeout the client is NULL !\n");
16             return;
17         }
18     
19         write_msg(client, HTML_RESPONSE_ECHO);
20         free_res(loop, client);
21     }

可以看到,定时器触发之后,本例中将输出一串预先定义好的文字,然后关闭连接。
如何关闭触发器,则很简单:


    ev_timer *timer = &client->timeout;
    if (timer != NULL && (timer->data != NULL)) {
        ev_timer_stop(loop, timer);
    }

编译运行

编译一下:

gcc long polling.c -o longpolling ../include/libev.a ../include/http-parser/http_parser.o -lm

运行它:

./long_polling

然后测试:

curl -i http://192.168.190.150:9000/long_polling

可以先看到头部:

HTTP/1.1 200 OK Content-Type: text/plain; charset=UTF-8 Connection: keep-alive

等到30秒后输出具体的文字内容:

The timeout(30s) had passed, you are welcome ~!

小结

所演示的长轮询,没有什么难度,HTTP 1.1头部输出,定时器启动,然后等待输出。
libev内含的timer组件简单易用,控制方便,但不算是最佳实践,官方文档给出了若干种最佳实践方式。具体可参阅:
http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod#code evtimer code relativeandopti

完整代码



nieyong 2013-03-27 08:57 发表评论

相关 [socket io server] 推荐:

Socket Server的N种并发模型汇总

- - 掘金架构
刘丹冰Aceld,微信公众号同名. 本文主要介绍常见的Server的并发模型,这些模型与编程语言本身无关,有的编程语言可能在语法上直接透明了模型本质,所以开发者没必要一定要基于模型去编写,只是需要知道和了解并发模型的构成和特点即可. 那么在了解并发模型之前,我们需要两个必备的前置知识:. 多线程/多进程等并发编程理论.

有关socket read

- - 五四陈科学院
以下内容由 [五四陈科学院]提供. 实际开发中,网络程序最可能遇到的就是数据没收到、收到错误数据这样诡异的问题.. 很多时候,都是由于对socket read的细节理解的不一致,导致了程序前后的矛盾. 下面详细阐述整个read的过程. read函数是负责从fd中读取内容.. 当读成功时, read返回实际所读的字节数.

物理IO与逻辑IO

- - 操作系统 - ITeye博客
IO性能对于一个系统的影响是至关重要的. 一个系统经过多项优化以后,瓶颈往往落在数据库;而数据库经过多种优化以后,瓶颈最终会落到IO. 而IO性能的发展,明显落后于CPU的发展. Memchached也好,NoSql也好,这些流行技术的背后都在直接或者间接地回避IO瓶颈,从而提高系统性能. 上图层次比较多,但总的就是三部分.

Socket的速率控制

- - CSDN博客互联网推荐文章
做一个以精确速率向外输出数据的数据源,要完成这个目标,最基础的是:. 1、找到一种精确的计时器,在精确的时间范围内控制数据源以指定的速度向外发送数据. 2、通过对套接字选项和线程优先级的设置减少网络因素对发送速度造成的影响,从而提高发送精度,保证数据的实际发送量尽可能的达到指定的理论发送量.      针对第一个要求,通过寻找到一种时间精度达到微秒级的精确计数器来保证,在硬件支持的情况下可以通过WindowsAPI获取时钟频率以及震荡次数,通过在事件两端分别调用函数得到震荡次数的差值并结合时钟频率可以计算出精确的时间间隔,通过指定的传输速度和精确的延时可以计算出需要发送的数据量.

ZeroMQ(java)中监控Socket

- - CSDN博客架构设计推荐文章
基本上ZeroMQ(java)中基本的代码都算是过了一遍了吧,不过觉得它在日志这一块貌似基本没有做什么工作,也就是我们通过日志来知道ZeroMQ都发生了什么事情. 而且由于ZeroMQ中将连接的建立和重连接都进行了隔离,用户不需要做什么事情来维护连接,当然这样做的好处是使程序员的编码工作变少了,但是当然也有不好的地方,那就是用户失去了对ZeroMQ整个运行阶段的控制.

java socket参数详解:BackLog

- - 开源软件 - ITeye博客
 java socket参数详解:BackLog. 输入连接指示(对连接的请求)的最大队列长度被设置为 backlog 参数. 如果队列满时收到连接指示,则拒绝该连接. backlog参数必须是大于 0 的正值. 如果传递的值等于或小于 0,则假定为默认值. 经过测试这个队列是按照 FIFO(先进先出)的原则.

HTML5 Web socket和socket.io - wishyouhappy

- - 博客园_首页
   HTML5的新特性,用于双向推送消息(例如网页聊天,手机推送消息等). client利用regular http请求webpage. 请求的webpage 执行javascript脚本,open a connection to server.. 有新的信息时服务器和客户端可以相互发送信息(Real-time traffic from the server to the client .

tcp/ip ,http,socket的关系

- - 行业应用 - ITeye博客
  物理层、数据链路层、网络层、传输层、会话层、表示层和应用层.   通过初步的了解,我知道IP协议对应于网络层,TCP协议对应于传输层,而HTTP协议对应于应用层,.   三者从本质上来说没有可比性,.   socket则是对TCP/IP协议的封装和应用(程序员层面上).   也可以说,TPC/IP协议是传输层协议,主要解决数据如何在网络中传输,.

SQL Server--索引

- - CSDN博客推荐文章
         1,概念:  数据库索引是对数据表中一个或多个列的值进行排序的结构,就像一本书的目录一样,索引提供了在行中快速查询特定行的能力..             2.1优点:  1,大大加快搜索数据的速度,这是引入索引的主要原因..                             2,创建唯一性索引,保证数据库表中每一行数据的唯一性..

SQL Server 面试

- - SQL - 编程语言 - ITeye博客
在SQL语言中,一个SELECT…FROM…WHERE语句称为一个查询块,将一个查询块嵌套在另一个查询块的WHERE子句中的查询称为子查询. 子查询分为嵌套子查询和相关子查询两种. 嵌套子查询的求解方法是由里向外处理,即每个子查询在其上一级查询处理之前求解,子查询的结果作为其父查询的查询条件. 子查询只执行一次,且可以单独执行;.