tcp-server 1.2.0-java → 1.4.1-java

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e929584365fe9f6f2f5acd5730590308d9ccf84b7cafc7cb611fe80290014891
4
- data.tar.gz: bd0148f3ebe104cc69dd4ed9f37dd68733c3a9e9dcca711184a5dc5e940005b8
3
+ metadata.gz: 18fc53639397d26d2a0b3755610853697649175288c8288ae0ee7c0b8205eac6
4
+ data.tar.gz: af583ff89a4eaf27a809a1469df1c5950a470584f588a9e7c83dd51a38ba4147
5
5
  SHA512:
6
- metadata.gz: 6260d608a17649fe1114e0e9382398e56297a9430ac9755c516578317d2e691fde6063e096847fc9f24e5d9ce8d34b940bf1a798433e19cb736be8ad1d956ca1
7
- data.tar.gz: 28e72cd37f04f4a958c638841a8742e13f991c89e91977c9298978695c8801eb29d1ca6c8a71e28ac7e6d3aea37c4022c4998e8a1fe1d308111bf0f0b7162e49
6
+ metadata.gz: c4fb9fbb2b7edf7fecb14dca462e9f832e6dedd998e0789a4a28f71bf7845caf2ea2721c6d5cddec8d6e2fe0ab636602311b3ce7ff134a6c3b886eace2818760
7
+ data.tar.gz: f466bc6d5c711d5853adb46805ea9c895a85e2ccbd7b5f5f8006de4a3938e111a5756d690c50db01b2029a710f204f48eb70f595777283746262d0b24d7e7f5d
data/README.md CHANGED
@@ -18,9 +18,10 @@ You may run the websocket server in a container. Using `[colima]` for a containe
18
18
 
19
19
  ```sh
20
20
  colima start
21
- docker-compose up --detach
21
+ docker build --tag tcp-server-jruby .
22
+ docker compose up --detach
22
23
  nc localhost 4000
23
- docker-compose down
24
+ docker compose down
24
25
  ```
25
26
 
26
27
  Building the image or running the container:
@@ -45,7 +46,6 @@ See: https://mise.jdx.dev/getting-started.html
45
46
  ```sh
46
47
  curl https://mise.jdx.dev/install.sh | sh
47
48
  ~/.local/bin/mise --version
48
- mise 2024.x.x
49
49
  ```
50
50
 
51
51
  Enable mise activation in future zsh sessions.
@@ -75,10 +75,10 @@ bundle install
75
75
 
76
76
  ## Run
77
77
 
78
- The entrypoint for the web application service may now be invoked from a command line interface terminal shell.
78
+ The entrypoint for the TCP server may now be invoked from a command line interface terminal shell.
79
79
 
80
80
  ```sh
81
- bundle exec ./tcp_server.rb
81
+ bundle exec exe/tcp_server
82
82
  ```
83
83
 
84
84
 
@@ -96,7 +96,7 @@ bundle exec rake
96
96
  To publish the gem after first verifying that the built gem works, execute:
97
97
 
98
98
  ```sh
99
- version=$(ruby -r lib/server/version -I . -e 'puts ::Server::VERSION')
99
+ version=$(ruby -r lib/tcp_server/version -I . -e 'puts TcpServer::VERSION')
100
100
  git tag --annotate --message "Release ${version}" "${version}-release"
101
101
  git push origin --tags
102
102
  ```
@@ -105,7 +105,7 @@ git push origin --tags
105
105
  Or manually, if necessary:
106
106
 
107
107
  ```sh
108
- bundle exec rake verify
108
+ bundle exec rake clean clobber test package verify
109
109
  bundle exec rake publish
110
110
  ```
111
111
 
@@ -124,47 +124,47 @@ bundle exec rake clean clobber
124
124
  Here is a bird's-eye view of the project layout.
125
125
 
126
126
  ```sh
127
- # date && tree -A -I "logs|vendor|tmp|Gemfile.lock"
128
- Sat Jul 23 22:12:37 CDT 2022
127
+ $ date; tree --gitignore
128
+ Sun Feb 8 09:29:34 CST 2026
129
129
  .
130
- ├── Dockerfile
131
- ├── Gemfile
132
- ├── Gemfile.lock
133
- ├── LICENSE
134
- ├── README.md
135
- ├── Rakefile
136
130
  ├── docker-compose.yaml
131
+ ├── Dockerfile
137
132
  ├── exe
138
133
  │ └── tcp_server
134
+ ├── Gemfile
139
135
  ├── lib
140
- │ ├── client.rb
141
- │ ├── demo_listener.rb
142
- │ ├── logging.rb
143
- │ ├── server
144
- │ │ ├── argument_parser.rb
145
- │ │ ├── channel_initializer.rb
136
+ │ ├── tcp_server
137
+ ├── arguments_parser.rb
138
+ ├── channelizer.rb
139
+ ├── client.rb
146
140
  │ │ ├── config.rb
141
+ │ │ ├── default_handler.rb
142
+ │ │ ├── demo_listener.rb
147
143
  │ │ ├── instance_methods.rb
148
144
  │ │ ├── listenable.rb
145
+ │ │ ├── logging.rb
149
146
  │ │ ├── message_handler.rb
150
147
  │ │ ├── modular_handler.rb
151
148
  │ │ ├── server.rb
152
- │ │ ├── shutdown_hook.rb
153
149
  │ │ └── version.rb
154
- │ ├── server.rb
155
- │ ├── tcp-server.rb
156
150
  │ └── tcp_server.rb
151
+ ├── LICENSE
152
+ ├── Rakefile
153
+ ├── README.md
157
154
  ├── spec
155
+ │ ├── server_arguments_parser_spec.rb
156
+ │ ├── server_default_handler_spec.rb
157
+ │ ├── server_listenable_spec.rb
158
+ │ ├── server_message_handler_spec.rb
158
159
  │ ├── spec_helper.rb
159
160
  │ ├── test_spec.rb
160
161
  │ └── verify
161
162
  │ └── verify_spec.rb
162
- ├── tcp-server-1.0.8-java.gem
163
- ├── tcp-server-jruby.gemspec
164
163
  ├── tcp_server.png
165
- └── tcp_server.rb
164
+ ├── tcp_server.rb
165
+ └── tcp-server-jruby.gemspec
166
166
 
167
- 5 directories, 31 files
167
+ 6 directories, 31 files
168
168
  ```
169
169
 
170
170
 
data/Rakefile CHANGED
@@ -23,7 +23,8 @@ end
23
23
 
24
24
  desc 'Run the spec tests'
25
25
  task :test do
26
- system('bundle', 'exec', 'rspec', '--exclude-pattern', 'spec/verify/**/*_spec.rb') or abort
26
+ # system('bundle', 'exec', 'rspec', '--exclude-pattern', 'spec/verify/**/*_spec.rb') or abort
27
+ system('bundle', 'exec', 'rspec') or abort
27
28
  end
28
29
  task test: :lint
29
30
 
@@ -41,7 +42,16 @@ task package: %i[clean clobber test]
41
42
 
42
43
  desc 'Verify the gem'
43
44
  task :verify do
44
- system('bundle', 'exec', 'rspec', 'spec/verify') or abort
45
+ env = {
46
+ 'GEM_HOME' => 'tmp',
47
+ 'GEM_PATH' => 'tmp',
48
+ 'BUNDLE_GEMFILE' => nil,
49
+ 'RUBYOPT' => nil
50
+ }
51
+
52
+ # cmd = ['jruby', '-S', 'rspec', 'spec/verify']
53
+ cmd = ['bundle', 'exec', 'rspec', 'spec/verify']
54
+ system(env, *cmd) or abort
45
55
  end
46
56
  task verify: :explode
47
57
 
data/exe/tcp_server CHANGED
@@ -8,10 +8,10 @@
8
8
 
9
9
  # =begin
10
10
 
11
- # Copyright Nels Nelson 2016-2024 but freely usable (see license)
11
+ # Copyright Nels Nelson 2016-2026 but freely usable (see license)
12
12
 
13
13
  # =end
14
14
 
15
- require_relative '../lib/server'
15
+ require_relative '../lib/tcp_server'
16
16
 
17
- Object.new.extend(Server).main
17
+ Object.new.extend(TcpServer).main
@@ -6,7 +6,7 @@
6
6
 
7
7
  # =begin
8
8
  #
9
- # Copyright Nels Nelson 2016-2024 but freely usable (see license)
9
+ # Copyright Nels Nelson 2016-2026 but freely usable (see license)
10
10
  #
11
11
  # =end
12
12
 
@@ -14,15 +14,15 @@ require 'optparse'
14
14
 
15
15
  require_relative 'config'
16
16
 
17
- # The Server module
18
- module Server
17
+ # The TcpServer module
18
+ module TcpServer
19
19
  # The ArgumentsParser class
20
20
  class ArgumentsParser
21
21
  attr_reader :parser, :options
22
22
 
23
23
  def initialize(option_parser = OptionParser.new)
24
24
  @parser = option_parser
25
- @options = ::Server.server_config.dup
25
+ @options = TcpServer.server_config.dup
26
26
  @flags = %i[banner port ssl idle_reading idle_writing log_requests log_level help version]
27
27
  @flags.each { |method_name| method(method_name)&.call if respond_to?(method_name) }
28
28
  end
@@ -34,7 +34,7 @@ module Server
34
34
  end
35
35
 
36
36
  def validated_port(value, integer_pattern = /^\d+$/)
37
- raise OptionParser::InvalidArgument, "Invalid port: #{value}" unless \
37
+ raise OptionParser::InvalidArgument, "Invalid port: #{value}" unless
38
38
  integer_pattern.match?(value.to_s) && value.positive? && value < 65_536
39
39
 
40
40
  value
@@ -72,8 +72,8 @@ module Server
72
72
  end
73
73
 
74
74
  def log_level
75
+ current_level = @options.fetch(:log_level, 0)
75
76
  @parser.on_tail('-v', '--verbose', 'Increase verbosity') do
76
- current_level = @options.fetch(:log_level, 0)
77
77
  @options[:log_level] = current_level - 1
78
78
  end
79
79
  end
@@ -87,14 +87,14 @@ module Server
87
87
 
88
88
  def version
89
89
  @parser.on_tail('--version', 'Show version') do
90
- puts "#{File.basename($PROGRAM_NAME)} version #{::Server::VERSION}"
90
+ puts "#{File.basename($PROGRAM_NAME)} version #{TcpServer::VERSION}"
91
91
  exit
92
92
  end
93
93
  end
94
94
  end
95
95
  # class ArgumentsParser
96
96
 
97
- def parse_arguments(arguments_parser = ::Server::ArgumentsParser.new)
97
+ def parse_arguments(arguments_parser = TcpServer::ArgumentsParser.new)
98
98
  arguments_parser.parser.parse!(ARGV)
99
99
  arguments_parser.options
100
100
  rescue OptionParser::InvalidArgument, OptionParser::InvalidOption,
@@ -102,4 +102,4 @@ module Server
102
102
  abort e.message
103
103
  end
104
104
  end
105
- # module Server
105
+ # module TcpServer
@@ -6,30 +6,30 @@
6
6
 
7
7
  # =begin
8
8
  #
9
- # Copyright Nels Nelson 2016-2024 but freely usable (see license)
9
+ # Copyright Nels Nelson 2016-2026 but freely usable (see license)
10
10
  #
11
11
  # =end
12
12
 
13
13
  require 'java'
14
14
  require 'netty'
15
15
 
16
+ java_import 'io.netty.channel.ChannelInitializer'
17
+ java_import 'io.netty.handler.codec.DelimiterBasedFrameDecoder'
18
+ java_import 'io.netty.handler.codec.string.StringDecoder'
19
+ java_import 'io.netty.handler.codec.string.StringEncoder'
20
+ java_import 'io.netty.handler.ssl.SslContextBuilder'
21
+ java_import 'io.netty.handler.ssl.SslHandler'
22
+ java_import 'io.netty.handler.ssl.util.InsecureTrustManagerFactory'
23
+ java_import 'io.netty.handler.ssl.util.SelfSignedCertificate'
24
+ java_import 'io.netty.util.concurrent.FutureListener'
25
+
16
26
  require_relative 'message_handler'
17
27
  require_relative 'modular_handler'
18
28
 
19
- # The Server module
20
- module Server
21
- java_import Java::io.netty.handler.codec.DelimiterBasedFrameDecoder
22
- java_import Java::io.netty.handler.codec.Delimiters
23
- java_import Java::io.netty.handler.codec.string.StringDecoder
24
- java_import Java::io.netty.handler.codec.string.StringEncoder
25
- java_import Java::io.netty.handler.ssl.SslContextBuilder
26
- java_import Java::io.netty.handler.ssl.SslHandler
27
- java_import Java::io.netty.handler.ssl.util.InsecureTrustManagerFactory
28
- java_import Java::io.netty.handler.ssl.util.SelfSignedCertificate
29
- java_import Java::io.netty.util.concurrent.FutureListener
30
-
31
- # The ChannelInitializer class
32
- class ChannelInitializer < Java::io.netty.channel.ChannelInitializer
29
+ # The TcpServer module
30
+ module TcpServer
31
+ # The Channelizer class
32
+ class Channelizer < ChannelInitializer
33
33
  attr_accessor :decoder, :encoder, :user_handlers
34
34
  attr_reader :options
35
35
 
@@ -55,11 +55,12 @@ module Server
55
55
  end
56
56
 
57
57
  def frame_decoder
58
- DelimiterBasedFrameDecoder.new(@options[:max_frame_length], @options[:delimiter])
58
+ DelimiterBasedFrameDecoder.new(
59
+ @options[:max_frame_length], @options[:delimiter])
59
60
  end
60
61
 
61
62
  def default_handler
62
- @default_handler ||= ::Server::ModularHandler.new(@channel_group)
63
+ @default_handler ||= TcpServer::ModularHandler.new(@channel_group)
63
64
  end
64
65
 
65
66
  def add_listener(*listener)
@@ -76,7 +77,7 @@ module Server
76
77
  @user_handlers.each do |handler|
77
78
  case handler
78
79
  when Class then pipeline.addLast(handler.new)
79
- when Proc then pipeline.addLast(::Server::MessageHandler.new(&handler))
80
+ when Proc then pipeline.addLast(TcpServer::MessageHandler.new(&handler))
80
81
  else pipeline.addLast(handler)
81
82
  end
82
83
  end
@@ -89,8 +90,10 @@ module Server
89
90
  log.debug 'Initializing SSL context'
90
91
  require 'bouncycastle'
91
92
  ssc = SelfSignedCertificate.new
92
- builder = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey())
93
- @ssl_ctx = builder.trustManager(InsecureTrustManagerFactory::INSTANCE).build()
93
+ builder = SslContextBuilder.forServer(
94
+ ssc.certificate(), ssc.privateKey())
95
+ @ssl_ctx = builder.trustManager(
96
+ InsecureTrustManagerFactory::INSTANCE).build()
94
97
  end
95
98
 
96
99
  def ssl_handler_instance(channel, ssl_ctx = ssl_context)
@@ -106,13 +109,14 @@ module Server
106
109
  handler
107
110
  end
108
111
 
109
- def ssl_handshake_future_listener(listener = Object.new.extend(FutureListener))
112
+ def ssl_handshake_future_listener(
113
+ listener = Object.new.extend(FutureListener))
110
114
  listener.define_singleton_method(:operationComplete) do |future|
111
115
  raise future.cause unless future.success?
112
116
  session = future.now.pipeline.get('SslHandler#0')&.engine&.session
113
- ::Server.log.info "Channel protocol: #{session.protocol}, cipher suite: #{session.cipher_suite}"
117
+ TcpServer.log.info "Channel protocol: #{session.protocol}, cipher suite: #{session.cipher_suite}"
114
118
  rescue StandardError => e
115
- ::Server.log.warn "Error handling operation complete event: #{e.message}"
119
+ TcpServer.log.warn "Error handling operation complete event: #{e.message}"
116
120
  end
117
121
  listener
118
122
  end
@@ -124,6 +128,6 @@ module Server
124
128
  ssl_engine
125
129
  end
126
130
  end
127
- # class ChannelInitializer
131
+ # class Channelizer
128
132
  end
129
- # module Server
133
+ # module TcpServer
@@ -8,7 +8,7 @@
8
8
 
9
9
  # =begin
10
10
  #
11
- # Copyright Nels Nelson 2016-2024 but freely usable (see license)
11
+ # Copyright Nels Nelson 2016-2026 but freely usable (see license)
12
12
  #
13
13
  # =end
14
14
 
@@ -19,6 +19,23 @@ require 'netty'
19
19
 
20
20
  require_relative 'logging'
21
21
 
22
+ java_import 'io.netty.bootstrap.Bootstrap'
23
+ java_import 'io.netty.channel.AbstractChannel'
24
+ java_import 'io.netty.channel.ChannelInitializer'
25
+ java_import 'io.netty.channel.ChannelOption'
26
+ java_import 'io.netty.channel.SimpleChannelInboundHandler'
27
+ java_import 'io.netty.channel.nio.NioEventLoopGroup'
28
+ java_import 'io.netty.channel.socket.nio.NioSocketChannel'
29
+ java_import 'io.netty.handler.codec.Delimiters'
30
+ java_import 'io.netty.handler.codec.DelimiterBasedFrameDecoder'
31
+ java_import 'io.netty.handler.codec.string.StringDecoder'
32
+ java_import 'io.netty.handler.codec.string.StringEncoder'
33
+ java_import 'io.netty.handler.ssl.SslContextBuilder'
34
+ java_import 'io.netty.handler.ssl.SslHandler'
35
+ java_import 'io.netty.handler.ssl.util.InsecureTrustManagerFactory'
36
+ java_import 'java.util.concurrent.CopyOnWriteArrayList'
37
+ java_import 'java.util.concurrent.LinkedBlockingQueue'
38
+
22
39
  # The Client module
23
40
  module Client
24
41
  def client_config
@@ -29,7 +46,7 @@ module Client
29
46
  log_level: Logger::INFO,
30
47
  quit_commands: %i[bye cease desist exit leave quit stop terminate],
31
48
  max_frame_length: 8192,
32
- delimiter: Java::io.netty.handler.codec.Delimiters.lineDelimiter
49
+ delimiter: Delimiters.lineDelimiter
33
50
  }.freeze
34
51
  end
35
52
  module_function :client_config
@@ -37,19 +54,13 @@ end
37
54
 
38
55
  # The Client module
39
56
  module Client
40
- java_import Java::io.netty.bootstrap.Bootstrap
41
- java_import Java::io.netty.channel.ChannelOption
42
- java_import Java::io.netty.channel.nio.NioEventLoopGroup
43
- java_import Java::io.netty.handler.ssl.SslContextBuilder
44
- java_import Java::io.netty.handler.ssl.util.InsecureTrustManagerFactory
45
-
46
57
  # The InitializationMethods module
47
58
  module InitializationMethods
48
59
  def init(options)
49
60
  @options = options
50
61
  @host = @options[:host]
51
62
  @port = @options[:port]
52
- @queue = java.util.concurrent.LinkedBlockingQueue.new
63
+ @queue = LinkedBlockingQueue.new
53
64
  end
54
65
 
55
66
  def bootstrap
@@ -58,15 +69,15 @@ module Client
58
69
  @bootstrap.channel(::TCP::CHANNEL_TYPE)
59
70
  @bootstrap.option(ChannelOption::TCP_NODELAY, true)
60
71
  @bootstrap.handler(logging_handler) if @options[:log_requests]
61
- @bootstrap.handler(channel_initializer)
72
+ @bootstrap.handler(channelizer)
62
73
  end
63
74
 
64
75
  def client_group
65
76
  @client_group ||= NioEventLoopGroup.new
66
77
  end
67
78
 
68
- def channel_initializer
69
- @channel_initializer ||= ::Client::ChannelInitializer.new(@options)
79
+ def channelizer
80
+ @channelizer ||= ::Client::Channelizer.new(@options)
70
81
  end
71
82
 
72
83
  def logging_handler
@@ -74,8 +85,8 @@ module Client
74
85
  end
75
86
 
76
87
  def configure_handlers(*handlers, &block)
77
- channel_initializer.default_handler.add_listener(self)
78
- channel_initializer.default_handler.listeners.addAll(handlers)
88
+ channelizer.default_handler.add_listener(self)
89
+ channelizer.default_handler.listeners.addAll(handlers)
79
90
  @user_app = block
80
91
  @application_handler = lambda do |ctx, msg|
81
92
  if @user_app.nil? || @user_app.arity == 1
@@ -92,13 +103,11 @@ end
92
103
 
93
104
  # The Client module
94
105
  module Client
95
- java_import Java::io.netty.channel.AbstractChannel
96
-
97
106
  # The InstanceMethods module
98
107
  module InstanceMethods
99
108
  def puts(msg)
100
109
  wait_until_channel_is_active
101
- msg.chomp!
110
+ msg = msg.chomp
102
111
  log.trace "#puts msg: #{msg.inspect}"
103
112
  raise 'Message is empty!' if msg.nil? || msg.empty?
104
113
  @last_write_future = @channel.writeAndFlush("#{msg}\n")
@@ -221,13 +230,11 @@ module Client
221
230
  # The Listenable module
222
231
  module Listenable
223
232
  def listeners
224
- @listeners ||= java.util.concurrent.CopyOnWriteArrayList.new
233
+ @listeners ||= CopyOnWriteArrayList.new
225
234
  end
226
235
 
227
236
  def add_listener(*listener)
228
237
  listeners.addAll(listener)
229
- ensure
230
- log.trace "Listeners: #{listeners}"
231
238
  end
232
239
 
233
240
  def remove_listener(*listener)
@@ -237,6 +244,8 @@ module Client
237
244
  def replace_listeners(*listener)
238
245
  listeners.clear
239
246
  add_listener(*listener)
247
+ ensure
248
+ log.trace "##{__method__} listeners: #{listeners}"
240
249
  end
241
250
 
242
251
  def notify(event, *args)
@@ -253,40 +262,40 @@ end
253
262
 
254
263
  # The Client module
255
264
  module Client
256
- # java_import Java::io.netty.channel.ChannelInboundHandlerAdapter
257
- java_import Java::io.netty.channel.SimpleChannelInboundHandler
258
-
259
265
  # The ModularHandler class
260
- # class ModularHandler < ChannelInboundHandlerAdapter
261
266
  class ModularHandler < SimpleChannelInboundHandler
262
267
  include ::Client::Listenable
263
268
 
269
+ # Overrides the Java::IoNettyChannel::SimpleChannelInboundHandler#isSharable
270
+ # method
271
+ # rubocop: disable Naming/PredicateMethod
264
272
  def isSharable
265
273
  true
266
274
  end
275
+ # rubocop: enable Naming/PredicateMethod
267
276
 
268
277
  def channelRegistered(ctx)
269
278
  log.trace "##{__method__} channel: #{ctx.channel}"
270
279
  notify :channel_registered, ctx
271
- super(ctx)
280
+ super
272
281
  end
273
282
 
274
283
  def channelUnregistered(ctx)
275
284
  log.trace "##{__method__} channel: #{ctx.channel}"
276
285
  notify :channel_unregistered, ctx
277
- super(ctx)
286
+ super
278
287
  end
279
288
 
280
289
  def channelActive(ctx)
281
290
  ::Client.log.debug "Channel active #{ctx.channel}"
282
291
  notify :channel_active, ctx
283
- super(ctx)
292
+ super
284
293
  end
285
294
 
286
295
  def channelInactive(ctx)
287
296
  log.trace "##{__method__} channel: #{ctx.channel}"
288
297
  notify :channel_inactive, ctx
289
- super(ctx)
298
+ super
290
299
  end
291
300
 
292
301
  def messageReceived(ctx, msg)
@@ -297,7 +306,7 @@ module Client
297
306
  def channelRead(ctx, msg)
298
307
  log.trace "##{__method__} channel: #{ctx.channel}, message: #{msg.inspect}"
299
308
  notify :channel_read, ctx, msg
300
- super(ctx, msg)
309
+ super
301
310
  end
302
311
 
303
312
  # Please keep in mind that this method will be renamed to
@@ -312,25 +321,25 @@ module Client
312
321
  def channelReadComplete(ctx)
313
322
  log.trace "##{__method__} channel: #{ctx.channel}"
314
323
  notify :channel_read_complete, ctx
315
- super(ctx)
324
+ super
316
325
  end
317
326
 
318
327
  def channelWritabilityChanged(ctx)
319
328
  log.trace "##{__method__} channel: #{ctx.channel}"
320
329
  notify :channel_writability_changed, ctx
321
- super(ctx)
330
+ super
322
331
  end
323
332
 
324
333
  def userEventTriggered(ctx, evt)
325
334
  log.trace "##{__method__} channel: #{ctx.channel}, event: #{evt}"
326
335
  notify :user_event_triggered, ctx, evt
327
- super(ctx, evt)
336
+ super
328
337
  end
329
338
 
330
339
  def exceptionCaught(ctx, cause)
331
340
  ::Client.log.warn "##{__method__} channel: #{ctx.channel}, cause: #{cause.message}"
332
341
  listeners = notify :exception_caught, ctx, cause
333
- super(ctx, cause) if listeners.empty?
342
+ super if listeners.empty?
334
343
  end
335
344
 
336
345
  IdentiferTemplate = '#<%<class>s:0x%<id>s>'.freeze
@@ -346,13 +355,8 @@ end
346
355
 
347
356
  # The Client module
348
357
  module Client
349
- java_import Java::io.netty.handler.codec.DelimiterBasedFrameDecoder
350
- java_import Java::io.netty.handler.codec.Delimiters
351
- java_import Java::io.netty.handler.codec.string.StringDecoder
352
- java_import Java::io.netty.handler.codec.string.StringEncoder
353
-
354
- # The ChannelInitializer class
355
- class ChannelInitializer < Java::io.netty.channel.ChannelInitializer
358
+ # The Channelizer class
359
+ class Channelizer < ChannelInitializer
356
360
  attr_accessor :decoder, :encoder, :handlers
357
361
 
358
362
  def initialize(options = {})
@@ -380,7 +384,8 @@ module Client
380
384
  end
381
385
 
382
386
  def frame_decoder
383
- DelimiterBasedFrameDecoder.new(@options[:max_frame_length], @options[:delimiter])
387
+ DelimiterBasedFrameDecoder.new(
388
+ @options[:max_frame_length], @options[:delimiter])
384
389
  end
385
390
 
386
391
  def default_handler
@@ -405,7 +410,8 @@ module Client
405
410
  return @ssl_ctx unless @ssl_ctx.nil?
406
411
  log.debug 'Initializing SSL context'
407
412
  builder = SslContextBuilder.forClient()
408
- @ssl_ctx = builder.trustManager(InsecureTrustManagerFactory::INSTANCE).build()
413
+ @ssl_ctx = builder.trustManager(
414
+ InsecureTrustManagerFactory::INSTANCE).build()
409
415
  end
410
416
 
411
417
  def ssl_handler(channel, ssl_ctx = ssl_context)
@@ -422,13 +428,13 @@ module Client
422
428
  ssl_engine
423
429
  end
424
430
  end
425
- # class ChannelInitializer
431
+ # class Channelizer
426
432
  end
427
433
  # module Client
428
434
 
429
435
  # The TCP module
430
436
  module TCP
431
- CHANNEL_TYPE = Java::io.netty.channel.socket.nio.NioSocketChannel.java_class
437
+ CHANNEL_TYPE = NioSocketChannel.java_class
432
438
 
433
439
  # The Client class
434
440
  class Client
@@ -439,6 +445,8 @@ module TCP
439
445
  def initialize(options = {}, *handlers, &block)
440
446
  init(::Client.client_config.merge(options))
441
447
  configure_handlers(*handlers, &block)
448
+ listeners = channelizer.default_handler.listeners
449
+ log.trace "##{__method__} listeners: #{listeners}"
442
450
  connect
443
451
  session
444
452
  end
@@ -480,7 +488,7 @@ module Client
480
488
  end
481
489
 
482
490
  def validated_port(val, integer_pattern = /^\d+$/)
483
- raise OptionParser::InvalidArgument, "Invalid port: #{val}" unless \
491
+ raise OptionParser::InvalidArgument, "Invalid port: #{val}" unless
484
492
  integer_pattern.match?(val.to_s) && val.positive? && val < 65_536
485
493
 
486
494
  val
@@ -500,9 +508,9 @@ module Client
500
508
  end
501
509
 
502
510
  def log_level
511
+ current_level = @options.fetch(:log_level, 0)
503
512
  @parser.on_tail('-v', '--verbose', 'Increase verbosity') do
504
- @options[:log_level] ||= 0
505
- @options[:log_level] -= 1
513
+ @options[:log_level] = current_level - 1
506
514
  end
507
515
  end
508
516
 
@@ -515,7 +523,7 @@ module Client
515
523
 
516
524
  def version
517
525
  @parser.on_tail('--version', 'Show version') do
518
- puts "#{File.basename($PROGRAM_NAME)} version #{::Server::VERSION}"
526
+ puts "#{File.basename($PROGRAM_NAME)} version #{::Client::VERSION}"
519
527
  exit
520
528
  end
521
529
  end