net-reactor 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/lib/net/reactor.rb +135 -0
  2. metadata +47 -0
@@ -0,0 +1,135 @@
1
+ # License: GPLv2
2
+ # Author: Tassilo Schweyer<welterde@arcor.de>
3
+ # Usage:
4
+ # require 'net/reactor'
5
+ # class Handler
6
+ # def initialize connection
7
+ # @connection = connection
8
+ # ...
9
+ # end
10
+ # def readEvent lines
11
+ # ...
12
+ # @connection.write lines[0]
13
+ # ...
14
+ # end
15
+ # end
16
+ # server = Net::Reactor::Server.new(4000, Handler)
17
+
18
+ begin
19
+ require 'rubygems'
20
+ rescue LoadError
21
+ # ignore
22
+ end
23
+ require 'io/reactor'
24
+ require 'socket'
25
+
26
+ module Net
27
+ module Reactor
28
+ class Server
29
+ def initialize(port, handler, host='0.0.0.0', interval=0.20)
30
+ @socket = TCPServer::new(host, port)
31
+ @handler = handler
32
+ @port = port
33
+ @pollInterval = interval
34
+ @reactor = IO::Reactor.new
35
+ @doShutdown = false
36
+ @connections = []
37
+
38
+ @reactor.register @socket, :read, &method(:handlePollEvent)
39
+ end
40
+
41
+ def handlePollEvent(socket, event)
42
+ case event
43
+ when :error
44
+ # TODO: log this error
45
+ shutdown
46
+ when :read
47
+ handleAccept(socket)
48
+ end
49
+ end
50
+
51
+ def handleAccept socket
52
+ sock = socket.accept
53
+ hand = Connection.new(sock, @handler, @reactor)
54
+ @reactor.register sock, :read, &hand.method(:handleIOEvent)
55
+ @connections << hand
56
+ end
57
+
58
+ def run
59
+ until @doShutdown
60
+ @reactor.poll(@pollInterval)
61
+ end
62
+ @connections.each do |connection|
63
+ @reactor.unregister connection.socket
64
+ connection.disconnected
65
+ end
66
+ end
67
+
68
+ def shutdown
69
+ @doShutdown = true
70
+ end
71
+ end
72
+
73
+ class Connection
74
+ MTU = 4096
75
+ CR = "\015"
76
+ LF = "\012"
77
+ EOL = CR + LF
78
+
79
+ def initialize(socket, handler, reactor)
80
+ @handler = handler.new self
81
+ @socket = socket
82
+ @reactor = reactor
83
+
84
+ @write_buffer = ''
85
+ @read_buffer = ''
86
+ end
87
+
88
+ def handleIOEvent(io, event)
89
+ case event
90
+ when :error
91
+ @handler.disconnected 'socket failed'
92
+ when :read
93
+ begin
94
+ handleRead
95
+ rescue EOFError
96
+ @handler.disconnected 'connection closed by remote host'
97
+ end
98
+ when :write
99
+ handleWrite
100
+ end
101
+ end
102
+
103
+ def write msg
104
+ @write_buffer << msg
105
+ @reactor.enableEvents(@socket, :write)
106
+ end
107
+
108
+ def handleWrite
109
+ bytes = @socket.syswrite(@write_buffer)
110
+ @write_buffer[ 0, bytes ] = '' if bytes.nonzero?
111
+ @reactor.disableEvents(@socket, :write) if @write_buffer.length.zero?
112
+ end
113
+
114
+ def handleRead
115
+ lines = []
116
+ @read_buffer << @socket.sysread(MTU)
117
+ if @read_buffer.index EOL
118
+ lines = @read_buffer.split EOL
119
+ else
120
+ lines = @read_buffer
121
+ end
122
+ @read_buffer[0, @read_buffer.length] = ''
123
+ @handler.readEvent lines
124
+ end
125
+
126
+ #delegate
127
+ def disconnected
128
+ @handler.disconnected 'socket closed'
129
+ end
130
+
131
+ attr_reader :socket
132
+ end
133
+ end
134
+ end
135
+
metadata ADDED
@@ -0,0 +1,47 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.0
3
+ specification_version: 1
4
+ name: net-reactor
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.0.1
7
+ date: 2007-04-05 00:00:00 +02:00
8
+ summary: An simple async network-engine for plain text
9
+ require_paths:
10
+ - lib
11
+ email:
12
+ homepage:
13
+ rubyforge_project:
14
+ description:
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: "true"
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Tassilo Schweyer
31
+ files:
32
+ - lib/net
33
+ - lib/net/reactor.rb
34
+ test_files: []
35
+
36
+ rdoc_options: []
37
+
38
+ extra_rdoc_files: []
39
+
40
+ executables: []
41
+
42
+ extensions: []
43
+
44
+ requirements: []
45
+
46
+ dependencies: []
47
+