Skip to content

Instantly share code, notes, and snippets.

@StephanieSunshine
Created August 20, 2013 01:38
Show Gist options
  • Save StephanieSunshine/6276187 to your computer and use it in GitHub Desktop.
Save StephanieSunshine/6276187 to your computer and use it in GitHub Desktop.
#!/usr/rubinius/2.0/bin/ruby
require 'rubygems'
require 'bundler/setup'
require 'reel'
require 'celluloid/autostart'
class TimeServer
include Celluloid
include Celluloid::Notifications
def initialize
async.run
end
def run
now = Time.now.to_f
sleep now.ceil - now + 0.001
every(1) { publish 'time_change', Time.now }
end
end
class TimeClient
include Celluloid
include Celluloid::Notifications
include Celluloid::Logger
def initialize(websocket)
info "Streaming time changes to client"
@socket = websocket
subscribe('time_change', :notify_time_change)
end
def notify_time_change(topic, new_time)
@socket << new_time.inspect
rescue Reel::SocketError
info "Time client disconnected"
terminate
end
end
class WebServer < Reel::Server
include Celluloid::Logger
def initialize(host = "0.0.0.0", port = 1234)
info "Time server example starting on #{host}:#{port}"
super(host, port, &method(:on_connection))
end
def on_connection(connection)
while request = connection.request
if request.websocket?
info "Received a WebSocket connection"
connection.detach
route_websocket request.websocket
return
else
route_request connection, request
end
end
end
def route_request(connection, request)
if request.url == "/"
return render_index(connection)
end
info "404 Not Found: #{request.path}"
connection.respond :not_found, "Not found"
end
def route_websocket(socket)
if socket.url == "/timeinfo"
TimeClient.new(socket)
else
info "Received invalid WebSocket request for: #{socket.url}"
socket.close
end
end
def render_index(connection)
info "200 OK: /"
connection.respond :ok, <<-HTML
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Reel WebSockets time server example</title>
<style>
body {
font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
font-weight: 300;
text-align: center;
}
#content {
width: 800px;
margin: 0 auto;
background: #EEEEEE;
padding: 1em;
}
</style>
</head>
<script>
var SocketKlass = "MozWebSocket" in window ? MozWebSocket : WebSocket;
var ws = new SocketKlass('ws://' + window.location.host + '/timeinfo');
ws.onmessage = function(msg){
document.getElementById('current-time').innerHTML = msg.data;
}
</script>
<body>
<div id="content">
<h1>Time Server Example</h1>
<div>The time is now: <span id="current-time">...</span></div>
</div>
</body>
</html>
HTML
end
end
TimeServer.supervise_as :time_server
WebServer.supervise_as :reel
sleep
------------------
joshua@wopr:~/freetable/chatserver/celluloid$ ./websockets.rb
I, [2013-08-19T18:35:34.328365 #17139] INFO -- : Time server example starting on 0.0.0.0:1234
E, [2013-08-19T18:35:47.953498 #17139] ERROR -- : WebServer crashed!
NoMethodError: undefined method `websocket?' on an instance of Reel::WebSocket.
kernel/delta/kernel.rb:81:in `websocket? (method_missing)'
./websockets.rb:53:in `on_connection'
kernel/common/method.rb:56:in `call'
kernel/bootstrap/proc.rb:20:in `[] (call)'
/usr/rubinius/2.0/gems/gems/reel-0.3.0/lib/reel/server.rb:27:in `handle_connection'
/usr/rubinius/2.0/gems/gems/celluloid-0.14.1/lib/celluloid/calls.rb:25:in `dispatch'
/usr/rubinius/2.0/gems/gems/celluloid-0.14.1/lib/celluloid/calls.rb:125:in `dispatch'
/usr/rubinius/2.0/gems/gems/celluloid-0.14.1/lib/celluloid/actor.rb:326:in `handle_message'
/usr/rubinius/2.0/gems/gems/celluloid-0.14.1/lib/celluloid/tasks.rb:42:in `initialize'
/usr/rubinius/2.0/gems/gems/celluloid-0.14.1/lib/celluloid/tasks/task_fiber.rb:11:in `create'
kernel/bootstrap/proc.rb:22:in `call'
I, [2013-08-19T18:35:47.959445 #17139] INFO -- : Time server example starting on 0.0.0.0:1234
@knewter
Copy link

knewter commented Aug 20, 2013

My on_connection looks like this:

    def on_connection(connection)
      while request = connection.request
        case request
        when Reel::Request
          route_request connection, request
        when Reel::WebSocket
          info "Received a WebSocket connection"
          route_websocket request
        end
      end
    end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment