Module: NIO::WebSocket

Defined in:
lib/nio/websocket.rb,
lib/nio/websocket/adapter.rb,
lib/nio/websocket/reactor.rb,
lib/nio/websocket/version.rb,
lib/nio/websocket/raw_adapter.rb,
lib/nio/websocket/adapter/proxy.rb,
lib/nio/websocket/adapter/client.rb,
lib/nio/websocket/adapter/server.rb

Defined Under Namespace

Classes: Adapter, RawAdapter, Reactor

Constant Summary collapse

SERVER_ADAPTER =
NIO::WebSocket::Adapter::Server
CLIENT_ADAPTER =
NIO::WebSocket::Adapter::Client
PROXY_ADAPTER =
NIO::WebSocket::Adapter::Proxy
VERSION =
"0.7.0".freeze

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.loggerLogger

Returns the current logger, or creates one at level ERROR if one has not been assigned

Returns:

  • (Logger)

    the current logger instance



18
19
20
21
22
23
24
# File 'lib/nio/websocket.rb', line 18

def logger
  @logger ||= begin
  logger = Logger.new(STDERR, progname: "WebSocket", level: Logger::ERROR)
  logger.level = Logger::ERROR
  logger
end
end

Class Method Details

.connect(url, options = {}, io = nil) {|::WebSocket::Driver| ... } ⇒ ::WebSocket::Driver

Create and return a websocket client that communicates either over the given IO object (upgrades the connection), or we’ll create a new connection to url if io is not supplied

Parameters:

  • url (String)

    ws:// or wss:// location to connect

  • options (Hash) (defaults to: {})
  • io (IO) (defaults to: nil)

    (DI) raw IO object to use in lieu of opening a new connection to url

Options Hash (options):

  • :websocket_options (Hash)

    Hash to pass to the ::WebSocket::Driver.client

  • :ssl_context (Hash)

    Hash from which to create the OpenSSL::SSL::SSLContext object

Yields:

Returns:



49
50
51
52
53
54
55
56
57
58
59
# File 'lib/nio/websocket.rb', line 49

def connect(url, options = {}, io = nil)
  io ||= open_socket(url, options)
  adapter = CLIENT_ADAPTER.new(url, io, options)
  yield(adapter.driver, adapter) if block_given?
  Reactor.queue_task do
    adapter.add_to_reactor
  end
  Reactor.start
  logger.info "Client #{io} connected to #{url}"
  adapter.driver
end

.listen(options = {}, server = nil) {|::WebSocket::Driver| ... } ⇒ Object

Start handling new connections, passing each through the supplied block

Parameters:

  • options (Hash) (defaults to: {})
  • server (TCPServer) (defaults to: nil)

    (DI) TCPServer-like object to use in lieu of starting a new server

Options Hash (options):

  • :port (Integer)

    required: Port on which to listen for incoming connections

  • :address (String)

    optional: Specific Address on which to bind the TCPServer

  • :websocket_options (Hash)

    Hash to pass to the ::WebSocket::Driver.server

  • :ssl_context (Hash)

    Hash from which to create the OpenSSL::SSL::SSLContext object

Yields:

Returns:

  • server, as passed in, or a new TCPServer if no server was specified



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/nio/websocket.rb', line 100

def listen(options = {}, server = nil)
  server ||= create_server(options)
  Reactor.queue_task do
    monitor = Reactor.selector.register(server, :r)
    monitor.value = proc do
      accept_socket server, options do |io| # this next block won't run until ssl (if enabled) has started
        adapter = SERVER_ADAPTER.new(io, options)
        yield(adapter.driver, adapter) if block_given?
        Reactor.queue_task do
          adapter.add_to_reactor
        end
        logger.info "Host accepted client connection #{io} on port #{options[:port]}"
      end
    end
  end
  Reactor.start
  logger.info "Host listening for new connections on port " + options[:port].to_s
  server
end

.log_traffic=(enable) ⇒ Object

Should raw traffic be logged through the logger? Disabled by default for security reasons

Parameters:

  • enable (Boolean)


30
31
32
33
# File 'lib/nio/websocket.rb', line 30

def log_traffic=(enable)
  @log_traffic = enable
  logger.level = Logger::DEBUG if enable
end

.log_traffic?Boolean

Should raw traffic be logged through the logger? Disabled by default for security reasons

Returns:

  • (Boolean)


36
37
38
# File 'lib/nio/websocket.rb', line 36

def log_traffic?
  @log_traffic
end

.proxy(remote, options = {}) {|::WebSocket::Driver| ... } ⇒ Object

Establish a proxy host listening on the given port and address, that marshalls all data to/from a new connection on remote

Parameters:

  • options (Hash) (defaults to: {})
  • remote (String)

    remote server in “hostname_or_ip:port” format

Options Hash (options):

  • :port (Integer)

    required: Port on which to listen for incoming connections

  • :address (String)

    optional: Specific Address on which to bind the TCPServer

  • :ssl_context (Hash)

    Hash from which to create the OpenSSL::SSL::SSLContext object

Yields:

Returns:

  • server, as passed in, or a new TCPServer if no server was specified



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/nio/websocket.rb', line 69

def proxy(remote, options = {})
  server = create_server(options)
  host, port, extra = remote.split(":", 3)
  raise "Specify the remote parameter in 'hostname_or_ip:port' format" if extra || port.to_i == 0 || host.empty?
  Reactor.queue_task do
    monitor = Reactor.selector.register(server, :r)
    monitor.value = proc do
      accept_socket server, options do |client|
        srv = open_socket "tcp://#{remote}", options
        adapter = PROXY_ADAPTER.new(srv, client, options)
        Reactor.queue_task do
          adapter.add_to_reactor
        end
        logger.info "Proxy connection established between #{srv} and #{client}"
      end
    end
  end
  logger.info "Proxy Host listening for new connections on port " + options[:port].to_s
  Reactor.start
  server
end

.resetObject

Resets this API to a fresh state



125
126
127
128
# File 'lib/nio/websocket.rb', line 125

def reset
  logger.info "Resetting reactor subsystem"
  Reactor.reset
end