def connect(routing_keys, &handler)
      raise ArgumentError, "Block missing" unless block_given?

      @attempted_connect_at = Time.now
      @close_code = @close_reason = nil

      # Initialize use of proxy if defined
      if (v = BalancedHttpClient::PROXY_ENVIRONMENT_VARIABLES.detect { |v| ENV.has_key?(v) })
        proxy_uri = ENV[v].match(/^[[:alpha:]]+:\/\//) ? URI.parse(ENV[v]) : URI.parse("http://" + ENV[v])
        @proxy = { :origin => proxy_uri.to_s }
      end

      options = {
        # Limit to .auth_header here (rather than .headers) to keep WebSockets happy
        :headers => {"X-API-Version" => API_VERSION}.merge(@auth_client.auth_header),
        :ping => @options[:listen_timeout] }

      options[:proxy] = @proxy if @proxy

      url = URI.parse(@auth_client.router_url)
      url.scheme = url.scheme == "https" ? "wss" : "ws"
      url.path = url.path + "/connect"
      url.query = routing_keys.map { |k| "routing_keys[]=#{CGI.escape(k)}" }.join("&") if routing_keys && routing_keys.any?
      Log.info("Creating WebSocket connection to #{url.to_s}")
      @websocket = Faye::WebSocket::Client.new(url.to_s, protocols = nil, options)

      @websocket.onerror = lambda do |event|
        error = if event.respond_to?(:data)
          # faye-websocket 0.7.0
          event.data
        elsif event.respond_to?(:message)
          # faye-websocket 0.7.4
          event.message
        else
          event.to_s
        end
        ErrorTracker.log(self, "WebSocket error (#{error})") if error
      end

      @websocket.onclose = lambda do |event|
        begin
          @close_code = event.code.to_i
          @close_reason = event.reason
          msg = "WebSocket closed (#{event.code}"
          msg << ((event.reason.nil? || event.reason.empty?) ? ")" : ": #{event.reason})")
          Log.info(msg)
        rescue Exception => e
          ErrorTracker.log(self, "Failed closing WebSocket", e)
        end
        @websocket = nil
      end

      @websocket.onmessage = lambda do |event|
        begin
          # Receive event
          event = SerializationHelper.symbolize_keys(JSON.parser.new(event.data, JSON.load_default_options).parse)
          Log.info("Received EVENT <#{event[:uuid]}> #{event[:type]} #{event[:path]} from #{event[:from]}")
          @stats["events"].update("#{event[:type]} #{event[:path]}")

          # Acknowledge event
          @websocket.send(JSON.dump({:ack => event[:uuid]}))

          # Handle event
          handler.call(event)
          @communicated_callbacks.each { |callback| callback.call } if @communicated_callbacks
        rescue Exception => e
          ErrorTracker.log(self, "Failed handling WebSocket event", e)
        end
      end

      @websocket
    end
def connect(routing_keys, &handler)
      raise ArgumentError, "Block missing" unless block_given?

      @attempted_connect_at = Time.now
      @close_code = @close_reason = nil

      # Initialize use of proxy if defined
      if (v = BalancedHttpClient::PROXY_ENVIRONMENT_VARIABLES.detect { |v| ENV.has_key?(v) })
        proxy_uri = ENV[v].match(/^[[:alpha:]]+:\/\//) ? URI.parse(ENV[v]) : URI.parse("http://" + ENV[v])
        @proxy = { :origin => proxy_uri.to_s }
      end

      options = {
        # Limit to .auth_header here (rather than .headers) to keep WebSockets happy
        :headers => {"X-API-Version" => API_VERSION}.merge(@auth_client.auth_header),
        :ping => @options[:listen_timeout] }

      options[:proxy] = @proxy if @proxy

      url = URI.parse(@auth_client.router_url)
      url.scheme = url.scheme == "https" ? "wss" : "ws"
      url.path = url.path + "/connect"
      url.query = routing_keys.map { |k| "routing_keys[]=#{CGI.escape(k)}" }.join("&") if routing_keys && routing_keys.any?
      Log.info("Creating WebSocket connection to #{url.to_s}")
      @websocket = Faye::WebSocket::Client.new(url.to_s, protocols = nil, options)

      @websocket.onerror = lambda do |event|
        error = if event.respond_to?(:data)
          # faye-websocket 0.7.0
          event.data
        elsif event.respond_to?(:message)
          # faye-websocket 0.7.4
          event.message
        else
          event.to_s
        end
        ErrorTracker.log(self, "WebSocket error (#{error})") if error
      end

      @websocket.onclose = lambda do |event|
        begin
          @close_code = event.code.to_i
          @close_reason = event.reason
          msg = "WebSocket closed (#{event.code}"
          msg << ((event.reason.nil? || event.reason.empty?) ? ")" : ": #{event.reason})")
          Log.info(msg)
        rescue Exception => e
          ErrorTracker.log(self, "Failed closing WebSocket", e)
        end
        @websocket = nil
      end

      @websocket.onmessage = lambda do |event|
        begin
          # Receive event
          event = SerializationHelper.symbolize_keys(JSON.parser.new(event.data, JSON.load_default_options).parse)
          Log.info("Received EVENT <#{event[:uuid]}> #{event[:type]} #{event[:path]} from #{event[:from]}")
          @stats["events"].update("#{event[:type]} #{event[:path]}")

          # Acknowledge event
          @websocket.send(JSON.dump({:ack => event[:uuid]}))

          # Handle event
          handler.call(event)
          @communicated_callbacks.each { |callback| callback.call } if @communicated_callbacks
        rescue Exception => e
          ErrorTracker.log(self, "Failed handling WebSocket event", e)
        end
      end

      @websocket
    end
Connect to RightNet router using WebSocket for receiving events

 @param [Array, NilClass] routing_keys as strings to assist router in delivering
   event to interested parties

 @yield [event] required block called when event received
 @yieldparam [Object] event received
 @yieldreturn [Hash, NilClass] event this is response to event received,
   or nil meaning no response

 @return [Faye::WebSocket] WebSocket created

 @raise [ArgumentError] block missing