async_tcpserver 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 +15 -0
- data/lib/async_tcpserver.rb +107 -0
- metadata +105 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
NGQyM2UwZmJhNjRkNjRjMjcxNmY4NTFjYThlMDE5M2FkZmYxZjQ0ZA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
NjFkODdiM2Y5Y2EwZjBiOGI5ODRmM2YzNDExZGNmM2RiMzc2MDUwZA==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
MTAxNjg3MzA0NmE0MzZiNWY1NGEyNTI2Y2MxOTIwMzI3OGMyMjFjYWRhYmY0
|
10
|
+
ZmE1NzRkZTU2MGI2ZGM0NGQ0OTc2ZjNkNTg0ZTBjYjJhZGQxNDYzM2FkMTg3
|
11
|
+
ZmNiNzVlOTc5YzJlYzVjYjM2ODBhYzBlZGU3MjE2ZmJkZGQzMzM=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
NTI4ODMwZjdmNzdiOWFjMWE0ZTYxMDY0YTQ1MTU1YzliYmQwYTI0Yjg4ZmVi
|
14
|
+
NGEzYmRhMWFjNDI5NDc5MzA3MzFhMGE5MzkxMmM0ZDgyY2ViZmU1YmZiNTBi
|
15
|
+
NmU1ZWNmZTU5NGE1MDdkMzI1ZjEwMmQzYzE2M2ZkZTVkMjA4MDg=
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'ready_pool'
|
2
|
+
require 'async_emitter'
|
3
|
+
require 'async_tcpsocket'
|
4
|
+
require 'thread'
|
5
|
+
|
6
|
+
################################################################################################
|
7
|
+
# Asynchronous TCP Server implementation
|
8
|
+
#
|
9
|
+
# Wraps TCPServer. The server emits,
|
10
|
+
# :connect to signal a new connection - a AsyncTCPSocket is passed to the Proc,
|
11
|
+
# :error to signal errors.
|
12
|
+
#
|
13
|
+
# If the accept method is called with the argument false it is non-blocking, otherwise it blocks;
|
14
|
+
# the example below blocks on the gets call as an example of a non-blocking accept.
|
15
|
+
#
|
16
|
+
# ==Example
|
17
|
+
#
|
18
|
+
# require "./lib/async_tcpserver"
|
19
|
+
#
|
20
|
+
# server = AsyncTCPServer.new 8000, 10
|
21
|
+
#
|
22
|
+
# server.on :error, Proc.new { |error|
|
23
|
+
# STDERR.puts "Error: #{error}"
|
24
|
+
# server.close
|
25
|
+
# }
|
26
|
+
#
|
27
|
+
# server.on :connect, Proc.new { |client|
|
28
|
+
# client.on :data, Proc.new { |data|
|
29
|
+
# client.puts data
|
30
|
+
# }
|
31
|
+
# }
|
32
|
+
#
|
33
|
+
# server.accept false
|
34
|
+
#
|
35
|
+
# gets
|
36
|
+
#
|
37
|
+
# server.close
|
38
|
+
#
|
39
|
+
# @author Greg Martin
|
40
|
+
##################################################################################################
|
41
|
+
class AsyncTCPServer < AsyncEmitter
|
42
|
+
|
43
|
+
#########################################################################################
|
44
|
+
# constructor
|
45
|
+
#
|
46
|
+
# @param hostname [String] optional host to bind to
|
47
|
+
# @param port [FixedNum] port to bind to
|
48
|
+
# @param num_threads [FixedNum] initial number of threads
|
49
|
+
########################################################################################
|
50
|
+
def initialize (*hostname, port, num_threads)
|
51
|
+
super()
|
52
|
+
|
53
|
+
@listen_thread = nil
|
54
|
+
@pool = ReadyPool.new num_threads, lambda { |client| thread_procedure client }
|
55
|
+
|
56
|
+
begin
|
57
|
+
if (hostname.length == 0)
|
58
|
+
@server = TCPServer.new port
|
59
|
+
else
|
60
|
+
@server = TCPServer.new hostname[0], port
|
61
|
+
end
|
62
|
+
rescue Exception => e
|
63
|
+
emit :error, e
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
#########################################################################################
|
70
|
+
# listen for connection requests
|
71
|
+
#
|
72
|
+
# @param blocking [Boolean] optional if set to false accept is non-blocking
|
73
|
+
########################################################################################
|
74
|
+
def accept (blocking=true)
|
75
|
+
if !blocking
|
76
|
+
@listen_thread = Thread.new do
|
77
|
+
loop do
|
78
|
+
client = @server.accept
|
79
|
+
@pool.start client
|
80
|
+
end
|
81
|
+
end
|
82
|
+
else
|
83
|
+
loop do
|
84
|
+
client = @server.accept
|
85
|
+
@pool.start client
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
#########################################################################################
|
91
|
+
# close server socket
|
92
|
+
########################################################################################
|
93
|
+
def close
|
94
|
+
@server.close
|
95
|
+
if @listen_thread != nil
|
96
|
+
Thread.kill @listen_thread
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
protected
|
101
|
+
def thread_procedure (client)
|
102
|
+
tcp_client = AsyncTCPSocket.new client
|
103
|
+
emit :connect, tcp_client
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
metadata
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: async_tcpserver
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Greg Martin
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-04-29 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: async_emitter
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.1'
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.1.1
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.1'
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.1.1
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: ready_pool
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ~>
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '1.1'
|
40
|
+
- - ! '>='
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 1.1.0
|
43
|
+
type: :runtime
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ~>
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '1.1'
|
50
|
+
- - ! '>='
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 1.1.0
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: async_tcpsocket
|
55
|
+
requirement: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ~>
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '1.0'
|
60
|
+
- - ! '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 1.0.0
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '1.0'
|
70
|
+
- - ! '>='
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: 1.0.0
|
73
|
+
description: An asyncronous tcp server for ruby
|
74
|
+
email: greg@softsprocket.com
|
75
|
+
executables: []
|
76
|
+
extensions: []
|
77
|
+
extra_rdoc_files: []
|
78
|
+
files:
|
79
|
+
- lib/async_tcpserver.rb
|
80
|
+
homepage: http://rubygems.org/gems/async_tcpserver.rb
|
81
|
+
licenses:
|
82
|
+
- MIT
|
83
|
+
metadata: {}
|
84
|
+
post_install_message:
|
85
|
+
rdoc_options: []
|
86
|
+
require_paths:
|
87
|
+
- lib
|
88
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ! '>='
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ! '>='
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
requirements: []
|
99
|
+
rubyforge_project:
|
100
|
+
rubygems_version: 2.4.6
|
101
|
+
signing_key:
|
102
|
+
specification_version: 4
|
103
|
+
summary: AsyncTCPServer
|
104
|
+
test_files: []
|
105
|
+
has_rdoc:
|