tcp-server 1.0.1-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []