Permalink
Switch branches/tags
Nothing to show
Find file
Fetching contributors…
Cannot retrieve contributors at this time
193 lines (160 sloc) 4.47 KB
require 'web_socket'
require 'rest_client'
require 'json'
require 'parser'
module SocketIO
# params [URI, String] uri
def self.connect(uri, options = {}, &block)
uri = URI(uri)
options[:path] = uri.path
# support query data
query = options[:query]
query = "?#{query}" if query
# handshake
response = RestClient.get "#{uri.scheme}://#{uri.host}:#{uri.port}/socket.io/1/#{query}"
response_array = response.split(':')
response_array = [uri] + response_array << options
cli = Client.new(*response_array)
cli.instance_eval(&block) if block
cli.start
end
class Client
[:INT, :TERM].each do |sig|
Signal.trap(sig) do
puts
puts "bye"
exit
end
end
# The state of the Socket.IO socket can be disconnected, disconnecting, connected and connecting.
# The transport connection can be closed, closing, open, and opening.
def initialize(uri, session_id, heartbeat_timeout, connection_timeout, supported_transports, options = {})
@uri = uri
namespace = uri.path.sub(%r~^/~, '')
@namespace = namespace.empty? ? "socket.io" : namespace
@session_id = session_id
@hb_timeout = heartbeat_timeout
@connect_timeout = connection_timeout
@supported_transports = supported_transports
@options = options
@reconnect = options[:reconnect]
@on_event = {}
@path = options[:path]
@end_point = options[:end_point]
end
def start
self.instance_eval(&@before_start) if @before_start
connect_transport
start_recieve_loop
self.instance_eval(&@after_start) if @after_start
@thread.join unless @options[:sync]
self
end
def connect_transport
if @supported_transports.include? "websocket"
scheme = @uri.scheme == "https" ? "wss" : "ws"
@transport = WebSocket.new("#{scheme}://#{@uri.host}:#{@uri.port}/socket.io/1/websocket/#{@session_id}", origin: @uri.to_s)
else
raise "We only support WebSockets.. and this server doesnt like web sockets.. O NO!!"
end
end
def start_recieve_loop
@thread = Thread.new() do
while data = @transport.receive()
recieve_loop_body(Parser.decode(data))
end
end
@thread
end
private
def recieve_loop_body(decoded)
case decoded[:type]
when '0'
@on_disconnect.call if @on_disconnect
when '1'
if @end_point
unless @end_point == decoded[:end_point]
@transport.send("1::#{@end_point}:")
end
end
@on_connect.call if @on_connect
when '2'
send_heartbeat
@on_heartbeat.call if @on_heartbeat
when '3'
@on_message.call decoded[:data] if @on_message
when '4'
@on_json_message.call decoded[:data] if @on_json_message
when '5'
message = JSON.parse(decoded[:data])
@on_event[message['name']].call message['args'] if @on_event[message['name']]
when '6'
@on_ack.call if @on_ack
when '7'
@on_error.call decoded[:data] if @on_error
when '8'
@on_noop.call if @on_noop
end
end
public
def disconnect
@transport.send("0::")
end
def disconnected
if @reconnect
connect_transport
start_recieve_loop
end
end
def join
@thread.join
end
def send_heartbeat
@transport.send("2::") #rescue false
end
def send_message(string)
@transport.send("3:::#{string}") #rescue false
end
alias :send :send_message
def send_json_message(hash)
@transport.send("4:::#{hash.to_json}") # rescue false
end
def send_event(name, hash)
@transport.send("5:::#{{name: name, args: [hash]}.to_json}") # rescue false
end
alias :emit :send_event
def before_start(&block)
@before_start = block
end
def after_start(&block)
@after_start = block
end
def on_disconnect(&block)
@on_disconnect = block
end
def on_connect(&block)
@on_connect = block
end
def on_heartbeat(&block)
@on_heartbeat = block
end
def on_message(&block)
@on_message = block
end
def on_json_message(&block)
@on_json_message = block
end
def on_event(name, &block)
@on_event[name] = block
end
def on_ack(&block)
@on_ack = block
end
def on_error(&block)
@on_error = block
end
def on_noop(&block)
@on_noop = block
end
end
end