Nginx HTTP Push

前些天看到一个Nginx的Module,用来是实现Comet,今天简单试了一下功能。作者名叫Leo Ponomarev,项目地址:http://pushmodule.slact.net/

安装

Module需要在编译时加入nginx,同时下载nginx和nginx-push-module,在nginx configure时增加一个参数:
./configure –add-module=path/to/nginx_http_push_module

使用

编写一个非常基本的nginx配置文件:

events{
	worker_connections 1024;
}
http{
	server {
		listen	80;
		server_name	localhost;

		location /publish {
			set $push_channel_id $arg_id;

			push_publisher;

			push_store_messages on;
			push_message_timeout 2h;
			push_max_message_buffer_length 10;
			push_min_message_recipients 0;
		}

		location /subscribe{
			push_subscriber;

			push_subscriber_concurrency broadcast;
			set $push_channel_id $arg_id;
			default_type text/plain;
		}

	}
}

一个简单的Server定义了两个路径分别用于publish和subscribe。所有相关的配置项可以在项目主页找到解释,不作赘述。

启动nginx
nginx -c /home/sun/nginxpush/nginx-push.conf

打开一个终端访问subscribe
curl -X GET http://localhost/subscribe?id=0

可以看到HTTP请求被阻塞

打开另一个终端访问publish
curl -X POST http://localhost/publish?id=0 -d “Hello World”

此时subscriber收到字符串”Hello World” ,完成HTTP请求。

subscriber可以通过设置HTTP头来对消息进行过滤,如
curl -X POST http://localhost/publish?id=0 -d “Hello World”
curl -X GET http://localhost/subscribe?id=0 –verbose

* About to connect() to localhost port 80 (#0)
*   Trying 127.0.0.1… connected
* Connected to localhost (127.0.0.1) port 80 (#0)
> GET /subscribe?id=0 HTTP/1.1
> User-Agent: curl/7.19.7 (i686-pc-linux-gnu) libcurl/7.19.7 OpenSSL/0.9.8l zlib/1.2.3.3
> Host: localhost
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/0.8.28
< Date: Thu, 26 Nov 2009 09:45:25 GMT
< Content-Type: application/x-www-form-urlencoded
< Content-Length: 10
< Last-Modified: Thu, 26 Nov 2009 09:44:59 GMT
< Connection: keep-alive
< Etag: 0
< Vary: If-None-Match, If-Modified-Since
<
* Connection #0 to host localhost left intact
* Closing connection #0

HelloWorld

从响应的头部可以看到Last-Modified: Thu, 26 Nov 2009 09:44:59 GMT的时间是上一次publish的时间,并且通过Vary字段提示了两个选项

  • If-None-Match
  • If-Modified-Since

RFC中对Vary头是这样解释的:

The Vary field value indicates the set of request-header fields that fully determines, while the response is fresh, whether a cache is permitted to use the response to reply to a subsequent request without revalidation.

即可以通过发送If-Modified-Since来获取指定时间之后的数据

curl -X GET -H “If-Modified-Since: Thu, 26 Nov 2009 09:44:50 GMT” http://localhost/subscribe?id=0 –verbose

这时subscribe会重新被阻塞而不是接收上次publish的数据,充分利用了HTTP的语义。

这样用push module来做Web-IM、聊天室的思路就非常清晰了:每个浏览器保持一个subscriber连接,在接收到消息后连接关闭。把消息打印出来,并根据消息响应的头部Last-Modified请求重新subscribe。

This entry was written by Sunng , posted on Thursday November 26 2009at 06:11 pm , filed under 手艺 and tagged , , . Bookmark the permalink . Post a comment below or leave a trackback: Trackback URL.

2 Responses to “Nginx HTTP Push”

  • goodtiger says:

    Moontools的APE也是Server Pull

    • Sunng says:

      @goodtiger, 这类技术如果不是客户端轮询的话应该都需要服务器端支持长连接,仅仅浏览器端不太好实现。。。
      我听说还有利用Flash做的
      另外HTML5里面有个WebSocket,可能是对这一类功能有一个比较好的封装

      HTML5里一些新功能真变态,都可以在客户端写数据库了

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

*
To prove you're a person (not a spam script), type the security word shown in the picture. Click on the picture to hear an audio file of the word.
Click to hear an audio file of the anti-spam word