Module: WebSocket

Defined in:
lib/websocket/config.rb,
lib/websocket/server.rb,
lib/websocket_client.rb,
lib/websocket_client.rb,
lib/websocket_client.rb,
lib/websocket_client.rb,
lib/websocket_client.rb,
lib/websocket_client.rb,
lib/websocket_client.rb,
lib/websocket_client.rb,
lib/websocket_client.rb,
lib/websocket_client.rb,
lib/websocket_server.rb,
lib/websocket/version.rb,
lib/websocket/encoding.rb,
lib/websocket/listenable.rb,
lib/websocket/idle_handler.rb,
lib/websocket/telnet_proxy.rb,
lib/websocket/frame_handler.rb,
lib/websocket/shutdown_hook.rb,
lib/websocket/header_helpers.rb,
lib/websocket/message_handler.rb,
lib/websocket/arguments_parser.rb,
lib/websocket/instance_methods.rb,
lib/websocket/response_helpers.rb,
lib/websocket/validation_helpers.rb,
lib/websocket/channel_initializer.rb,
lib/websocket/ssl_cipher_inspector.rb,
lib/websocket/ssl_context_initialization.rb,
lib/websocket/idle_state_user_event_handler.rb,
lib/websocket/http_static_file_server_handler.rb,
lib/websocket/file_server_channel_progressive_future_listener.rb,
lib/websocket/http_static_file_server_handler_instance_methods.rb

Overview

The WebSocket module

Defined Under Namespace

Modules: ClientInitializationMethods, ClientInstanceMethods, HeaderHelpers, HttpStaticFileServerHandlerInstanceMethods, InstanceMethods, Listenable, ResponseHelpers, SslContextInitializationMethods, ValidationHelpers Classes: ArgumentsParser, ChannelInitializer, Client, ClientChannelHandler, ClientChannelInitializer, FileServerChannelProgressiveFutureListener, FrameHandler, HttpStaticFileServerHandler, IdleHandler, IdleStateUserEventHandler, MessageHandler, Server, ShutdownHook, SslCipherInspector, TelnetProxy

Constant Summary collapse

WEBSOCKET_SUBMODULE_DIR_PATH =
File.expand_path(__dir__)
LIB_DIR_PATH =
File.expand_path(File.dirname(WEBSOCKET_SUBMODULE_DIR_PATH))
PROJECT_DIR_PATH =
File.expand_path(File.dirname(LIB_DIR_PATH))
DEFAULT_LOG_LEVEL =
Logger::INFO
DEFAULT_HOSTNAME =
'0.0.0.0'.freeze
DEFAULT_PORT =
4000
DEFAULT_SSL_PORT =
443
DEFAULT_TELNET_PROXY_HOST =
nil
DEFAULT_TELNET_PROXY_PORT =
21
DEFAULT_KEEP_ALIVE =
true
DEFAULT_MAX_QUEUED_INCOMING_CONNECTIONS =
100
DEFAULT_IDLE_READING_SECONDS =

seconds

5 * 60
DEFAULT_IDLE_WRITING_SECONDS =

seconds

30
DEFAULT_SSL_ENABLED =
false
DEFAULT_SSL_CERTIFICATE_FILE_PATH =
File.join(PROJECT_DIR_PATH, 'fullchain.pem')
DEFAULT_SSL_PRIVATE_KEY_FILE_PATH =

openssl pkcs8 -topk8 -nocrypt -in websocket.key -out websocket_pcks8

The privkey.key file here should be generated using the following openssl command:

openssl pkcs8 -topk8 -inform PEM -outform DER -in privkey.pem -nocrypt > privkey.key
File.join(PROJECT_DIR_PATH, 'privkey.key')
DEFAULT_SSL_INSPECTION_ENABLED =
false
DEFAULT_WEB_SOCKET_PATH =
'/websocket'.freeze
DEFAULT_WEB_DIR =
'web'.freeze
DEFAULT_WEB_ROOT =
File.join(PROJECT_DIR_PATH, DEFAULT_WEB_DIR)
DEFAULT_INDEX_PAGE =
'index.html'.freeze
DEFAULT_PING_MESSAGE =
"ping\n".freeze
DEFAULT_HTTP_DATE_FORMAT =

EEE, dd MMM yyyy HH:mm:ss zzz

'%a, %d %b %Y %H:%M:%S %Z'.freeze
DEFAULT_HTTP_DATE_GMT_TIMEZONE =
'GMT'.freeze
DEFAULT_CACHE_SECONDS =

seconds

60
DEFAULT_INSECURE_URI_PATTERN =
%r{.*[<>&"].*}
DEFAULT_LOG_REQUESTS =
false
SUPPORTED_SCHEMES =
%w[ws wss].freeze
CHANNEL_TYPE =
Java::io.netty.channel.socket.nio.NioSocketChannel.java_class
PING_MSG_CONTENT =
[8, 1, 8, 1].to_java(:byte)
UNEXPECTED_FULL_RESPONSE_ERROR =
'Unexpected FullHttpResponse (getStatus=%<status>s, content=%<content>s)'.freeze
VERSION =
'1.2.0'.freeze
Encoding =
CharsetUtil::UTF_8
HtmlContentType =
"text/html; charset=#{Encoding.name}".freeze
PingMessage =

The PingMessage class is just a convenient alias for the PingWebSocketFrame class.

Class.new(PingWebSocketFrame)

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.client_configObject

rubocop: disable Metrics/AbcSize



27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/websocket_client.rb', line 27

def client_config
  @client_config ||= {
    log_level: Logger::INFO,
    uri: java.net.URI.new('ws://127.0.0.1:4000/websocket'),
    # Connect with V13 (RFC 6455 aka HyBi-17). You can change it to V08 or V00.
    # If you change it to V00, ping is not supported and remember to change
    # HttpResponseDecoder to WebSocketHttpResponseDecoder in the pipeline.
    websocket_version: Java::io.netty.handler.codec.http.websocketx.WebSocketVersion::V13,
    subprotocol: nil,
    allow_extensions: true,
    default_headers: Java::io.netty.handler.codec.http.DefaultHttpHeaders.new,
    prompt: '>'
  }
end

.server_configObject

rubocop: disable Metrics/MethodLength



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/websocket/config.rb', line 54

def server_config
  @server_config ||= {
    log_level: DEFAULT_LOG_LEVEL,
    host: DEFAULT_HOSTNAME,
    port: DEFAULT_PORT,
    ssl_port: DEFAULT_SSL_PORT,
    telnet_proxy_host: DEFAULT_TELNET_PROXY_HOST,
    telnet_proxy_port: DEFAULT_TELNET_PROXY_PORT,
    ssl: DEFAULT_SSL_ENABLED,
    ssl_certificate_file_path: DEFAULT_SSL_CERTIFICATE_FILE_PATH,
    ssl_private_key_file_path: DEFAULT_SSL_PRIVATE_KEY_FILE_PATH,
    use_jdk_ssl_provider: false,
    inspect_ssl: DEFAULT_SSL_INSPECTION_ENABLED,
    idle_reading: DEFAULT_IDLE_READING_SECONDS,
    idle_writing: DEFAULT_IDLE_WRITING_SECONDS,
    keep_alive: DEFAULT_KEEP_ALIVE,
    max_queued_incoming_connections: DEFAULT_MAX_QUEUED_INCOMING_CONNECTIONS,
    index_page: DEFAULT_INDEX_PAGE,
    web_root: DEFAULT_WEB_ROOT,
    web_socket_path: DEFAULT_WEB_SOCKET_PATH,
    ping_message: DEFAULT_PING_MESSAGE,
    http_date_format: DEFAULT_HTTP_DATE_FORMAT,
    http_date_gmt_timezone: DEFAULT_HTTP_DATE_GMT_TIMEZONE,
    http_cache_seconds: DEFAULT_CACHE_SECONDS,
    insecure_uri_pattern: DEFAULT_INSECURE_URI_PATTERN,
    log_requests: DEFAULT_LOG_REQUESTS
  }
end

Instance Method Details

#echo_server(options) ⇒ Object



24
25
26
27
28
# File 'lib/websocket_server.rb', line 24

def echo_server(options)
  ::WebSocket::Server.new(options) do |_ctx, msg|
    format("%<message>s\n", message: msg.upcase)
  end.run
end

#main(args = parse_arguments) ⇒ Object

rubocop: disable Metrics/AbcSize



36
37
38
39
40
41
42
43
44
45
46
# File 'lib/websocket_server.rb', line 36

def main(args = parse_arguments)
  Logging.log_level = args[:log_level]
  ::WebSocket::Client.new(args)
rescue Interrupt => e
  warn "\n#{e.class}"
  exit
rescue StandardError => e
  ::WebSocket::Client.log.fatal "Unexpected error: #{e.class}: #{e.message}"
  e.backtrace.each { |t| log.debug t } if Logging.log_level == Logger::DEBUG
  exit 1
end

#parse_arguments(arguments_parser = WebSocket::ArgumentsParser.new) ⇒ Object

rubocop: enable Metrics/ClassLength class ArgumentsParser



489
490
491
492
493
494
495
496
497
498
499
500
# File 'lib/websocket_client.rb', line 489

def parse_arguments(arguments_parser = ArgumentsParser.new)
  arguments_parser.parser.parse!(ARGV)
  arguments_parser.parse_positional_arguments!
  arguments_parser.options
rescue OptionParser::InvalidArgument, OptionParser::InvalidOption,
       OptionParser::MissingArgument, OptionParser::NeedlessArgument => e
  puts e.message
  puts parser
  exit
rescue OptionParser::AmbiguousOption => e
  abort e.message
end

#telnet_proxy(options) ⇒ Object



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

def telnet_proxy(options)
  handler = ::WebSocket::TelnetProxy.new(options[:telnet_proxy_host], options[:telnet_proxy_port])
  ::WebSocket::Server.new(options, handler).run
end