tcp-server 1.0.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.
@@ -0,0 +1,119 @@
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-2022 but freely usable (see license)
10
+ #
11
+ # =end
12
+
13
+ require 'java'
14
+ require 'netty'
15
+
16
+ require_relative 'listenable'
17
+
18
+ # The Server module
19
+ module Server
20
+ java_import Java::io.netty.channel.SimpleChannelInboundHandler
21
+ java_import Java::io.netty.channel.group.DefaultChannelGroup
22
+ java_import Java::io.netty.util.concurrent.GlobalEventExecutor
23
+
24
+ # rubocop: disable Style/IfUnlessModifier
25
+ unless defined?(::Server::Channels)
26
+ Channels = DefaultChannelGroup.new('channels', GlobalEventExecutor::INSTANCE)
27
+ end
28
+ # rubocop: enable Style/IfUnlessModifier
29
+
30
+ # The ModularHandler class notifies listeners about events.
31
+ class ModularHandler < SimpleChannelInboundHandler
32
+ include ::Server::Listenable
33
+
34
+ def isSharable
35
+ true
36
+ end
37
+
38
+ def channelRegistered(ctx)
39
+ log.trace "##{__method__} channel: #{ctx.channel}"
40
+ notify :channel_registered, ctx
41
+ super(ctx)
42
+ end
43
+
44
+ def channelUnregistered(ctx)
45
+ log.trace "##{__method__} channel: #{ctx.channel}"
46
+ notify :channel_unregistered, ctx
47
+ super(ctx)
48
+ end
49
+
50
+ def channelActive(ctx)
51
+ log.trace "##{__method__} channel: #{ctx.channel}"
52
+ ::Server::Channels.add(ctx.channel)
53
+ notify :channel_active, ctx
54
+ super(ctx)
55
+ end
56
+
57
+ def channelInactive(ctx)
58
+ log.trace "##{__method__} channel: #{ctx.channel}"
59
+ notify :channel_inactive, ctx
60
+ super(ctx)
61
+ end
62
+
63
+ def channelRead(ctx, msg)
64
+ log.trace "##{__method__} channel: #{ctx.channel}, message: #{msg.inspect}"
65
+ notify :channel_read, ctx, msg
66
+ super(ctx, msg)
67
+ end
68
+
69
+ # Please keep in mind that this method will be renamed to
70
+ # messageReceived(ChannelHandlerContext, I) in 5.0.
71
+ #
72
+ # java_signature 'protected abstract void channelRead0(ChannelHandlerContext ctx, I msg) throws Exception'
73
+ def channelRead0(ctx, msg)
74
+ log.trace "##{__method__} channel: #{ctx.channel}, message: #{msg.inspect}"
75
+ messageReceived(ctx, msg)
76
+ # super(ctx, msg)
77
+ end
78
+
79
+ def messageReceived(ctx, msg)
80
+ log.trace "##{__method__} channel: #{ctx.channel}, message: #{msg.inspect}"
81
+ notify :message_received, ctx, msg
82
+ # super(ctx, msg)
83
+ end
84
+
85
+ def channelReadComplete(ctx)
86
+ log.trace "##{__method__} channel: #{ctx.channel}"
87
+ notify :channel_read_complete, ctx
88
+ super(ctx)
89
+ end
90
+
91
+ def userEventTriggered(ctx, evt)
92
+ log.trace "##{__method__} channel: #{ctx.channel}, event: #{evt}"
93
+ notify :user_event_triggered, ctx, evt
94
+ super(ctx, evt)
95
+ end
96
+
97
+ def channelWritabilityChanged(ctx)
98
+ log.trace "##{__method__} channel: #{ctx.channel}"
99
+ notify :channel_writability_changed, ctx
100
+ super(ctx)
101
+ end
102
+
103
+ def exceptionCaught(ctx, cause)
104
+ ::Server.log.warn "##{__method__} channel: #{ctx.channel}, cause: #{cause.message}"
105
+ cause.backtrace.each { |t| ::Server.log.error t }
106
+ listeners = notify :exception_caught, ctx, cause
107
+ super(ctx, cause) if listeners.empty?
108
+ end
109
+
110
+ IdentiferTemplate = '#<%<class>s:0x%<id>s>'.freeze
111
+
112
+ def to_s
113
+ format(IdentiferTemplate, class: self.class.name, id: object_id.to_s(16))
114
+ end
115
+ alias inspect to_s
116
+ end
117
+ # class ModularHandler
118
+ end
119
+ # module Server
@@ -0,0 +1,51 @@
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-2022 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
+ CHANNEL_TYPE = Java::io.netty.channel.socket.nio.NioServerSocketChannel.java_class
22
+
23
+ # The Server class sets up the netty server.
24
+ class Server
25
+ include ::Server::InstanceMethods
26
+ attr_reader :options
27
+
28
+ def initialize(params = {}, &block)
29
+ @options = params.fetch(:options, {})
30
+ configure_handlers(&block)
31
+ end
32
+
33
+ # rubocop: disable Metrics/AbcSize
34
+ def message_received(ctx, msg)
35
+ log.trace "##{__method__} channel: #{ctx.channel}, message: #{msg.inspect}"
36
+ msg&.chomp!
37
+ return if msg.nil? || msg.empty?
38
+ return ctx.close() if @options[:quit_commands].include?(msg.downcase.to_sym)
39
+ response = msg.upcase
40
+ log.debug "Sending response: #{response.inspect}"
41
+ ctx.writeAndFlush("#{response}\n")
42
+ end
43
+
44
+ def add_listener(listener)
45
+ ::Server::ChannelInitializer::DefaultHandler.add_listener(listener)
46
+ end
47
+ # rubocop: enable Metrics/AbcSize
48
+ end
49
+ # class Server
50
+ end
51
+ # module Server
@@ -0,0 +1,35 @@
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-2022 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
@@ -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-2022 but freely usable (see license)
10
+ #
11
+ # =end
12
+
13
+ # The Server module
14
+ module Server
15
+ VERSION = '1.0.1'.freeze
16
+ end
data/lib/server.rb ADDED
@@ -0,0 +1,59 @@
1
+ #! /usr/bin/env jruby
2
+
3
+ # encoding: utf-8
4
+ # frozen_string_literal: false
5
+
6
+ # -*- mode: ruby -*-
7
+ # vi: set ft=ruby :
8
+
9
+ # =begin
10
+ #
11
+ # Copyright Nels Nelson 2016-2022 but freely usable (see license)
12
+ #
13
+ # =end
14
+
15
+ require_relative 'log'
16
+ require_relative 'server/argument_parser'
17
+ require_relative 'server/server'
18
+
19
+ # The Server module
20
+ module Server
21
+ InterruptTemplate = "\r%<class>s".freeze
22
+
23
+ # The Demo class
24
+ class Demo
25
+ def channel_active(ctx)
26
+ ::Server.log.info "Channel active: #{ctx.channel}"
27
+ response = 'Hello, world!'
28
+ log.trace "Sending response: #{response.inspect}"
29
+ ctx.channel.writeAndFlush("#{response}\n")
30
+ end
31
+
32
+ def exception_caught(_ctx, cause)
33
+ ::Server.log.error "Exception caught: #{cause}"
34
+ cause.backtrace.each { |t| ::Server.log.error t }
35
+ ctx.close()
36
+ end
37
+ end
38
+
39
+ # rubocop: disable Metrics/AbcSize
40
+ # rubocop: disable Metrics/MethodLength
41
+ def main(args = parse_arguments)
42
+ Logging.log_level = args[:log_level]
43
+ server = ::Server::Server.new(options: args)
44
+ server.add_listener(::Server::Demo.new)
45
+ server.run
46
+ rescue Interrupt => e
47
+ warn format(InterruptTemplate, class: e.class)
48
+ exit
49
+ rescue StandardError => e
50
+ ::Server.log.fatal(e)
51
+ e.backtrace.each { |t| ::Server.log.fatal t }
52
+ exit 1
53
+ end
54
+ # rubocop: enable Metrics/AbcSize
55
+ # rubocop: enable Metrics/MethodLength
56
+ end
57
+ # module Server
58
+
59
+ Object.new.extend(::Server).main if $PROGRAM_NAME == __FILE__
metadata ADDED
@@ -0,0 +1,148 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tcp-server
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ platform: java
6
+ authors:
7
+ - Nels Nelson
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2022-04-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: 2.17.1
19
+ name: apache-log4j-2
20
+ prerelease: false
21
+ type: :runtime
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 2.17.1
27
+ - !ruby/object:Gem::Dependency
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: 1.70.1
33
+ name: bouncycastle
34
+ prerelease: false
35
+ type: :runtime
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.70.1
41
+ - !ruby/object:Gem::Dependency
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: 4.1.74
47
+ name: netty-io
48
+ prerelease: false
49
+ type: :runtime
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 4.1.74
55
+ - !ruby/object:Gem::Dependency
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: 12.3.0
61
+ name: rake
62
+ prerelease: false
63
+ type: :development
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 12.3.0
69
+ - !ruby/object:Gem::Dependency
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: 3.11.0
75
+ name: rspec
76
+ prerelease: false
77
+ type: :development
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 3.11.0
83
+ - !ruby/object:Gem::Dependency
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: 1.25.0
89
+ name: rubocop
90
+ prerelease: false
91
+ type: :development
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 1.25.0
97
+ description: TCP Server for JRuby is a tcp server which supports a demo echo server
98
+ application.
99
+ email: nels@nelsnelson.org
100
+ executables:
101
+ - tcp_server
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - LICENSE
106
+ - README.md
107
+ - Rakefile
108
+ - exe/tcp_server
109
+ - lib/client.rb
110
+ - lib/log.rb
111
+ - lib/server.rb
112
+ - lib/server/argument_parser.rb
113
+ - lib/server/channel_initializer.rb
114
+ - lib/server/config.rb
115
+ - lib/server/instance_methods.rb
116
+ - lib/server/listenable.rb
117
+ - lib/server/message_handler.rb
118
+ - lib/server/modular_handler.rb
119
+ - lib/server/server.rb
120
+ - lib/server/shutdown_hook.rb
121
+ - lib/server/version.rb
122
+ homepage: https://rubygems.org/gems/tcp-server-jruby
123
+ licenses:
124
+ - MIT
125
+ metadata:
126
+ source_code_uri: https://gitlab.com/nelsnelson/tcp-server-jruby
127
+ bug_tracker_uri: https://gitlab.com/nelsnelson/tcp-server-jruby/issues
128
+ rubygems_mfa_required: 'true'
129
+ post_install_message:
130
+ rdoc_options: []
131
+ require_paths:
132
+ - lib
133
+ required_ruby_version: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: 2.6.8
138
+ required_rubygems_version: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ requirements: []
144
+ rubygems_version: 3.2.29
145
+ signing_key:
146
+ specification_version: 4
147
+ summary: Server for JRuby packaged as a gem.
148
+ test_files: []