def run(obj, host = DEFHOST, port = DEFPORT, opts = {:tls => false})
tries = [port, opts[:port_fail]].include?(:auto) ? 100 : 1
port = DEFPORT if :auto == port
raise "root permission required for port below 1024 (#{port})" if port < 1024 && Process.euid != 0
begin
server = EM.start_server(host, port, PryRemoteEm::Server, obj, opts) do |pre|
Fiber.new {
begin
yield pre if block_given?
Pry.start(obj, :input => pre, :output => pre)
ensure
pre.close_connection
end
}.resume
end
rescue => e
if (e.message.include?('port is in use') || e.message.include?('no acceptor')) && tries > 1
tries -= 1
port += 1
retry
end
raise "can't bind to #{host}:#{port} - #{e}"
end
url = "#{opts[:tls] ? 'pryems' : 'pryem'}://#{host}:#{port}/"
name = obj.send(:eval, 'self') rescue "#{obj}"
name = Pry.view_clip(name)
PryRemoteEm.servers[url] = [server, name]
(opts[:logger] || ::Logger.new(STDERR)).info("[pry-remote-em] listening for connections on #{url}")
Broker.run(opts[:broker_host] || ENV['PRYEMBROKER'] || DEF_BROKERHOST, opts[:broker_port] || ENV['PRYEMBROKERPORT'] || DEF_BROKERPORT, opts) do |broker|
broker.register(url, name)
rereg = EM::PeriodicTimer.new(15) do
EM.get_sockname(server) ? broker.register(url, name) : nil
end
end
url
end