Created
October 26, 2009 02:55
-
-
Save mnutt/218400 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| == NGINX HTTP PUSH == | |
| Steps to reproduce: | |
| Install passenger gem: | |
| sudo gem install passenger | |
| Download nginx: | |
| wget http://sysoev.ru/nginx/nginx-0.7.62.tar.gz | |
| tar -zxvf nginx-0.7.62.tar.gz | |
| ##HACK## | |
| Edit nginx-0.7.62/auto/cc/gcc and search for -Werror and change it to -Wno-error | |
| Otherwise the nginx compile will fail because of warnings in the http push module. | |
| I expect this will be fixed very soon, possibly by the time you read this. | |
| Clone the nginx http push module: | |
| git clone git://github.com/slact/nginx_http_push_module.git | |
| Use the passenger script to install nginx with support for passenger and long polling: | |
| sudo passenger-install-nginx-module --nginx-source-dir=/path/to/src/nginx-0.7.62 \ | |
| --extra-configure-flags="--add-module='/path/to/src/nginx_http_push_module'" | |
| Be sure to specify absolute paths. | |
| Edit /opt/nginx/conf/nginx.conf and make it look something like this: | |
| (make sure to change /path/to to point to the correct directories) | |
| ############################## SAMPLE NGINX ################################ | |
| worker_processes 1; | |
| events { | |
| worker_connections 1024; | |
| } | |
| http { | |
| passenger_root /path/to/passenger-2.2.5; | |
| passenger_ruby /path/to/bin/ruby; | |
| include mime.types; | |
| default_type application/octet-stream; | |
| #maximum amount of memory the push module is allowed to use | |
| #for buffering and stuff | |
| push_max_reserved_memory 12M; | |
| push_queue_messages off; | |
| sendfile on; | |
| keepalive_timeout 65; | |
| server { | |
| listen 80; | |
| server_name localhost; | |
| location / { | |
| root /path/to/your/rails/application/public; | |
| index index.html index.htm; | |
| passenger_enabled on; | |
| rack_env development; | |
| } | |
| # redirect server error pages to the static page /50x.html | |
| # | |
| error_page 500 502 503 504 /50x.html; | |
| location = /50x.html { | |
| root html; | |
| } | |
| #sender | |
| location /send { | |
| allow 127.0.0.1; | |
| deny all; | |
| default_type text/plain; | |
| set $push_channel_id $arg_id; #/?id=239aff3 or somesuch | |
| push_publisher; | |
| push_message_timeout 2h; #buffered messages expire after 2 hours\ | |
| } | |
| #receiver | |
| location /listen { | |
| push_subscriber; | |
| push_subscriber_concurrency broadcast; | |
| set $push_channel_id $arg_id; #/?id=239aff3 or somesuch | |
| default_type text/plain; | |
| } | |
| } | |
| } | |
| ########################### END SAMPLE NGINX ############################# | |
| The ruby/rails app just needs to do a post to localhost/listen. I'm doing | |
| it in-process for now since nginx is on the same box and very responsive, | |
| but there could be reliability implications. | |
| ########################## START RUBY EXAMPLE ############################ | |
| class MessagesController < ApplicationController | |
| def create | |
| @msg = Message.new(:content => params[:content], :user => current_user) | |
| if @msg.save | |
| http = Net::HTTP.new("localhost", 80) | |
| http.post "/send/?id=messages", @msg.to_json | |
| render :json => {:response => 200} | |
| else | |
| render :json => {:response => 500, :errors => @msg.errors } | |
| end | |
| end | |
| def index | |
| render :json => Message.all.to_json | |
| end | |
| end | |
| ########################## END RUBY EXAMPLE ############################## | |
| To fetch new messages in javascript you need to hold an ajax connection open. | |
| This example uses jQuery: | |
| ########################## START JS EXAMPLE ############################## | |
| var newMessage = function(data) { | |
| console.log(data); | |
| }; | |
| // From http://stackoverflow.com/questions/333664/simple-long-polling-example-code | |
| // (by dbr) | |
| function waitForMsg(){ | |
| /* This requests the url "msgsrv.php" | |
| When it complete (or errors)*/ | |
| $.ajax({ | |
| type: "GET", | |
| url: "/listen?id=messages", | |
| async: true, /* If set to non-async, browser shows page as "Loading.."*/ | |
| cache: false, | |
| timeout:50000, /* Timeout in ms */ | |
| dataType: 'json', | |
| success: function(data){ /* called when request to barge.php completes */ | |
| newMessage(data); /* Add response to a .msg div (with the "new" class)*/ | |
| setTimeout( | |
| 'waitForMsg()', /* Request next message */ | |
| 1000 /* ..after 1 seconds */ | |
| ); | |
| }, | |
| error: function(XMLHttpRequest, textStatus, errorThrown){ | |
| console.log("error " + textStatus + " (" + errorThrown + ")"); | |
| setTimeout( | |
| 'waitForMsg()', /* Try again after.. */ | |
| "4000"); /* milliseconds (15seconds) */ | |
| }, | |
| }); | |
| }; | |
| $(function() { waitForMsg(); } ); | |
| ########################## END JS EXAMPLE ############################## |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment