Permalink
Browse files

adds 'RPC push' example

  • Loading branch information...
1 parent a92490d commit ce5f6ea5acb91cee45e3a337e560342c822ee7eb @frsyuki committed Jul 21, 2010
Showing with 159 additions and 5 deletions.
  1. +16 −0 examples/README.md
  2. +1 −1 examples/echo.rb
  3. +26 −0 examples/rpc
  4. +47 −0 examples/rpc.rb
  5. +2 −4 examples/shoutchat.rb
  6. +67 −0 examples/views/rpc.erb
View
@@ -14,11 +14,27 @@ A HTTP server runs on localhost:8080 and WebSocket server runs on localhost:8081
Then access to [htt://localhost:8080/echo.html](http://localhost:8080/echo.html).
+## RPC push
+
+With RPC (Remote Procedure Call), you can push messages to browsers from programs separated from the WebSocket server.
+
+In this example, a Sinatra based web appliction pushes messages using MessagePack-RPC, a simple cross-language RPC library.
+
+ $ gem install msgpack-rpc
+ $ gem install rev-websocket
+ $ gem install sinatra
+ $ gem install json
+ $ ruby ./rpc
+
+Then access to [htt://localhost:8080/](http://localhost:8080/).
+
+
## ShoutChat
ShoutChat is a simple browser-based chat application.
$ gem install rev-websocket
+ $ gem install json
$ ruby ./shoutchat
Then access to [htt://localhost:8080/shoutchat.html](http://localhost:8080/shoutchat.html).
View
@@ -5,7 +5,7 @@
class EchoConnection < Rev::WebSocket
def on_open
- puts "WebSocket opened"
+ puts "WebSocket opened from '#{peeraddr[2]}': request=#{request.inspect}"
send_message("server: Hello, world!")
end
View
@@ -0,0 +1,26 @@
+#!/usr/bin/env ruby
+
+fork {
+ load 'rpc.rb'
+ exit 0
+}
+
+require 'rubygems'
+require 'sinatra'
+require 'msgpack/rpc'
+
+rpc_port = 18800
+$ws = MessagePack::RPC::Client.new('127.0.0.1', rpc_port)
+
+get '/' do
+ erb :rpc
+end
+
+post '/push' do
+ data = {'Hello'=>'World!', 'data' => params}
+ $ws.call(:push_data, data)
+ redirect '/', 303
+end
+
+set :port, 8080
+
View
@@ -0,0 +1,47 @@
+# RPC push
+# This program receives messages.
+# See ./rpc file which sends messages to this program.
+
+require 'rubygems'
+require 'rev/websocket'
+require 'msgpack/rpc'
+require 'json'
+
+$sockets = {}
+
+class MyConnection < Rev::WebSocket
+ def on_open
+ puts "WebSocket opened from '#{peeraddr[2]}': request=#{request.inspect}"
+ $sockets[self] = self
+ end
+
+ def on_close
+ puts "WebSocket closed"
+ $sockets.delete(self)
+ end
+end
+
+class RPCServer
+ def push_data(data)
+ $sockets.each_key {|sock|
+ sock.send_message(data.to_json)
+ }
+ nil
+ end
+end
+
+host = '0.0.0.0'
+port = ARGV[0] || 8081
+
+rpc_port = 18800
+
+loop = Rev::Loop.default
+
+ws = Rev::WebSocketServer.new(host, port, MyConnection)
+ws.attach(loop)
+
+rpc = MessagePack::RPC::Server.new(loop)
+rpc.listen('127.0.0.1', rpc_port, RPCServer.new)
+
+loop.run
+
View
@@ -41,8 +41,7 @@ def size
class ShoutChatConnection < Rev::WebSocket
def on_open
- @host = request['HTTP_HOST']
- return unless @host
+ @host = peeraddr[2]
puts "connection opened: <#{@host}>"
@sid = $pubsub.subscribe {|data|
@@ -53,15 +52,14 @@ def on_open
end
def on_message(data)
- puts "broadcasting: <#{@host}> #{data}"
+ puts "broadcasting: <#{@host}> '#{data}'"
$pubsub.publish(data)
$record.push(data)
$record.shift while $record.size > 20
end
def on_close
- return unless @host
puts "connection closed: <#{@host}>"
$pubsub.unsubscribe(@sid)
View
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="UTF-8" />
+ <meta content="text/css" http-equiv="content-style-type" />
+ <meta content="text/javascript" http-equiv="content-script-type" />
+
+ <script type="text/javascript" src='js/jquery.min.js'></script>
+ <script type="text/javascript" src='js/swfobject.js'></script>
+ <script type="text/javascript" src='js/FABridge.js'></script>
+ <script type="text/javascript" src='js/web_socket.js'></script>
+ <script type="text/javascript" src='js/json2.js'></script>
+ <link rel="stylesheet" type="text/css" href="echo.css" />
+
+ <title>Rev-WebSocket Demo: Echo server</title>
+
+ <script>
+ WS_URL = "ws://localhost:8081";
+ WEB_SOCKET_SWF_LOCATION = "js/WebSocketMain.swf";
+
+ var global = this;
+
+ $(document).ready(function(){
+
+ function debug(message) {
+ html = "<p><span class='time'>"+new Date()+"</span>"+message+"</p>"
+ $("#debug").append(html);
+ }
+
+ debug("connecting to "+WS_URL+"...");
+ ws = new WebSocket(WS_URL);
+
+ ws.onopen = function() {
+ debug("connected.");
+
+ text = "client: hello";
+ ws.send(text);
+
+ debug("message sent: "+text);
+ }
+
+ ws.onclose = function() {
+ debug("disconnected...");
+ }
+
+ ws.onerror = function(msg) {
+ debug("failed to connect:"+msg);
+ }
+
+ ws.onmessage = function(event) {
+ debug("message received: "+event.data);
+ $("#message").append("<p>"+event.data+"</p>");
+ }
+ });
+ </script>
+</head>
+<body>
+ <div>
+ <form action="/push" target="_blank" method="post">
+ <input type="text" name="text" id="text" value="text..." />
+ <input type="submit" value="submit" />
+ </form>
+ </div>
+
+ <div id="message"></div>
+ <div id="debug"></div>
+</body>

0 comments on commit ce5f6ea

Please sign in to comment.