nginx comet

Nginx加Comet:低延迟的服务器端推送

要做实时的网络程序,比如在线聊天等,现在的技术有两种,一种是拉(pull)、一种是推(push),哪种方式好我相信接触网络的朋友们都知道, 服务器端推送服务这种方式能够满足完全的实时交互,不需要客户端做太多的东西。NGiNX_HTTP_Push_Module这个nginx的插件就是为 了这个目的来做的,它保持客户的长连接状态(当然了,不是每个客户一个线程,而是采用事件方式来处理,即保持了连接状态,又节约了资源,这就是nginx 这个轻量级web服务器的可爱之处)并且维护一个事件队列,提供发布者和订阅者服务。

要使用它,需要编译ngnix,从http://pushmodule.slact.net/下载模块,使用

./configure --add-module=/path/to/plugin && make && make install

进行编译,并参考Readme和http://github.com/slact/nginx_http_push_module/blob/master/protocol.txt这两个文件来学习配置,下面是一个比较简单的发布、订阅模型

 

nginx-push.conf

#user nobody;

worker_processes 1;

 

#error_log logs/error.log;

#error_log logs/error.log notice;

#error_log logs/error.log info;

#pid logs/nginx.pid;

 

events {

    worker_connections 1024;

}

 

http {

    include mime.types;

    default_type application/octet-stream;

 

    #log_format main '$remote_addr - $remote_user [$time_local] $request '

    # '"$status" $body_bytes_sent "$http_referer" '

    # '"$http_user_agent" "$http_x_forwarded_for"';

 

    #access_log logs/access.log main;

    sendfile on;

    keepalive_timeout 65;

 

# max allowed memory for buferring

    push_max_reserved_memory 10M;

 

    server {

        listen 80;

        server_name localhost;

 

        location / {

            root html;

            index index.html index.htm;

        }

 

        ###### Push configuration

        # internal publish endpoint (keep it private / protected)

        location /publish {

          set $push_channel_id $arg_id; #/?id=239aff3 or somesuch

          push_publisher;

 

          push_store_messages on; # enable message queueing

          push_message_timeout 2h; # expire buffered messages after 2 hours

          push_max_message_buffer_length 10; # store 10 messages

          push_min_message_recipients 0; # minimum recipients before purge

        }

 

        # public long-polling endpoint

        location /activity {

          push_subscriber;

 

          # how multiple listener requests to the same channel id are handled

          # - last: only the most recent listener request is kept, 409 for others.

          # - first: only the oldest listener request is kept, 409 for others.

          # - broadcast: any number of listener requests may be long-polling.

          push_subscriber_concurrency broadcast;

          set $push_channel_id $arg_id;

          default_type text/plain;

        }

 

        ###### END Push configuration

 

        error_page 404 /404.html;

 

        # redirect server error pages to the static page /50x.html

        error_page 500 502 503 504 /50x.html;

        location = /50x.html {

            root html;

        }

    }

}

这是一个ruby实例

require 'rubygems'

require 'em-http'

 

def subscribe(opts)

  listener = EventMachine::HttpRequest.new('http://127.0.0.1/activity?id='+ opts[:channel]).get :head => opts[:head]

  listener.callback { 

    # print recieved message, re-subscribe to channel with

    # the last-modified header to avoid duplicate messages 

    puts "Listener recieved: " + listener.response + "\n"

 

    modified = listener.response_header['LAST_MODIFIED']

    subscribe({:channel => opts[:channel], :head => {'If-Modified-Since' => modified}})

  }

end

 

EventMachine.run {

  channel = "pub"

 

  # Publish new message every 5 seconds

  EM.add_periodic_timer(5) do

    time = Time.now

    publisher = EventMachine::HttpRequest.new('http://127.0.0.1/publish?id='+channel).post :body => "Hello @ #{time}"

    publisher.callback {

      puts "Published message @ #{time}"

      puts "Response code: " + publisher.response_header.status.to_s

      puts "Headers: " + publisher.response_header.inspect

      puts "Body: \n" + publisher.response

      puts "\n"

    }

  end

 

  # open two listeners (aka broadcast/pubsub distribution)

  subscribe(:channel => channel)

  subscribe(:channel => channel)

}

上面的这个例子每5秒钟发布一则消息,同时nginx服务器会把消息push到连个订阅客户端

你可能感兴趣的:(nginx)