Skip to content

Instantly share code, notes, and snippets.

@Asmod4n
Forked from robertjpayne/server.rb
Last active January 4, 2016 17:29
Show Gist options
  • Save Asmod4n/8654523 to your computer and use it in GitHub Desktop.
Save Asmod4n/8654523 to your computer and use it in GitHub Desktop.
source 'https://rubygems.org'
platform :rbx do
gem 'rubysl'
end
gem 'reel', github: 'celluloid/reel'
gem 'websocket-driver'
gem 'rack'
#!/usr/bin/env ruby
require 'bundler/setup'
require 'rack'
require 'reel'
require File.expand_path('../websocket_handler.rb', __FILE__)
class Server < Reel::Server::HTTP
include Celluloid::Logger
def initialize(host = '0.0.0.0', port = (ENV['PORT'] || 5000).to_i)
super(host, port, &method(:on_connection))
end
def on_connection(connection)
connection.each_request do |request|
if request.websocket?
connection.detach
handle_websocket_request(request, connection)
return
else
handle_http_request(request, connection)
end
end
end
def handle_http_request(request, connection)
request.respond :ok, {'Content-Type' => 'text/html'}, "Hello Lame"
end
def handle_websocket_request(request, connection)
debug("[handle_websocket_request] method: #{request.method}, url: #{request.url}, uri: #{request.uri}, query_string: #{request.query_string}, fragment: #{request.fragment}, headers: #{request.headers}")
ws = WebSocketHandler.new(request, connection)
ws.on :open do |event|
debug('[ws] open')
end
ws.on :message do |event|
debug('[ws] message')
end
ws.on :close do |event|
debug('[ws] close')
end
ws.on :error do |event|
debug('[ws] error')
end
ws.run
debug("[handle_websocket_request] finished")
end
end
Server.run
require 'forwardable'
require 'websocket/driver'
class WebSocketHandler
include Celluloid::IO
include Celluloid::Logger
extend Forwardable
def initialize(request, connection)
@request = request
@connection = connection
@socket = nil
end
def_delegators :driver, :on, :text, :binary, :ping, :close
def run
# grab socket
@socket = @connection.socket
# start the driver
driver.start
# hook into close message from client
driver.on(:close) { @connection.close }
begin
loop do
break unless @connection.alive?
buffer = @socket.readpartial(@connection.buffer_size)
driver.parse(buffer)
end
ensure
@connection.close
end
rescue EOFError
@connection.close
end
def url
@request.url
end
def env
@env ||= begin
e = {
:method => @request.method,
:input => @request.body.to_s,
'REMOTE_ADDR' => @request.remote_addr
}.merge(Hash[@request.headers.map { |key, value| ['HTTP_' + key.upcase.gsub('-','_'),value ] }])
::Rack::MockRequest.env_for(url, e)
end
end
def write(buffer)
# should probably raise an error here if
# writing to socket that has not been started up yet
@socket.write(buffer)
end
def close
@connection.close if @connection.alive? && [email protected]?
end
protected
def driver
@driver ||= ::WebSocket::Driver.rack(wrapped_object)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment