tcp-server 1.2.1-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.
@@ -6,61 +6,65 @@
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
- require_relative 'listenable'
16
+ java_import 'io.netty.channel.SimpleChannelInboundHandler'
17
17
 
18
- # The Server module
19
- module Server
20
- java_import Java::io.netty.channel.SimpleChannelInboundHandler
18
+ require_relative 'listenable'
21
19
 
20
+ # The TcpServer module
21
+ module TcpServer
22
22
  # The ModularHandler class notifies listeners about events.
23
23
  class ModularHandler < SimpleChannelInboundHandler
24
- include ::Server::Listenable
24
+ include TcpServer::Listenable
25
25
 
26
26
  def initialize(channel_group)
27
27
  super()
28
28
  @channel_group = channel_group
29
29
  end
30
30
 
31
+ # Overrides the Java::IoNettyChannel::SimpleChannelInboundHandler#isSharable
32
+ # method
33
+ # rubocop: disable Naming/PredicateMethod
31
34
  def isSharable
32
35
  true
33
36
  end
37
+ # rubocop: enable Naming/PredicateMethod
34
38
 
35
39
  def channelRegistered(ctx)
36
- log.trace "##{__method__} channel: #{ctx.channel}"
40
+ log.trace "#channelRegistered channel: #{ctx.channel}"
37
41
  notify :channel_registered, ctx
38
- super(ctx)
42
+ super
39
43
  end
40
44
 
41
45
  def channelUnregistered(ctx)
42
- log.trace "##{__method__} channel: #{ctx.channel}"
46
+ log.trace "#channelUnregistered channel: #{ctx.channel}"
43
47
  notify :channel_unregistered, ctx
44
- super(ctx)
48
+ super
45
49
  end
46
50
 
47
51
  def channelActive(ctx)
48
- ::Server.log.debug "##{__method__} channel: #{ctx.channel}"
52
+ TcpServer.log.debug "#channelActive channel: #{ctx.channel}"
49
53
  @channel_group.add(ctx.channel)
50
54
  notify :channel_active, ctx
51
- super(ctx)
55
+ super
52
56
  end
53
57
 
54
58
  def channelInactive(ctx)
55
- log.trace "##{__method__} channel: #{ctx.channel}"
59
+ log.trace "#channelInactive channel: #{ctx.channel}"
56
60
  notify :channel_inactive, ctx
57
- super(ctx)
61
+ super
58
62
  end
59
63
 
60
64
  def channelRead(ctx, msg)
61
- log.trace "##{__method__} channel: #{ctx.channel}, message: #{msg.inspect}"
65
+ log.trace "#channelRead channel: #{ctx.channel}, message: #{msg.inspect}"
62
66
  notify :channel_read, ctx, msg
63
- super(ctx, msg)
67
+ super
64
68
  end
65
69
 
66
70
  # Please keep in mind that this method will be renamed to
@@ -68,40 +72,41 @@ module Server
68
72
  #
69
73
  # java_signature 'protected abstract void channelRead0(ChannelHandlerContext ctx, I msg) throws Exception'
70
74
  def channelRead0(ctx, msg)
71
- log.trace "##{__method__} channel: #{ctx.channel}, message: #{msg.inspect}"
75
+ log.trace "#channelRead0 channel: #{ctx.channel}, message: #{msg.inspect}"
72
76
  messageReceived(ctx, msg)
73
77
  # super(ctx, msg)
74
78
  end
75
79
 
76
80
  def messageReceived(ctx, msg)
77
- log.trace "##{__method__} channel: #{ctx.channel}, message: #{msg.inspect}"
81
+ log.trace "#messageReceived channel: #{ctx.channel}, message: #{msg.inspect}"
78
82
  notify :message_received, ctx, msg
79
83
  # super(ctx, msg)
80
84
  end
81
85
 
82
86
  def channelReadComplete(ctx)
83
- log.trace "##{__method__} channel: #{ctx.channel}"
87
+ log.trace "#channelReadComplete channel: #{ctx.channel}"
84
88
  notify :channel_read_complete, ctx
85
- super(ctx)
89
+ super
86
90
  end
87
91
 
88
92
  def userEventTriggered(ctx, evt)
89
- log.trace "##{__method__} channel: #{ctx.channel}, event: #{evt}"
93
+ log.trace "#userEventTriggered channel: #{ctx.channel}, event: #{evt}"
90
94
  notify :user_event_triggered, ctx, evt
91
- super(ctx, evt)
95
+ super
92
96
  end
93
97
 
94
98
  def channelWritabilityChanged(ctx)
95
- log.trace "##{__method__} channel: #{ctx.channel}"
99
+ log.trace "#channelWritabilityChanged channel: #{ctx.channel}"
96
100
  notify :channel_writability_changed, ctx
97
- super(ctx)
101
+ super
98
102
  end
99
103
 
100
104
  def exceptionCaught(ctx, cause)
101
- ::Server.log.warn "##{__method__} channel: #{ctx.channel}, cause: #{cause.message}"
102
- cause.backtrace.each { |t| ::Server.log.error t }
105
+ TcpServer.log.warn "#exceptionCaught channel: #{ctx.channel}, " \
106
+ "cause: #{cause.message}"
107
+ cause.backtrace.each { |t| TcpServer.log.error t }
103
108
  listeners = notify :exception_caught, ctx, cause
104
- super(ctx, cause) if listeners.nil? || listeners.empty?
109
+ super if listeners.nil? || listeners.empty?
105
110
  end
106
111
 
107
112
  IdentifierTemplate = '#<%<class>s:0x%<id>s>'.freeze
@@ -113,4 +118,4 @@ module Server
113
118
  end
114
119
  # class ModularHandler
115
120
  end
116
- # module Server
121
+ # module TcpServer
@@ -0,0 +1,58 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: false
3
+
4
+ # -*- mode: ruby -*-
5
+ # vi: set ft=ruby :
6
+
7
+ # =begin
8
+ #
9
+ # Copyright Nels Nelson 2016-2026 but freely usable (see license)
10
+ #
11
+ # =end
12
+
13
+ require 'java'
14
+ require 'netty'
15
+
16
+ require_relative 'arguments_parser'
17
+ require_relative 'demo_listener'
18
+ require_relative 'instance_methods'
19
+ require_relative 'listenable'
20
+ require_relative 'logging'
21
+
22
+ java_import 'io.netty.channel.socket.nio.NioServerSocketChannel'
23
+
24
+ # The Server module
25
+ module TcpServer
26
+ # The Server class sets up the netty server.
27
+ class Server
28
+ CHANNEL_TYPE = NioServerSocketChannel.java_class
29
+ include TcpServer::InstanceMethods
30
+
31
+ attr_reader :options
32
+
33
+ def initialize(options = {}, *handlers, &block)
34
+ raise ArgumentError, 'Parameter may not be nil: options' if options.nil?
35
+ @options = TcpServer.server_config.merge(options)
36
+ configure_handlers(*(handlers.empty? && block.nil? ? [self] : handlers), &block)
37
+ ensure
38
+ listeners = channelizer.default_handler.listeners
39
+ log.trace "##{__method__} listeners: #{listeners}"
40
+ end
41
+ end
42
+ # class Server
43
+
44
+ def main(args = parse_arguments)
45
+ Logging.log_level = args[:log_level]
46
+ demo_handler = TcpServer::Demo.new(args)
47
+ TcpServer::Server.new(args, demo_handler).run
48
+ rescue Interrupt => e
49
+ warn format("\r%<class>s", class: e.class)
50
+ exit
51
+ rescue StandardError => e
52
+ TcpServer::Server.log.fatal(e)
53
+ e.backtrace.each { |t| TcpServer.log.fatal t }
54
+ exit 1
55
+ end
56
+ end
57
+
58
+ Object.new.extend(TcpServer).main if $PROGRAM_NAME == __FILE__
@@ -0,0 +1,16 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: false
3
+
4
+ # -*- mode: ruby -*-
5
+ # vi: set ft=ruby :
6
+
7
+ # =begin
8
+ #
9
+ # Copyright Nels Nelson 2016-2026 but freely usable (see license)
10
+ #
11
+ # =end
12
+
13
+ # The TcpServer module
14
+ module TcpServer
15
+ VERSION = '1.4.1'.freeze
16
+ end
data/lib/tcp_server.rb CHANGED
@@ -6,8 +6,9 @@
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
- require_relative 'server'
13
+ require_relative 'tcp_server/client'
14
+ require_relative 'tcp_server/server'
metadata CHANGED
@@ -1,60 +1,70 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tcp-server
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 1.4.1
5
5
  platform: java
6
6
  authors:
7
7
  - Nels Nelson
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2024-04-15 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
13
+ name: apache-log4j-2
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
16
  - - "~>"
17
17
  - !ruby/object:Gem::Version
18
- version: 2.17.1
19
- name: apache-log4j-2
18
+ version: 2.25.3
20
19
  type: :runtime
21
20
  prerelease: false
22
21
  version_requirements: !ruby/object:Gem::Requirement
23
22
  requirements:
24
23
  - - "~>"
25
24
  - !ruby/object:Gem::Version
26
- version: 2.17.1
27
- force_ruby_platform: false
25
+ version: 2.25.3
28
26
  - !ruby/object:Gem::Dependency
27
+ name: bouncycastle
29
28
  requirement: !ruby/object:Gem::Requirement
30
29
  requirements:
31
30
  - - "~>"
32
31
  - !ruby/object:Gem::Version
33
- version: 1.70.1
34
- name: bouncycastle
32
+ version: '1.83'
35
33
  type: :runtime
36
34
  prerelease: false
37
35
  version_requirements: !ruby/object:Gem::Requirement
38
36
  requirements:
39
37
  - - "~>"
40
38
  - !ruby/object:Gem::Version
41
- version: 1.70.1
42
- force_ruby_platform: false
39
+ version: '1.83'
43
40
  - !ruby/object:Gem::Dependency
41
+ name: logger
44
42
  requirement: !ruby/object:Gem::Requirement
45
43
  requirements:
46
44
  - - "~>"
47
45
  - !ruby/object:Gem::Version
48
- version: 4.1.74
46
+ version: '1.7'
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '1.7'
54
+ - !ruby/object:Gem::Dependency
49
55
  name: netty-io
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: 4.2.9
50
61
  type: :runtime
51
62
  prerelease: false
52
63
  version_requirements: !ruby/object:Gem::Requirement
53
64
  requirements:
54
65
  - - "~>"
55
66
  - !ruby/object:Gem::Version
56
- version: 4.1.74
57
- force_ruby_platform: false
67
+ version: 4.2.9
58
68
  description: TCP Server for JRuby is a tcp server which supports a demo echo server
59
69
  application.
60
70
  email: nels@nelsnelson.org
@@ -67,23 +77,20 @@ files:
67
77
  - README.md
68
78
  - Rakefile
69
79
  - exe/tcp_server
70
- - lib/client.rb
71
- - lib/demo_listener.rb
72
- - lib/logging.rb
73
- - lib/server.rb
74
- - lib/server/argument_parser.rb
75
- - lib/server/channel_initializer.rb
76
- - lib/server/config.rb
77
- - lib/server/default_handler.rb
78
- - lib/server/instance_methods.rb
79
- - lib/server/listenable.rb
80
- - lib/server/message_handler.rb
81
- - lib/server/modular_handler.rb
82
- - lib/server/server.rb
83
- - lib/server/shutdown_hook.rb
84
- - lib/server/version.rb
85
- - lib/tcp-server.rb
86
80
  - lib/tcp_server.rb
81
+ - lib/tcp_server/arguments_parser.rb
82
+ - lib/tcp_server/channelizer.rb
83
+ - lib/tcp_server/client.rb
84
+ - lib/tcp_server/config.rb
85
+ - lib/tcp_server/default_handler.rb
86
+ - lib/tcp_server/demo_listener.rb
87
+ - lib/tcp_server/instance_methods.rb
88
+ - lib/tcp_server/listenable.rb
89
+ - lib/tcp_server/logging.rb
90
+ - lib/tcp_server/message_handler.rb
91
+ - lib/tcp_server/modular_handler.rb
92
+ - lib/tcp_server/server.rb
93
+ - lib/tcp_server/version.rb
87
94
  homepage: https://rubygems.org/gems/tcp-server-jruby
88
95
  licenses:
89
96
  - MIT
@@ -91,7 +98,6 @@ metadata:
91
98
  source_code_uri: https://gitlab.com/nelsnelson/tcp-server-jruby
92
99
  bug_tracker_uri: https://gitlab.com/nelsnelson/tcp-server-jruby/issues
93
100
  rubygems_mfa_required: 'true'
94
- post_install_message:
95
101
  rdoc_options: []
96
102
  require_paths:
97
103
  - lib
@@ -106,8 +112,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
106
112
  - !ruby/object:Gem::Version
107
113
  version: '0'
108
114
  requirements: []
109
- rubygems_version: 3.3.26
110
- signing_key:
115
+ rubygems_version: 3.6.9
111
116
  specification_version: 4
112
117
  summary: TCP Server for JRuby packaged as a gem.
113
118
  test_files: []
data/lib/logging.rb DELETED
@@ -1,253 +0,0 @@
1
- # encoding: utf-8
2
- # frozen_string_literal: false
3
-
4
- # -*- mode: ruby -*-
5
- # vi: set ft=ruby :
6
-
7
- # =begin
8
-
9
- # Copyright Nels Nelson 2016-2024 but freely usable (see license)
10
-
11
- # =end
12
-
13
- require 'java'
14
- require 'fileutils'
15
- require 'logger'
16
-
17
- require 'apache-log4j-2'
18
-
19
- # The Logging module
20
- module Logging
21
- # rubocop: disable Metrics/MethodLength
22
- def config
23
- @config ||= begin
24
- lib_dir_path = File.expand_path(__dir__)
25
- project_dir_path = File.expand_path(File.dirname(lib_dir_path))
26
- logs_dir_path = File.expand_path(File.join(project_dir_path, 'logs'))
27
- FileUtils.mkdir_p(logs_dir_path)
28
- log_file_path = File.expand_path(File.join(logs_dir_path, 'server.log'))
29
- FileUtils.touch(log_file_path)
30
- {
31
- level: Logger::INFO,
32
- name: 'websocket',
33
- lib_dir_path: lib_dir_path,
34
- project_dir_path: project_dir_path,
35
- logs_dir_path: logs_dir_path,
36
- log_file_path: log_file_path,
37
- rolling_log_file_name_template: File.expand_path(
38
- File.join(logs_dir_path, 'server-%d{yyyy-MM-dd}.log.gz')),
39
- logging_pattern_template: {
40
- java: '%d{ABSOLUTE} %-5p [%c{1}] %m%n',
41
- ruby: "%<timestamp>s %-5<severity>s [%<progname>s] %<msg>s\n"
42
- },
43
- schedule: '0 0 0 * * ?',
44
- size: '100M'
45
- }
46
- end
47
- end
48
- module_function :config
49
- # rubocop: enable Metrics/MethodLength
50
- end
51
-
52
- # The Logging module
53
- module Logging
54
- if defined?(Java)
55
- java_import Java::org.apache.logging.log4j.core.appender::ConsoleAppender
56
- java_import Java::org.apache.logging.log4j.core.config::Configurator
57
- java_import Java::org.apache.logging.log4j.core.config.builder.api::ConfigurationBuilderFactory
58
- end
59
-
60
- # rubocop: disable Metrics/AbcSize
61
- # rubocop: disable Metrics/MethodLength
62
- def init_log4j(log_level = org.apache.logging.log4j.Level::INFO)
63
- java.lang::System.setProperty('log4j.shutdownHookEnabled', java.lang::Boolean.toString(false))
64
- config = ConfigurationBuilderFactory.newConfigurationBuilder()
65
-
66
- log_level = org.apache.logging.log4j::Level.to_level(log_level.to_s.upcase) if log_level.is_a? Symbol
67
- config.setStatusLevel(log_level)
68
- config.setConfigurationName('websocket')
69
-
70
- # create a console appender
71
- target = ConsoleAppender::Target::SYSTEM_OUT
72
- pattern = Logging.config[:logging_pattern_template][:java]
73
- layout = config.newLayout('PatternLayout')
74
- layout = layout.addAttribute('pattern', pattern)
75
- appender = config.newAppender('stdout', 'CONSOLE')
76
- appender = appender.addAttribute('target', target)
77
- appender = appender.add(layout)
78
- config.add(appender)
79
-
80
- # create a root logger
81
- root_logger = config.newRootLogger(log_level)
82
- root_logger = root_logger.add(config.newAppenderRef('stdout'))
83
-
84
- # create a rolling file appender
85
- cron = config.newComponent('CronTriggeringPolicy')
86
- cron = cron.addAttribute('schedule', '0 0 0 * * ?')
87
-
88
- size = config.newComponent('SizeBasedTriggeringPolicy')
89
- size = size.addAttribute('size', '100M')
90
-
91
- policies = config.newComponent('Policies')
92
- policies = policies.addComponent(cron)
93
- policies = policies.addComponent(size)
94
-
95
- appender = config.newAppender('rolling_file', 'RollingFile')
96
- appender = appender.addAttribute('fileName', Logging.config[:log_file_path])
97
- appender = appender.addAttribute('filePattern', Logging.config[:rolling_log_file_name_template])
98
- appender = appender.add(layout)
99
- appender = appender.addComponent(policies)
100
- config.add(appender)
101
-
102
- root_logger = root_logger.addAttribute('additivity', false)
103
- root_logger = root_logger.add(config.newAppenderRef('rolling_file'))
104
- config.add(root_logger)
105
-
106
- logging_configuration = config.build()
107
- ctx = Configurator.initialize(logging_configuration)
108
- ctx.updateLoggers()
109
- end
110
- module_function :init_log4j
111
- # rubocop: enable Metrics/AbcSize
112
- # rubocop: enable Metrics/MethodLength
113
- # def init_log4j
114
-
115
- init_log4j if defined?(Java)
116
- end
117
- # module Logging
118
-
119
- # Namespace for methods to help with implicit backtrace printing
120
- module LoggerHelpers
121
- def generate_message(error_or_message, error)
122
- error_message = "#{error_or_message}: #{error.class.name}"
123
- error_message << ": #{error.message}" if error.respond_to?(:message)
124
- error_message
125
- end
126
-
127
- def extract_backtrace(error, default_result = nil)
128
- if error.respond_to?(:backtrace)
129
- error.backtrace.each { |trace| original_error(trace) unless trace.nil? }
130
- elsif error.respond_to?(:getStackTrace)
131
- error.getStackTrace().each { |trace| original_error(trace) unless trace.nil? }
132
- else
133
- default_result
134
- end
135
- end
136
- end
137
-
138
- # Monkey-patch the built-in Ruby Logger class to support
139
- # implicit backtrace printing
140
- # TODO: Figure out if this is actually useful.
141
- class Logger
142
- include LoggerHelpers
143
-
144
- alias original_error error
145
- def error(error_or_message, error = nil)
146
- return extract_backtrace(error_or_message) if error.nil?
147
- original_error(generate_message(error_or_message, error))
148
- extract_backtrace(original_error(error))
149
- end
150
- end
151
-
152
- # The Logging module
153
- module Logging
154
- if defined?(Java)
155
- java_import Java::org.apache.logging.log4j.Level
156
- java_import Java::org.apache.logging.log4j.LogManager
157
- end
158
-
159
- FORWARD_SLASH_PATTERN = %r{/} unless defined?(FORWARD_SLASH_PATTERN)
160
-
161
- def init_logger(level = :info, logger_name = nil)
162
- return init_java_logger(level, logger_name, caller[2]) if defined?(Java)
163
- init_ruby_logger(level, logger_name, caller[2])
164
- end
165
-
166
- def ruby_log_formatter(severity_level, datetime, program_name, message)
167
- format(
168
- Logging.config[:logging_pattern_template][:ruby],
169
- timestamp: datetime.strftime(Logging.config[:logging_timestamp_format]),
170
- progname: program_name, severity: severity_level, msg: message)
171
- end
172
-
173
- def init_ruby_logger(level = nil, logger_name = nil, source_location = nil)
174
- logger_name = get_formatted_logger_name(logger_name)
175
- logger_name = source_location.split(FORWARD_SLASH_PATTERN).last if logger_name.empty?
176
- log = Logger.new($stdout, progname: logger_name)
177
- log.level = level.to_s unless level.nil?
178
- log.formatter = method(:ruby_log_formatter)
179
- log
180
- end
181
-
182
- def init_java_logger(level = nil, logger_name = nil, source_location = nil)
183
- logger_name = get_formatted_logger_name(logger_name)
184
- logger_name = source_location.split(FORWARD_SLASH_PATTERN).last if logger_name.empty?
185
- log = LogManager.getLogger(logger_name)
186
- log.level = Level.to_level(level.to_s.upcase) unless level.nil?
187
- log
188
- end
189
-
190
- def get_formatted_logger_name(logger_name = nil)
191
- return logger_name.to_s[/\w+$/] unless logger_name.nil?
192
- return name[/\w+$/] if is_a?(Class) || is_a?(Module)
193
- self.class.name[/\w+$/]
194
- end
195
-
196
- # rubocop: disable Metrics/CyclomaticComplexity
197
- # OFF: 0
198
- # FATAL: 100
199
- # ERROR: 200
200
- # WARN: 300
201
- # INFO: 400
202
- # DEBUG: 500
203
- # TRACE: 600
204
- # ALL: 2147483647
205
- # See: https://logging.apache.org/log4j/2.x/log4j-api/apidocs/org/apache/logging/log4j/Level.html
206
- def symbolize_numeric_log_level(level)
207
- case level
208
- when 5..Float::INFINITY then :off
209
- when 4 then :fatal
210
- when 3 then :error
211
- when 2 then :warn
212
- when 1 then :info
213
- when 0 then :debug
214
- when -1 then :trace
215
- when -Float::INFINITY..-2 then :all
216
- end
217
- end
218
- # rubocop: enable Metrics/CyclomaticComplexity
219
-
220
- def log_level=(level)
221
- Logging.config[:level] = symbolize_numeric_log_level(level)
222
- end
223
- module_function :log_level=
224
-
225
- def log_level
226
- Logging.config[:level]
227
- end
228
- module_function :log_level
229
-
230
- def log(level = Logging.log_level, log_name = Logging.config[:app_name])
231
- @log ||= init_logger(level, log_name)
232
- end
233
- alias logger log
234
- end
235
- # module Logging
236
-
237
- # The Module class
238
- class Module
239
- # Universally include Logging
240
- include ::Logging
241
- end
242
-
243
- # The Class class
244
- class Class
245
- # Universally include Logging
246
- include ::Logging
247
- end
248
-
249
- # The Object class
250
- class Object
251
- # Universally include Logging
252
- include ::Logging
253
- end
data/lib/server/server.rb DELETED
@@ -1,38 +0,0 @@
1
- # encoding: utf-8
2
- # frozen_string_literal: false
3
-
4
- # -*- mode: ruby -*-
5
- # vi: set ft=ruby :
6
-
7
- # =begin
8
- #
9
- # Copyright Nels Nelson 2016-2024 but freely usable (see license)
10
- #
11
- # =end
12
-
13
- require 'java'
14
- require 'netty'
15
-
16
- require_relative 'instance_methods'
17
- require_relative 'listenable'
18
-
19
- # The Server module
20
- module Server
21
- # The Server class sets up the netty server.
22
- class Server
23
- CHANNEL_TYPE = Java::io.netty.channel.socket.nio.NioServerSocketChannel.java_class
24
- include ::Server::InstanceMethods
25
- attr_reader :options
26
-
27
- def initialize(options = {}, *handlers, &block)
28
- raise ArgumentError, 'Parameter may not be nil: options' if options.nil?
29
- @options = ::Server.server_config.merge(options)
30
- configure_handlers(*(handlers.empty? && block.nil? ? [self] : handlers), &block)
31
- ensure
32
- listeners = channel_initializer.default_handler.listeners
33
- log.trace "##{__method__} listeners: #{listeners}"
34
- end
35
- end
36
- # class Server
37
- end
38
- # module Server
@@ -1,35 +0,0 @@
1
- # encoding: utf-8
2
- # frozen_string_literal: false
3
-
4
- # -*- mode: ruby -*-
5
- # vi: set ft=ruby :
6
-
7
- # =begin
8
- #
9
- # Copyright Nels Nelson 2016-2024 but freely usable (see license)
10
- #
11
- # =end
12
-
13
- require 'java'
14
-
15
- # The Server module
16
- module Server
17
- # The ShutdownHook class specifies a routine to be invoked when the
18
- # java runtime is shutdown.
19
- class ShutdownHook < java.lang.Thread
20
- attr_reader :server
21
-
22
- def initialize(server)
23
- super()
24
- @server = server
25
- java.lang.Runtime.runtime.add_shutdown_hook(self)
26
- end
27
-
28
- def run
29
- $stdout.write "\r\e[0K"
30
- $stdout.flush
31
- ::Server.log.info 'Shutting down'
32
- server.shutdown if server.respond_to?(:shutdown)
33
- end
34
- end
35
- end