Skip to content

Instantly share code, notes, and snippets.

@kjellm
Last active December 14, 2015 15:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kjellm/5112038 to your computer and use it in GitHub Desktop.
Save kjellm/5112038 to your computer and use it in GitHub Desktop.
Plugman, Celluloid, DCell, Reel, Websockets
#! /usr/bin/env ruby
require 'reel'
require 'dcell'
DCell.start :id => "web_server", :addr => "tcp://127.0.0.1:9001"
class Inbox
include Celluloid
include Celluloid::Notifications
def notify(msg)
publish 'message_received', msg
end
end
class WebsocketHandler
include Celluloid
include Celluloid::Notifications
def initialize(websocket)
@socket = websocket
subscribe('message_received', :message_received)
end
def message_received(topic, message)
@socket << message
rescue Reel::SocketError
info "Time client disconnected"
terminate
end
end
class WebServer < Reel::Server
include Celluloid::Logger
def initialize(host = "127.0.0.1", port = 9002)
info "Web server starting on #{host}:#{port}"
super(host, port, &method(:on_connection))
end
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
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 == "/counter"
WebsocketHandler.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>Websocket 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 + '/counter');
ws.onmessage = function(msg){
document.getElementById('counter').innerHTML = msg.data;
}
</script>
<body>
<div id="content">
<h1>Websocket example</h1>
<div>Counter: <span id="counter">...</span></div>
</div>
</body>
</html>
HTML
end
end
Inbox.supervise_as :inbox
WebServer.supervise_as :reel
sleep
#! /usr/bin/env ruby
require 'plugman'
require 'dcell'
DCell.start :id => "worker", :addr => "tcp://127.0.0.1:9003"
class DCellPlugin
include Celluloid
def initialize
@node = ::DCell::Node["web_server"]
@inbox_service = @node[:inbox]
end
def task_done(report)
@inbox_service.notify(report)
end
end
class LoggerPlugin
def task_done(report)
puts "Report: #{report}"
end
end
class AReallyHardWorkingWorker
def initialize
@plugman = Plugman.new(plugins: [DCellPlugin.new, LoggerPlugin.new])
@n = 0
end
def run
loop do
do_task_that_requires_hard_work
@plugman.notify(:task_done, @n.to_s)
sleep 1
end
end
def do_task_that_requires_hard_work
@n += 1
end
end
DCellPlugin.supervise_as :worker
AReallyHardWorkingWorker.new.run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment