1
0
Fork 0
mirror of https://github.com/teampoltergeist/poltergeist.git synced 2022-11-09 12:05:00 -05:00

Merge pull request #322 from jcoglan/websocket-driver

Replace faye-websocket with websocket-driver.
This commit is contained in:
Jon Leighton 2013-06-09 06:07:44 -07:00
commit c2495eaf44
2 changed files with 15 additions and 79 deletions

View file

@ -1,7 +1,5 @@
require 'socket' require 'socket'
require 'stringio' require 'websocket/driver'
require 'http/parser'
require 'faye/websocket'
module Capybara::Poltergeist module Capybara::Poltergeist
# This is a 'custom' Web Socket server that is designed to be synchronous. What # This is a 'custom' Web Socket server that is designed to be synchronous. What
@ -11,45 +9,6 @@ module Capybara::Poltergeist
# how Web Sockets are usually used, but it's what we want here, as we want to # how Web Sockets are usually used, but it's what we want here, as we want to
# send a message to PhantomJS and then wait for it to respond). # send a message to PhantomJS and then wait for it to respond).
class WebSocketServer class WebSocketServer
class FayeHandler
attr_reader :owner, :env, :parser
def initialize(owner, env)
@owner = owner
@env = env
@parser = Faye::WebSocket.parser(env).new(self)
@messages = []
end
def url
"ws://#{env['SERVER_NAME']}:#{env['SERVER_PORT']}/"
end
def handshake_response
parser.handshake_response
end
def parse(data)
parser.parse(data)
end
def encode(message)
parser.frame(Faye::WebSocket.encode(message))
end
def receive(message)
@messages << message
end
def message?
@messages.any?
end
def next_message
@messages.shift
end
end
# How much to try to read from the socket at once (it's kinda arbitrary because we # How much to try to read from the socket at once (it's kinda arbitrary because we
# just keep reading until we've received a full frame) # just keep reading until we've received a full frame)
RECV_SIZE = 1024 RECV_SIZE = 1024
@ -59,12 +18,11 @@ module Capybara::Poltergeist
HOST = '127.0.0.1' HOST = '127.0.0.1'
attr_reader :port, :parser, :socket, :handler, :server attr_reader :port, :driver, :socket, :server
attr_accessor :timeout attr_accessor :timeout
def initialize(port = nil, timeout = nil) def initialize(port = nil, timeout = nil)
@timeout = timeout @timeout = timeout
@parser = Http::Parser.new
@server = start_server(port) @server = start_server(port)
end end
@ -94,37 +52,16 @@ module Capybara::Poltergeist
# Accept a client on the TCP server socket, then receive its initial HTTP request # Accept a client on the TCP server socket, then receive its initial HTTP request
# and use that to initialize a Web Socket. # and use that to initialize a Web Socket.
def accept def accept
@socket = server.accept @socket = server.accept
@messages = []
while msg = socket.gets @driver = ::WebSocket::Driver.server(self)
parser << msg @driver.on(:connect) { |event| @driver.start }
break if msg == "\r\n" @driver.on(:message) { |event| @messages << event.data }
end
@handler = FayeHandler.new(self, env)
socket.write handler.handshake_response
end end
# Note that the socket.read(8) assumes we're using the hixie-76 parser. This is def write(data)
# fine for now as it corresponds to the version of Web Sockets that the version of @socket.write(data)
# WebKit in PhantomJS uses, but it might need to change in the future.
def env
@env ||= begin
env = {
'REQUEST_METHOD' => parser.http_method,
'SCRIPT_NAME' => '',
'PATH_INFO' => '',
'QUERY_STRING' => '',
'SERVER_NAME' => '127.0.0.1',
'SERVER_PORT' => port.to_s,
'HTTP_ORIGIN' => 'http://127.0.0.1:2000/',
'rack.input' => StringIO.new(socket.read(8))
}
parser.headers.each do |header, value|
env['HTTP_' + header.upcase.gsub('-', '_')] = value
end
env
end
end end
# Block until the next message is available from the Web Socket. # Block until the next message is available from the Web Socket.
@ -132,21 +69,21 @@ module Capybara::Poltergeist
def receive def receive
start = Time.now start = Time.now
until handler.message? until @messages.any?
raise Errno::EWOULDBLOCK if (Time.now - start) >= timeout raise Errno::EWOULDBLOCK if (Time.now - start) >= timeout
IO.select([socket], [], [], timeout) or raise Errno::EWOULDBLOCK IO.select([socket], [], [], timeout) or raise Errno::EWOULDBLOCK
data = socket.recv(RECV_SIZE) data = socket.recv(RECV_SIZE)
break if data.empty? break if data.empty?
handler.parse(data) driver.parse(data)
end end
handler.next_message @messages.shift
end end
# Send a message and block until there is a response # Send a message and block until there is a response
def send(message) def send(message)
accept unless connected? accept unless connected?
socket.write handler.encode(message) driver.text(message)
receive receive
rescue Errno::EWOULDBLOCK rescue Errno::EWOULDBLOCK
raise TimeoutError.new(message) raise TimeoutError.new(message)

View file

@ -16,9 +16,8 @@ Gem::Specification.new do |s|
s.required_ruby_version = ">= 1.9.2" s.required_ruby_version = ">= 1.9.2"
s.add_dependency "capybara", "~> 2.1.0" s.add_dependency "capybara", "~> 2.1.0"
s.add_dependency "http_parser.rb", "~> 0.5.3" s.add_dependency "websocket-driver", ">= 0.2.0"
s.add_dependency "faye-websocket", ">= 0.4.4", "< 0.5.0"
s.add_development_dependency 'rspec', '~> 2.12' s.add_development_dependency 'rspec', '~> 2.12'
s.add_development_dependency 'sinatra', '~> 1.0' s.add_development_dependency 'sinatra', '~> 1.0'