tiny_tcp_service 1.0.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 +7 -0
- data/lib/tiny_tcp_service.rb +94 -0
- metadata +43 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 7a9d89a4cf5f6578a0f606fe0c24cb81495fe2c96cfea70074670f2e9a3fd3ac
|
4
|
+
data.tar.gz: 50b6169a75272e14a07fbd17fc2b6575a3c8010bc580776ad456ee3786eca5bf
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d80e1a3243cb5102bc776d19759c0c5ffed178ccbf7b96aaa895bf18144675be725fc0b7df7f42b877358b980fd9e16d5588a39bc4434bd6f5231c90630d23ae
|
7
|
+
data.tar.gz: 73fc25a0c4b58609a711694840c3227717412aca82a84623884aa3b1f7539f8e318cb1310913f139dd4114c9010804d7df6ed48ede08450d4c4433156fdb9ece
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'socket'
|
2
|
+
|
3
|
+
# usage:
|
4
|
+
# s = TinyTCPService.new(
|
5
|
+
# 1234,
|
6
|
+
# ->(m) { puts m }
|
7
|
+
# )
|
8
|
+
#
|
9
|
+
# s.start! # everything runs in background threads
|
10
|
+
# s.stop! # gracefully shutdown the server
|
11
|
+
class TinyTCPService
|
12
|
+
def initialize(port, msg_handler)
|
13
|
+
@port = port
|
14
|
+
@msg_handler = msg_handler
|
15
|
+
|
16
|
+
@server = TCPServer.new(port)
|
17
|
+
@clients = []
|
18
|
+
@running = false
|
19
|
+
@error_handlers = {}
|
20
|
+
end
|
21
|
+
|
22
|
+
# returns true if the server is running
|
23
|
+
# false otherwise
|
24
|
+
def running?
|
25
|
+
@running
|
26
|
+
end
|
27
|
+
|
28
|
+
# add the error handler and block for the specified class
|
29
|
+
#
|
30
|
+
# you can assume that the local variable name of the error will be `e'
|
31
|
+
def add_error_handler(klass, block)
|
32
|
+
@error_handlers[klass] = block
|
33
|
+
end
|
34
|
+
|
35
|
+
# remove the error handler associated with klass
|
36
|
+
def remove_error_handler(klass)
|
37
|
+
@error_handlers.delete(klass)
|
38
|
+
end
|
39
|
+
|
40
|
+
# returns the number of connected clients
|
41
|
+
def num_clients
|
42
|
+
@clients.length
|
43
|
+
end
|
44
|
+
|
45
|
+
# starts the server
|
46
|
+
def start!
|
47
|
+
return if running?
|
48
|
+
@running = true
|
49
|
+
|
50
|
+
# client accept thread
|
51
|
+
Thread.new do |t|
|
52
|
+
loop do
|
53
|
+
break unless running?
|
54
|
+
@clients << @server.accept
|
55
|
+
end
|
56
|
+
|
57
|
+
@clients.each{|c| c.close if c && !c.closed? }
|
58
|
+
@server.close
|
59
|
+
end
|
60
|
+
|
61
|
+
# service thread
|
62
|
+
Thread.new do |t|
|
63
|
+
loop do
|
64
|
+
break unless running?
|
65
|
+
|
66
|
+
readable, _, errored = IO.select(@clients, nil, @clients, 1)
|
67
|
+
readable&.each do |client|
|
68
|
+
begin
|
69
|
+
@msg_handler.call(client.gets.chomp)
|
70
|
+
rescue => e
|
71
|
+
handler = @error_handlers[e.class]
|
72
|
+
|
73
|
+
if handler
|
74
|
+
handler.call(e)
|
75
|
+
else
|
76
|
+
stop!
|
77
|
+
raise e unless handler
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
errored&.each do |client|
|
83
|
+
@clients.delete(client)
|
84
|
+
client.close if client && !client.closed?
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# stops the server gracefully
|
91
|
+
def stop!
|
92
|
+
@running = false
|
93
|
+
end
|
94
|
+
end
|
metadata
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tiny_tcp_service
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jeff Lunt
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-10-29 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: a tiny TCP service with automated client lifecycle
|
14
|
+
email: jefflunt@gmail.com
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- lib/tiny_tcp_service.rb
|
20
|
+
homepage: https://github.com/jefflunt/tiny_tcp_service
|
21
|
+
licenses:
|
22
|
+
- MIT
|
23
|
+
metadata: {}
|
24
|
+
post_install_message:
|
25
|
+
rdoc_options: []
|
26
|
+
require_paths:
|
27
|
+
- lib
|
28
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
34
|
+
requirements:
|
35
|
+
- - ">="
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
requirements: []
|
39
|
+
rubygems_version: 3.3.7
|
40
|
+
signing_key:
|
41
|
+
specification_version: 4
|
42
|
+
summary: a tiny TCP service with automated client lifecycle
|
43
|
+
test_files: []
|