nio4r-websocket 0.6.3 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.travis.yml +1 -3
- data/Gemfile +1 -1
- data/Rakefile +2 -2
- data/Vagrantfile +5 -5
- data/bin/console +3 -3
- data/lib/nio/websocket.rb +51 -20
- data/lib/nio/websocket/adapter.rb +12 -72
- data/lib/nio/websocket/adapter/client.rb +1 -1
- data/lib/nio/websocket/adapter/proxy.rb +38 -0
- data/lib/nio/websocket/adapter/server.rb +2 -2
- data/lib/nio/websocket/raw_adapter.rb +87 -0
- data/lib/nio/websocket/reactor.rb +4 -4
- data/lib/nio/websocket/version.rb +1 -1
- data/nio4r-websocket.gemspec +16 -16
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ef260d2997eba2db8dcff293dd847bc51488f477
|
4
|
+
data.tar.gz: 173b08a770153db1e35132edb4c438d530a5455e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a93ff5fafb1488c319b3cb5b1383639e6a5b47d856fda7dae9ab55cea2a42b46196aaa126061a3ca9f601346dc217d02036895d34d5f7bc415c18f970c3e7920
|
7
|
+
data.tar.gz: 07a552ff14074cd8211bbb47c9a7d493b1eefe0e591165a3439e97788ba2d39e8cbd835d4b799d0e3dbc000c86fcde642ae305f759ed3d7fc9ee554b67015ad1
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/Rakefile
CHANGED
data/Vagrantfile
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
Vagrant.configure(
|
2
|
-
config.vm.box =
|
3
|
-
config.vm.provider
|
4
|
-
vb.memory =
|
1
|
+
Vagrant.configure("2") do |config|
|
2
|
+
config.vm.box = "ubuntu/trusty64"
|
3
|
+
config.vm.provider "virtualbox" do |vb|
|
4
|
+
vb.memory = "512"
|
5
5
|
end
|
6
|
-
config.vm.provision
|
6
|
+
config.vm.provision "chef_apply" do |chef|
|
7
7
|
chef.recipe = <<-RECIPE
|
8
8
|
apt_update 'update' do
|
9
9
|
action :nothing
|
data/bin/console
CHANGED
data/lib/nio/websocket.rb
CHANGED
@@ -1,13 +1,14 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
1
|
+
require "nio/websocket/version"
|
2
|
+
require "websocket/driver"
|
3
|
+
require "nio"
|
4
|
+
require "socket"
|
5
|
+
require "uri"
|
6
|
+
require "openssl"
|
7
|
+
require "logger"
|
8
|
+
require "nio/websocket/reactor"
|
9
|
+
require "nio/websocket/adapter/client"
|
10
|
+
require "nio/websocket/adapter/server"
|
11
|
+
require "nio/websocket/adapter/proxy"
|
11
12
|
|
12
13
|
module NIO
|
13
14
|
module WebSocket
|
@@ -16,7 +17,7 @@ module NIO
|
|
16
17
|
# @return [Logger] the current logger instance
|
17
18
|
def logger
|
18
19
|
@logger ||= begin
|
19
|
-
logger = Logger.new(STDERR, progname:
|
20
|
+
logger = Logger.new(STDERR, progname: "WebSocket", level: Logger::ERROR)
|
20
21
|
logger.level = Logger::ERROR
|
21
22
|
logger
|
22
23
|
end
|
@@ -29,7 +30,6 @@ module NIO
|
|
29
30
|
def log_traffic=(enable)
|
30
31
|
@log_traffic = enable
|
31
32
|
logger.level = Logger::DEBUG if enable
|
32
|
-
enable
|
33
33
|
end
|
34
34
|
|
35
35
|
# Should raw traffic be logged through the logger? Disabled by default for security reasons
|
@@ -58,6 +58,36 @@ module NIO
|
|
58
58
|
adapter.driver
|
59
59
|
end
|
60
60
|
|
61
|
+
# Establish a proxy host listening on the given port and address, that marshalls all data to/from a new connection on remote
|
62
|
+
# @param [Hash] options
|
63
|
+
# @param remote [String] remote server in "hostname_or_ip:port" format
|
64
|
+
# @option options [Integer] :port required: Port on which to listen for incoming connections
|
65
|
+
# @option options [String] :address optional: Specific Address on which to bind the TCPServer
|
66
|
+
# @option options [Hash] :ssl_context Hash from which to create the OpenSSL::SSL::SSLContext object
|
67
|
+
# @yield [::WebSocket::Driver]
|
68
|
+
# @return server, as passed in, or a new TCPServer if no server was specified
|
69
|
+
def proxy(remote, options = {})
|
70
|
+
server = create_server(options)
|
71
|
+
host, port, extra = remote.split(":", 3)
|
72
|
+
raise "Specify the remote parameter in 'hostname_or_ip:port' format" if extra || port.to_i == 0 || host.empty?
|
73
|
+
Reactor.queue_task do
|
74
|
+
monitor = Reactor.selector.register(server, :r)
|
75
|
+
monitor.value = proc do
|
76
|
+
accept_socket server, options do |client|
|
77
|
+
srv = open_socket "tcp://#{remote}", options
|
78
|
+
adapter = PROXY_ADAPTER.new(srv, client, options)
|
79
|
+
Reactor.queue_task do
|
80
|
+
adapter.add_to_reactor
|
81
|
+
end
|
82
|
+
logger.info "Proxy connection established between #{srv} and #{client}"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
logger.info "Proxy Host listening for new connections on port " + options[:port].to_s
|
87
|
+
Reactor.start
|
88
|
+
server
|
89
|
+
end
|
90
|
+
|
61
91
|
# Start handling new connections, passing each through the supplied block
|
62
92
|
# @param [Hash] options
|
63
93
|
# @param server [TCPServer] (DI) TCPServer-like object to use in lieu of starting a new server
|
@@ -83,16 +113,17 @@ module NIO
|
|
83
113
|
end
|
84
114
|
end
|
85
115
|
Reactor.start
|
86
|
-
logger.info
|
116
|
+
logger.info "Host listening for new connections on port " + options[:port].to_s
|
87
117
|
server
|
88
118
|
end
|
89
119
|
|
90
120
|
SERVER_ADAPTER = NIO::WebSocket::Adapter::Server
|
91
121
|
CLIENT_ADAPTER = NIO::WebSocket::Adapter::Client
|
122
|
+
PROXY_ADAPTER = NIO::WebSocket::Adapter::Proxy
|
92
123
|
|
93
124
|
# Resets this API to a fresh state
|
94
125
|
def reset
|
95
|
-
logger.info
|
126
|
+
logger.info "Resetting reactor subsystem"
|
96
127
|
Reactor.reset
|
97
128
|
end
|
98
129
|
|
@@ -103,10 +134,10 @@ module NIO
|
|
103
134
|
# return an open socket given the url and options
|
104
135
|
def open_socket(url, options)
|
105
136
|
uri = URI(url)
|
106
|
-
port = uri.port || (uri.scheme ==
|
137
|
+
port = uri.port || (uri.scheme == "wss" ? 443 : 80) # redundant? test uri.port if port is unspecified but because ws: & wss: aren't default protocols we'll maybe still need this(?)
|
107
138
|
logger.debug "Opening Connection to #{uri.hostname} on port #{port}"
|
108
139
|
io = TCPSocket.new uri.hostname, port
|
109
|
-
return io unless uri.scheme ==
|
140
|
+
return io unless uri.scheme == "wss"
|
110
141
|
logger.debug "Upgrading Connection #{io} to ssl"
|
111
142
|
ssl = upgrade_to_ssl(io, options).connect
|
112
143
|
logger.info "Connection #{io} upgraded to #{ssl}"
|
@@ -121,7 +152,7 @@ module NIO
|
|
121
152
|
def accept_socket(server, options)
|
122
153
|
waiting = accept_nonblock server
|
123
154
|
if [:r, :w].include? waiting
|
124
|
-
logger.warn
|
155
|
+
logger.warn "Expected to receive new connection, but the server is not quite ready"
|
125
156
|
return
|
126
157
|
end
|
127
158
|
logger.debug "Receiving new connection #{waiting} on port #{options[:port]}"
|
@@ -157,11 +188,11 @@ module NIO
|
|
157
188
|
end
|
158
189
|
|
159
190
|
def accept_nonblock(io)
|
160
|
-
|
191
|
+
io.accept_nonblock
|
161
192
|
rescue IO::WaitReadable
|
162
|
-
|
193
|
+
:r
|
163
194
|
rescue IO::WaitWritable
|
164
|
-
|
195
|
+
:w
|
165
196
|
end
|
166
197
|
|
167
198
|
def upgrade_to_ssl(io, options)
|
@@ -1,12 +1,10 @@
|
|
1
|
+
require "nio/websocket/raw_adapter"
|
2
|
+
|
1
3
|
module NIO
|
2
4
|
module WebSocket
|
3
|
-
class Adapter
|
5
|
+
class Adapter < RawAdapter
|
4
6
|
def initialize(io, driver, options)
|
5
|
-
@inner = io
|
6
|
-
@options = options
|
7
7
|
@driver = driver
|
8
|
-
@buffer = ''
|
9
|
-
@mutex = Mutex.new
|
10
8
|
|
11
9
|
driver.on :close do |ev|
|
12
10
|
WebSocket.logger.info "Driver initiated #{inner} close (code #{ev.code}): #{ev.reason}"
|
@@ -16,85 +14,27 @@ module NIO
|
|
16
14
|
WebSocket.logger.error "Driver reports error on #{inner}: #{ev.message}"
|
17
15
|
close :driver
|
18
16
|
end
|
17
|
+
|
18
|
+
super io, options
|
19
19
|
end
|
20
|
-
attr_reader :
|
20
|
+
attr_reader :driver
|
21
21
|
|
22
22
|
def teardown
|
23
|
+
driver.force_state :closed
|
24
|
+
driver.emit :io_error
|
23
25
|
@driver = nil # circular reference
|
24
|
-
|
25
|
-
inner.close
|
26
|
+
super
|
26
27
|
end
|
27
28
|
|
28
29
|
def close(from = nil)
|
29
|
-
|
30
|
-
|
31
|
-
driver.close if from.nil?
|
32
|
-
@closing = true
|
33
|
-
monitor.interests = :rw
|
34
|
-
Reactor.selector.wakeup
|
35
|
-
true
|
36
|
-
end
|
37
|
-
|
38
|
-
def add_to_reactor
|
39
|
-
@monitor = Reactor.selector.register(inner, :rw) # This can block if this is the main thread and the reactor is busy
|
40
|
-
monitor.value = proc do
|
41
|
-
begin
|
42
|
-
read if monitor.readable?
|
43
|
-
pump_buffer if monitor.writable?
|
44
|
-
rescue Errno::ECONNRESET, EOFError, Errno::ECONNABORTED
|
45
|
-
driver.force_state :closed
|
46
|
-
driver.emit :io_error
|
47
|
-
teardown
|
48
|
-
WebSocket.logger.info "#{inner} socket closed"
|
49
|
-
rescue IO::WaitReadable # rubocop:disable Lint/HandleExceptions
|
50
|
-
rescue IO::WaitWritable
|
51
|
-
monitor.interests = :rw
|
52
|
-
end
|
53
|
-
if @closing
|
54
|
-
if !monitor.readable? && @buffer.empty?
|
55
|
-
teardown
|
56
|
-
WebSocket.logger.info "#{inner} closed"
|
57
|
-
else
|
58
|
-
monitor.interests = :rw unless monitor.closed? # keep the :w interest so that our block runs each time
|
59
|
-
# edge case: if monitor was readable this time, and the write buffer is empty, if we emptied the read buffer this time our block wouldn't run again
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
30
|
+
driver.close if from.nil? && !closing
|
31
|
+
super()
|
63
32
|
end
|
64
33
|
|
65
34
|
def read
|
66
|
-
|
67
|
-
if data
|
68
|
-
WebSocket.logger.debug { "Incoming data on #{inner}:\n#{data}" } if WebSocket.log_traffic?
|
35
|
+
super do |data|
|
69
36
|
driver.parse data
|
70
37
|
end
|
71
|
-
data
|
72
|
-
end
|
73
|
-
|
74
|
-
def write(data)
|
75
|
-
@mutex.synchronize do
|
76
|
-
@buffer << data
|
77
|
-
end
|
78
|
-
return unless monitor
|
79
|
-
pump_buffer
|
80
|
-
Reactor.selector.wakeup unless monitor.interests == :r
|
81
|
-
end
|
82
|
-
|
83
|
-
def pump_buffer
|
84
|
-
@mutex.synchronize do
|
85
|
-
written = 0
|
86
|
-
begin
|
87
|
-
written = inner.write_nonblock @buffer unless @buffer.empty?
|
88
|
-
WebSocket.logger.debug { "Pumped #{written} bytes of data from buffer to #{inner}:\n#{@buffer}" } unless @buffer.empty? || !WebSocket.log_traffic?
|
89
|
-
@buffer = @buffer.byteslice(written..-1) if written > 0
|
90
|
-
WebSocket.logger.debug { "The buffer is now:\n#{@buffer}" } unless @buffer.empty? || !WebSocket.log_traffic?
|
91
|
-
rescue IO::WaitWritable, IO::WaitReadable
|
92
|
-
return written
|
93
|
-
ensure
|
94
|
-
monitor.interests = @buffer.empty? ? :r : :rw
|
95
|
-
end
|
96
|
-
written
|
97
|
-
end
|
98
38
|
end
|
99
39
|
end
|
100
40
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require "nio/websocket/raw_adapter"
|
2
|
+
|
3
|
+
module NIO
|
4
|
+
module WebSocket
|
5
|
+
class Adapter
|
6
|
+
class Proxy
|
7
|
+
def initialize(srv, client, options)
|
8
|
+
@srv_adapter = ProxyAdapter.new srv, options do |data|
|
9
|
+
client_adapter.write data
|
10
|
+
end
|
11
|
+
@client_adapter = ProxyAdapter.new client, options do |data|
|
12
|
+
srv_adapter.write data
|
13
|
+
end
|
14
|
+
WebSocket.logger.debug "Initiating proxy connection between #{srv} and #{client}"
|
15
|
+
end
|
16
|
+
attr_reader :srv_adapter, :client_adapter
|
17
|
+
|
18
|
+
def add_to_reactor
|
19
|
+
srv_adapter.add_to_reactor
|
20
|
+
client_adapter.add_to_reactor
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class ProxyAdapter < RawAdapter
|
25
|
+
def initialize(io, options, &block)
|
26
|
+
super io, options
|
27
|
+
@read_event = block
|
28
|
+
end
|
29
|
+
|
30
|
+
def read
|
31
|
+
super do |data|
|
32
|
+
@read_event.call data
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "nio/websocket/adapter"
|
2
2
|
|
3
3
|
module NIO
|
4
4
|
module WebSocket
|
@@ -9,7 +9,7 @@ module NIO
|
|
9
9
|
driver.on :connect do
|
10
10
|
if ::WebSocket::Driver.websocket? driver.env
|
11
11
|
driver.start
|
12
|
-
WebSocket.logger.debug
|
12
|
+
WebSocket.logger.debug "driver connected"
|
13
13
|
end
|
14
14
|
end
|
15
15
|
super io, driver, options
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module NIO
|
2
|
+
module WebSocket
|
3
|
+
class RawAdapter
|
4
|
+
def initialize(io, options)
|
5
|
+
@inner = io
|
6
|
+
@options = options
|
7
|
+
@buffer = ""
|
8
|
+
@mutex = Mutex.new
|
9
|
+
end
|
10
|
+
attr_reader :inner, :options, :monitor, :closing
|
11
|
+
|
12
|
+
def teardown
|
13
|
+
monitor.close
|
14
|
+
inner.close
|
15
|
+
end
|
16
|
+
|
17
|
+
def close
|
18
|
+
return false if @closing
|
19
|
+
|
20
|
+
@closing = true
|
21
|
+
monitor.interests = :rw
|
22
|
+
Reactor.selector.wakeup
|
23
|
+
true
|
24
|
+
end
|
25
|
+
|
26
|
+
def add_to_reactor
|
27
|
+
@monitor = Reactor.selector.register(inner, :rw) # This can block if this is the main thread and the reactor is busy
|
28
|
+
monitor.value = proc do
|
29
|
+
begin
|
30
|
+
read if monitor.readable?
|
31
|
+
pump_buffer if monitor.writable?
|
32
|
+
rescue Errno::ECONNRESET, EOFError, Errno::ECONNABORTED
|
33
|
+
teardown
|
34
|
+
WebSocket.logger.info "#{inner} socket closed"
|
35
|
+
rescue IO::WaitReadable # rubocop:disable Lint/HandleExceptions
|
36
|
+
rescue IO::WaitWritable
|
37
|
+
monitor.interests = :rw
|
38
|
+
end
|
39
|
+
if @closing
|
40
|
+
if !monitor.readable? && @buffer.empty?
|
41
|
+
teardown
|
42
|
+
WebSocket.logger.info "#{inner} closed"
|
43
|
+
else
|
44
|
+
monitor.interests = :rw unless monitor.closed? # keep the :w interest so that our block runs each time
|
45
|
+
# edge case: if monitor was readable this time, and the write buffer is empty, if we emptied the read buffer this time our block wouldn't run again
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def read
|
52
|
+
data = inner.read_nonblock(16384)
|
53
|
+
if data
|
54
|
+
WebSocket.logger.debug { "Incoming data on #{inner}:\n#{data}" } if WebSocket.log_traffic?
|
55
|
+
yield data if block_given?
|
56
|
+
end
|
57
|
+
data
|
58
|
+
end
|
59
|
+
|
60
|
+
def write(data)
|
61
|
+
@mutex.synchronize do
|
62
|
+
@buffer << data
|
63
|
+
end
|
64
|
+
return unless monitor
|
65
|
+
pump_buffer
|
66
|
+
Reactor.selector.wakeup unless monitor.interests == :r
|
67
|
+
end
|
68
|
+
|
69
|
+
def pump_buffer
|
70
|
+
@mutex.synchronize do
|
71
|
+
written = 0
|
72
|
+
begin
|
73
|
+
written = inner.write_nonblock @buffer unless @buffer.empty?
|
74
|
+
WebSocket.logger.debug { "Pumped #{written} bytes of data from buffer to #{inner}:\n#{@buffer}" } unless @buffer.empty? || !WebSocket.log_traffic?
|
75
|
+
@buffer = @buffer.byteslice(written..-1) if written > 0
|
76
|
+
WebSocket.logger.debug { "The buffer is now:\n#{@buffer}" } unless @buffer.empty? || !WebSocket.log_traffic?
|
77
|
+
rescue IO::WaitWritable, IO::WaitReadable
|
78
|
+
return written
|
79
|
+
ensure
|
80
|
+
monitor.interests = @buffer.empty? ? :r : :rw
|
81
|
+
end
|
82
|
+
written
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "nio"
|
2
2
|
|
3
3
|
module NIO
|
4
4
|
module WebSocket
|
@@ -26,10 +26,10 @@ module NIO
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def start
|
29
|
-
WebSocket.logger.debug
|
29
|
+
WebSocket.logger.debug "Starting reactor" unless @reactor
|
30
30
|
@reactor ||= Thread.start do
|
31
31
|
Thread.current.abort_on_exception = true
|
32
|
-
WebSocket.logger.info
|
32
|
+
WebSocket.logger.info "Reactor started"
|
33
33
|
begin
|
34
34
|
loop do
|
35
35
|
queue = []
|
@@ -53,7 +53,7 @@ module NIO
|
|
53
53
|
Thread.pass # give other threads a chance at manipulating our selector (e.g. a new connection on the main thread trying to register)
|
54
54
|
end
|
55
55
|
rescue => e
|
56
|
-
WebSocket.logger.fatal
|
56
|
+
WebSocket.logger.fatal "Error occured in reactor subsystem."
|
57
57
|
WebSocket.logger.fatal "#{e.class}: #{e.message}"
|
58
58
|
e.backtrace.map { |s| WebSocket.logger.fatal "\t#{s}" }
|
59
59
|
raise
|
data/nio4r-websocket.gemspec
CHANGED
@@ -1,30 +1,30 @@
|
|
1
1
|
# coding: utf-8
|
2
|
-
lib = File.expand_path(
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
4
|
+
require "nio/websocket/version"
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
7
|
+
spec.name = "nio4r-websocket"
|
8
8
|
spec.version = NIO::WebSocket::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
9
|
+
spec.authors = ["Sean Zachariasen"]
|
10
|
+
spec.email = ["thewyzard@hotmail.com"]
|
11
11
|
|
12
|
-
spec.summary =
|
13
|
-
spec.homepage =
|
14
|
-
spec.license =
|
12
|
+
spec.summary = "websocket-driver implementation built over nio4r"
|
13
|
+
spec.homepage = "https://github.com/nexussw/nio4r-websocket"
|
14
|
+
spec.license = "MIT"
|
15
15
|
|
16
16
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
17
17
|
f.match(%r{^(test|spec|features)/})
|
18
18
|
end
|
19
|
-
spec.bindir =
|
19
|
+
spec.bindir = "exe"
|
20
20
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
|
-
spec.require_paths = [
|
21
|
+
spec.require_paths = ["lib"]
|
22
22
|
|
23
|
-
spec.add_dependency
|
24
|
-
spec.add_dependency
|
23
|
+
spec.add_dependency "nio4r", ">= 1.2.1", "< 3.0" # Allow older nio4r, if possible, so as to not lock our ruby version to 2.2.2
|
24
|
+
spec.add_dependency "websocket-driver", "~> 0.6"
|
25
25
|
|
26
|
-
spec.add_development_dependency
|
27
|
-
spec.add_development_dependency
|
28
|
-
spec.add_development_dependency
|
29
|
-
spec.add_development_dependency
|
26
|
+
spec.add_development_dependency "bundler"
|
27
|
+
spec.add_development_dependency "rake"
|
28
|
+
spec.add_development_dependency "rspec"
|
29
|
+
spec.add_development_dependency "simplecov"
|
30
30
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nio4r-websocket
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sean Zachariasen
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-01-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nio4r
|
@@ -120,7 +120,9 @@ files:
|
|
120
120
|
- lib/nio/websocket.rb
|
121
121
|
- lib/nio/websocket/adapter.rb
|
122
122
|
- lib/nio/websocket/adapter/client.rb
|
123
|
+
- lib/nio/websocket/adapter/proxy.rb
|
123
124
|
- lib/nio/websocket/adapter/server.rb
|
125
|
+
- lib/nio/websocket/raw_adapter.rb
|
124
126
|
- lib/nio/websocket/reactor.rb
|
125
127
|
- lib/nio/websocket/version.rb
|
126
128
|
- nio4r-websocket.gemspec
|
@@ -144,7 +146,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
144
146
|
version: '0'
|
145
147
|
requirements: []
|
146
148
|
rubyforge_project:
|
147
|
-
rubygems_version: 2.
|
149
|
+
rubygems_version: 2.6.14
|
148
150
|
signing_key:
|
149
151
|
specification_version: 4
|
150
152
|
summary: websocket-driver implementation built over nio4r
|