eventmachine 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. data/COPYING +281 -0
  2. data/README +69 -0
  3. data/RELEASE_NOTES +18 -0
  4. data/doc/classes/Echo.html +180 -0
  5. data/doc/classes/Echo.src/M000033.html +23 -0
  6. data/doc/classes/Echo.src/M000034.html +19 -0
  7. data/doc/classes/Echo.src/M000035.html +19 -0
  8. data/doc/classes/Echo.src/M000036.html +18 -0
  9. data/doc/classes/EventMachine.html +369 -0
  10. data/doc/classes/EventMachine.src/M000002.html +24 -0
  11. data/doc/classes/EventMachine.src/M000003.html +24 -0
  12. data/doc/classes/EventMachine.src/M000004.html +26 -0
  13. data/doc/classes/EventMachine.src/M000005.html +21 -0
  14. data/doc/classes/EventMachine.src/M000006.html +23 -0
  15. data/doc/classes/EventMachine.src/M000007.html +28 -0
  16. data/doc/classes/EventMachine.src/M000008.html +20 -0
  17. data/doc/classes/EventMachine.src/M000009.html +19 -0
  18. data/doc/classes/EventMachine.src/M000010.html +18 -0
  19. data/doc/classes/EventMachine.src/M000011.html +18 -0
  20. data/doc/classes/EventMachine/Connection.html +341 -0
  21. data/doc/classes/EventMachine/Connection.src/M000020.html +19 -0
  22. data/doc/classes/EventMachine/Connection.src/M000021.html +17 -0
  23. data/doc/classes/EventMachine/Connection.src/M000022.html +18 -0
  24. data/doc/classes/EventMachine/Connection.src/M000023.html +17 -0
  25. data/doc/classes/EventMachine/Connection.src/M000024.html +18 -0
  26. data/doc/classes/EventMachine/Connection.src/M000025.html +18 -0
  27. data/doc/classes/EventMachine/Connection.src/M000026.html +18 -0
  28. data/doc/classes/EventMachine/Connection.src/M000027.html +18 -0
  29. data/doc/classes/EventMachine/Connection.src/M000028.html +17 -0
  30. data/doc/classes/EventMachine/Connection.src/M000029.html +18 -0
  31. data/doc/classes/EventMachine/Connection.src/M000030.html +18 -0
  32. data/doc/classes/EventMachine/Connection.src/M000031.html +18 -0
  33. data/doc/classes/EventMachine/Connection.src/M000032.html +18 -0
  34. data/doc/classes/EventMachine/ConnectionAlreadyBound.html +111 -0
  35. data/doc/classes/EventMachine/ConnectionNotBound.html +111 -0
  36. data/doc/classes/EventMachine/Connections.html +292 -0
  37. data/doc/classes/EventMachine/Connections.src/M000012.html +20 -0
  38. data/doc/classes/EventMachine/Connections.src/M000013.html +23 -0
  39. data/doc/classes/EventMachine/Connections.src/M000014.html +23 -0
  40. data/doc/classes/EventMachine/Connections.src/M000015.html +24 -0
  41. data/doc/classes/EventMachine/Connections.src/M000016.html +19 -0
  42. data/doc/classes/EventMachine/Connections.src/M000017.html +21 -0
  43. data/doc/classes/EventMachine/Connections.src/M000018.html +19 -0
  44. data/doc/classes/EventMachine/Connections.src/M000019.html +20 -0
  45. data/doc/classes/EventMachine/EventCodes.html +133 -0
  46. data/doc/classes/EventMachine/NoConnectionMade.html +111 -0
  47. data/doc/classes/EventMachine/NoHandlerForAcceptedConnection.html +111 -0
  48. data/doc/classes/EventMachine/NoServerCreated.html +111 -0
  49. data/doc/classes/EventMachine/TimerNotInstalled.html +111 -0
  50. data/doc/classes/EventMachine/TooManyAcceptors.html +111 -0
  51. data/doc/classes/EventMachine/TooManyTimersPending.html +111 -0
  52. data/doc/classes/EventMachine/UnknownTimerFired.html +111 -0
  53. data/doc/classes/Zzz.html +131 -0
  54. data/doc/classes/Zzz.src/M000001.html +18 -0
  55. data/doc/created.rid +1 -0
  56. data/doc/files/binder_cpp.html +101 -0
  57. data/doc/files/ed_cpp.html +101 -0
  58. data/doc/files/em_cpp.html +101 -0
  59. data/doc/files/event_machine_rb.html +118 -0
  60. data/doc/files/g_rb.html +108 -0
  61. data/doc/files/lib/eventmachine_rb.html +114 -0
  62. data/doc/files/libmain_cpp.html +101 -0
  63. data/doc/files/sigs_cpp.html +101 -0
  64. data/doc/files/tests/testem_rb.html +110 -0
  65. data/doc/fr_class_index.html +41 -0
  66. data/doc/fr_file_index.html +35 -0
  67. data/doc/fr_method_index.html +62 -0
  68. data/doc/index.html +24 -0
  69. data/ext/libeventmachine.so +0 -0
  70. data/lib/eventmachine.rb +631 -0
  71. data/tests/testem.rb +5 -0
  72. metadata +121 -0
@@ -0,0 +1,41 @@
1
+
2
+ <?xml version="1.0" encoding="iso-8859-1"?>
3
+ <!DOCTYPE html
4
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
5
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
6
+
7
+ <!--
8
+
9
+ Classes
10
+
11
+ -->
12
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
13
+ <head>
14
+ <title>Classes</title>
15
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
16
+ <link rel="stylesheet" href="rdoc-style.css" type="text/css" />
17
+ <base target="docwin" />
18
+ </head>
19
+ <body>
20
+ <div id="index">
21
+ <h1 class="section-bar">Classes</h1>
22
+ <div id="index-entries">
23
+ <a href="classes/Echo.html">Echo</a><br />
24
+ <a href="classes/EventMachine.html">EventMachine</a><br />
25
+ <a href="classes/EventMachine/Connection.html">EventMachine::Connection</a><br />
26
+ <a href="classes/EventMachine/ConnectionAlreadyBound.html">EventMachine::ConnectionAlreadyBound</a><br />
27
+ <a href="classes/EventMachine/ConnectionNotBound.html">EventMachine::ConnectionNotBound</a><br />
28
+ <a href="classes/EventMachine/Connections.html">EventMachine::Connections</a><br />
29
+ <a href="classes/EventMachine/EventCodes.html">EventMachine::EventCodes</a><br />
30
+ <a href="classes/EventMachine/NoConnectionMade.html">EventMachine::NoConnectionMade</a><br />
31
+ <a href="classes/EventMachine/NoHandlerForAcceptedConnection.html">EventMachine::NoHandlerForAcceptedConnection</a><br />
32
+ <a href="classes/EventMachine/NoServerCreated.html">EventMachine::NoServerCreated</a><br />
33
+ <a href="classes/EventMachine/TimerNotInstalled.html">EventMachine::TimerNotInstalled</a><br />
34
+ <a href="classes/EventMachine/TooManyAcceptors.html">EventMachine::TooManyAcceptors</a><br />
35
+ <a href="classes/EventMachine/TooManyTimersPending.html">EventMachine::TooManyTimersPending</a><br />
36
+ <a href="classes/EventMachine/UnknownTimerFired.html">EventMachine::UnknownTimerFired</a><br />
37
+ <a href="classes/Zzz.html">Zzz</a><br />
38
+ </div>
39
+ </div>
40
+ </body>
41
+ </html>
@@ -0,0 +1,35 @@
1
+
2
+ <?xml version="1.0" encoding="iso-8859-1"?>
3
+ <!DOCTYPE html
4
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
5
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
6
+
7
+ <!--
8
+
9
+ Files
10
+
11
+ -->
12
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
13
+ <head>
14
+ <title>Files</title>
15
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
16
+ <link rel="stylesheet" href="rdoc-style.css" type="text/css" />
17
+ <base target="docwin" />
18
+ </head>
19
+ <body>
20
+ <div id="index">
21
+ <h1 class="section-bar">Files</h1>
22
+ <div id="index-entries">
23
+ <a href="files/binder_cpp.html">binder.cpp</a><br />
24
+ <a href="files/ed_cpp.html">ed.cpp</a><br />
25
+ <a href="files/em_cpp.html">em.cpp</a><br />
26
+ <a href="files/event_machine_rb.html">event_machine.rb</a><br />
27
+ <a href="files/g_rb.html">g.rb</a><br />
28
+ <a href="files/lib/eventmachine_rb.html">lib/eventmachine.rb</a><br />
29
+ <a href="files/libmain_cpp.html">libmain.cpp</a><br />
30
+ <a href="files/sigs_cpp.html">sigs.cpp</a><br />
31
+ <a href="files/tests/testem_rb.html">tests/testem.rb</a><br />
32
+ </div>
33
+ </div>
34
+ </body>
35
+ </html>
@@ -0,0 +1,62 @@
1
+
2
+ <?xml version="1.0" encoding="iso-8859-1"?>
3
+ <!DOCTYPE html
4
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
5
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
6
+
7
+ <!--
8
+
9
+ Methods
10
+
11
+ -->
12
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
13
+ <head>
14
+ <title>Methods</title>
15
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
16
+ <link rel="stylesheet" href="rdoc-style.css" type="text/css" />
17
+ <base target="docwin" />
18
+ </head>
19
+ <body>
20
+ <div id="index">
21
+ <h1 class="section-bar">Methods</h1>
22
+ <div id="index-entries">
23
+ <a href="classes/EventMachine/Connections.html#M000019">accept_connection (EventMachine::Connections)</a><br />
24
+ <a href="classes/EventMachine.html#M000004">add_periodic_timer (EventMachine)</a><br />
25
+ <a href="classes/EventMachine/Connections.html#M000017">add_timer (EventMachine::Connections)</a><br />
26
+ <a href="classes/EventMachine.html#M000003">add_timer (EventMachine)</a><br />
27
+ <a href="classes/EventMachine.html#M000008">add_timer (EventMachine)</a><br />
28
+ <a href="classes/EventMachine/Connection.html#M000031">close_connection (EventMachine::Connection)</a><br />
29
+ <a href="classes/EventMachine/Connection.html#M000024">close_connection (EventMachine::Connection)</a><br />
30
+ <a href="classes/EventMachine/Connection.html#M000032">close_connection_after_writing (EventMachine::Connection)</a><br />
31
+ <a href="classes/EventMachine/Connection.html#M000025">close_connection_after_writing (EventMachine::Connection)</a><br />
32
+ <a href="classes/EventMachine/Connections.html#M000013">connect (EventMachine::Connections)</a><br />
33
+ <a href="classes/EventMachine.html#M000006">connect (EventMachine)</a><br />
34
+ <a href="classes/EventMachine.html#M000010">connect (EventMachine)</a><br />
35
+ <a href="classes/EventMachine.html#M000007">connection_callback (EventMachine)</a><br />
36
+ <a href="classes/EventMachine/Connection.html#M000027">new (EventMachine::Connection)</a><br />
37
+ <a href="classes/EventMachine/Connections.html#M000012">new (EventMachine::Connections)</a><br />
38
+ <a href="classes/EventMachine/Connection.html#M000020">new (EventMachine::Connection)</a><br />
39
+ <a href="classes/Echo.html#M000034">post_init (Echo)</a><br />
40
+ <a href="classes/EventMachine/Connection.html#M000021">post_init (EventMachine::Connection)</a><br />
41
+ <a href="classes/Zzz.html#M000001">receive_data (Zzz)</a><br />
42
+ <a href="classes/Echo.html#M000033">receive_data (Echo)</a><br />
43
+ <a href="classes/EventMachine/Connections.html#M000016">receive_data (EventMachine::Connections)</a><br />
44
+ <a href="classes/EventMachine/Connection.html#M000022">receive_data (EventMachine::Connection)</a><br />
45
+ <a href="classes/EventMachine/Connection.html#M000030">receive_data (EventMachine::Connection)</a><br />
46
+ <a href="classes/Echo.html#M000035">receive_data (Echo)</a><br />
47
+ <a href="classes/EventMachine.html#M000009">run (EventMachine)</a><br />
48
+ <a href="classes/EventMachine.html#M000002">run (EventMachine)</a><br />
49
+ <a href="classes/EventMachine/Connections.html#M000018">run_timer (EventMachine::Connections)</a><br />
50
+ <a href="classes/EventMachine/Connection.html#M000029">send_data (EventMachine::Connection)</a><br />
51
+ <a href="classes/EventMachine/Connection.html#M000026">send_data (EventMachine::Connection)</a><br />
52
+ <a href="classes/EventMachine.html#M000011">start_server (EventMachine)</a><br />
53
+ <a href="classes/EventMachine/Connections.html#M000014">start_server (EventMachine::Connections)</a><br />
54
+ <a href="classes/EventMachine.html#M000005">start_server (EventMachine)</a><br />
55
+ <a href="classes/EventMachine/Connection.html#M000028">unbind (EventMachine::Connection)</a><br />
56
+ <a href="classes/Echo.html#M000036">unbind (Echo)</a><br />
57
+ <a href="classes/EventMachine/Connection.html#M000023">unbind (EventMachine::Connection)</a><br />
58
+ <a href="classes/EventMachine/Connections.html#M000015">unbind_connection (EventMachine::Connections)</a><br />
59
+ </div>
60
+ </div>
61
+ </body>
62
+ </html>
data/doc/index.html ADDED
@@ -0,0 +1,24 @@
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <!DOCTYPE html
3
+ PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
4
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
5
+
6
+ <!--
7
+
8
+ RDoc Documentation
9
+
10
+ -->
11
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
12
+ <head>
13
+ <title>RDoc Documentation</title>
14
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
15
+ </head>
16
+ <frameset rows="20%, 80%">
17
+ <frameset cols="25%,35%,45%">
18
+ <frame src="fr_file_index.html" title="Files" name="Files" />
19
+ <frame src="fr_class_index.html" name="Classes" />
20
+ <frame src="fr_method_index.html" name="Methods" />
21
+ </frameset>
22
+ <frame src="files/binder_cpp.html" name="docwin" />
23
+ </frameset>
24
+ </html>
Binary file
@@ -0,0 +1,631 @@
1
+ # $Id: eventmachine.rb 2281 2006-04-13 05:09:13Z francis $
2
+ #
3
+ # Author:: blackhedd (gmail address: garbagecat20).
4
+ # Date:: 8 Apr 2006
5
+ #
6
+ # Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
7
+ #
8
+ # This program is made available under the terms of the GPL version 2.
9
+ #
10
+ # See EventMachine and EventMachine::Connection for documentation and
11
+ # usage examples.
12
+ #
13
+
14
+ require 'libeventmachine'
15
+
16
+ # == Introduction
17
+ # EventMachine provides a fast, lightweight framework for implementing
18
+ # Ruby programs that can use the network to communicate with other
19
+ # processes. Using EventMachine, Ruby programmers can easily connect
20
+ # to remote servers and act as servers themselves. EventMachine does not
21
+ # supplant the Ruby IP libraries. It does provide an alternate technique
22
+ # for those applications requiring better performance, scalability,
23
+ # and discipline over the behavior of network sockets, than is easily
24
+ # obtainable using the built-in libraries, especially in applications
25
+ # which are structurally well-suited for the event-driven programming model.
26
+ #
27
+ # EventMachine provides a perpetual event-loop which your programs can
28
+ # start and stop. Within the event loop, TCP network connections are
29
+ # initiated and accepted, based on EventMachine methods called by your
30
+ # program. You also define callback methods which are called by EventMachine
31
+ # when events of interest occur within the event-loop.
32
+ #
33
+ # User programs will be called back when the following events occur:
34
+ # * When the event loop accepts network connections from remote peers
35
+ # * When data is received from network connections
36
+ # * When connections are closed, either by the local or the remote side
37
+ # * When user-defined timers expire
38
+ #
39
+ # == Usage example
40
+ #
41
+ # Here's a fully-functional echo server implemented in EventMachine:
42
+ #
43
+ # require 'rubygems'
44
+ # require_gem 'eventmachine'
45
+ #
46
+ # module EchoServer
47
+ # def receive_data data
48
+ # send_data ">>>you sent: #{data}"
49
+ # close_connection if data =~ /quit/i
50
+ # end
51
+ # end
52
+ #
53
+ # EventMachine::run {
54
+ # EventMachine::start_server "192.168.0.100", 8081, EchoServer
55
+ # }
56
+ #
57
+ # What's going on here? Well, we have defined the module EchoServer to
58
+ # implement the semantics of the echo protocol (more about that shortly).
59
+ # The last three lines invoke the event-machine itself, which runs forever
60
+ # unless one of your callbacks terminates it. The block that you supply
61
+ # to EventMachine::run contains code that runs immediately after the event
62
+ # machine is initialized and before it starts looping. This is the place
63
+ # to open up a TCP server by specifying the address and port it will listen
64
+ # on, together with the module that will process the data.
65
+ #
66
+ # Our EchoServer is extremely simple as the echo protocol doesn't require
67
+ # much work. Basically you want to send back to the remote peer whatever
68
+ # data it sends you. We'll dress it up with a little extra text to make it
69
+ # interesting. Also, we'll close the connection in case the received data
70
+ # contains the word "quit."
71
+ #
72
+ # So what about this module EchoServer? Well, whenever a network connection
73
+ # (either a client or a server) starts up, EventMachine instantiates an anonymous
74
+ # class, that your module has been mixed into. Exactly one of these class
75
+ # instances is created for each connection. Whenever an event occurs on a
76
+ # given connection, its corresponding object automatically calls specific
77
+ # instance methods which your module may redefine. The code in your module
78
+ # always runs in the context of a class instance, so you can create instance
79
+ # variables as you wish and they will be carried over to other callbacks
80
+ # made on that same connection.
81
+ #
82
+ # Looking back up at EchoServer, you can see that we've defined the method
83
+ # receive_data which (big surprise) is called whenever data has been received
84
+ # from the remote end of the connection. Very simple. We get the data
85
+ # (a String object) and can do whatever we wish with it. In this case,
86
+ # we use the method send_data to return the received data to the caller,
87
+ # with some extra text added in. And if the user sends the word "quit,"
88
+ # we'll close the connection with (naturally) close_connection.
89
+ # (Notice that closing the connection doesn't terminate the processing loop,
90
+ # or change the fact that your echo server is still accepting connections!)
91
+ #
92
+ #
93
+ # == Questions and Futures
94
+ # Encryption: EventMachine needs the capability to run SSL/TLS on any
95
+ # of its clients and servers. Coming soon.
96
+ #
97
+ # <tt>epoll(4):</tt> EventMachine currently is based on the <tt>select(2)</tt>
98
+ # system call in order to be compatible with the widest variety of platforms,
99
+ # but it would be interesting to re-base it on <tt>epoll(4).</tt>
100
+ # While requiring a Linux 2.6 kernel, this might possibly give much better
101
+ # performance and scalability. EventMachine's C++ antecedents already work
102
+ # with <tt>kqueue</tt> from the BSD world, but it's not yet clear that this
103
+ # is worth doing. Depends on how many people ask for it.
104
+ #
105
+ # Would it be useful for EventMachine to incorporate the Observer pattern
106
+ # and make use of the corresponding Ruby <tt>observer</tt> package?
107
+ # Interesting thought.
108
+ #
109
+ #
110
+ module EventMachine
111
+
112
+
113
+ # EventMachine::run initializes and runs an event loop.
114
+ # This method only returns if user-callback code calls stop_event_loop.
115
+ # Use the supplied block to define your clients and servers.
116
+ # The block is called by EventMachine::run immediately after initializing
117
+ # its internal event loop but <i>before</i> running the loop.
118
+ # Therefore this block is the right place to call start_server if you
119
+ # want to accept connections from remote clients.
120
+ #
121
+ # For programs that are structured as servers, it's usually appropriate
122
+ # to start an event loop by calling EventMachine::run, and let it
123
+ # run forever. It's also possible to use EventMachine::run to make a single
124
+ # client-connection to a remote server, process the data flow from that
125
+ # single connection, and then call stop_event_loop to force EventMachine::run
126
+ # to return. Your program will then continue from the point immediately
127
+ # following the call to EventMachine::run.
128
+ #
129
+ # You can of course do both client and servers simultaneously in the same program.
130
+ # One of the strengths of the event-driven programming model is that the
131
+ # handling of network events on many different connections will be interleaved,
132
+ # and scheduled according to the actual events themselves. This maximizes
133
+ # efficiency.
134
+ #
135
+ # === Server usage example
136
+ #
137
+ # See the text at the top of this file for an example of an echo server.
138
+ #
139
+ # === Client usage example
140
+ #
141
+ # See the description of stop_event_loop for an extremely simple client example.
142
+ #
143
+
144
+ def EventMachine::run &block
145
+ @conns = {}
146
+ @acceptors = {}
147
+ @timers = {}
148
+ initialize_event_machine
149
+ block and add_timer 0, block
150
+ run_machine
151
+ release_machine
152
+ end
153
+
154
+ # EventMachine#add_timer adds a one-shot timer to the event loop.
155
+ # Call it with one or two parameters. The first parameters is a delay-time
156
+ # expressed in <i>seconds</i> (not milliseconds). The second parameter, if
157
+ # present, must be a proc object. If a proc object is not given, then you
158
+ # can also simply pass a block to the method call.
159
+ #
160
+ # EventMachine#add_timer may be called from the block passed to EventMachine#run
161
+ # or from any callback method. It schedules execution of the proc or block
162
+ # passed to add_timer, after the passage of an interval of time equal to
163
+ # <i>at least</i> the number of seconds specified in the first parameter to
164
+ # the call.
165
+ #
166
+ # EventMachine#add_timer is a <i>non-blocking</i> call. Callbacks can and will
167
+ # be called during the interval of time that the timer is in effect.
168
+ # There is no built-in limit to the number of timers that can be outstanding at
169
+ # any given time.
170
+ #
171
+ # === Usage example
172
+ #
173
+ # This example shows how easy timers are to use. Observe that two timers are
174
+ # initiated simultaneously. Also, notice that the event loop will continue
175
+ # to run even after the second timer event is processed, since there was
176
+ # no call to EventMachine#stop_event_loop. There will be no activity, of
177
+ # course, since no network clients or servers are defined. Stop the program
178
+ # with Ctrl-C.
179
+ #
180
+ # require 'rubygems'
181
+ # require_gem 'eventmachine'
182
+ #
183
+ # EventMachine::run {
184
+ # puts "Starting the run now: #{Time.now}"
185
+ # EventMachine::add_timer 5, proc { puts "Executing timer event: #{Time.now}" }
186
+ # EventMachine::add_timer( 10 ) { puts "Executing timer event: #{Time.now}" }
187
+ # }
188
+ #
189
+ #
190
+ def EventMachine::add_timer *args, &block
191
+ interval = args.shift
192
+ code = args.shift || block
193
+ if code
194
+ # check too many timers!
195
+ s = add_oneshot_timer interval
196
+ @timers[s] = code
197
+ end
198
+ end
199
+
200
+ # EventMachine#add_periodic_timer adds a periodic timer to the event loop.
201
+ # It takes the same parameters as the one-shot timer method, EventMachine#add_timer.
202
+ # This method schedules execution of the given block repeatedly, at intervals
203
+ # of time <i>at least</i> as great as the number of seconds given in the first
204
+ # parameter to the call.
205
+ #
206
+ # === Usage example
207
+ #
208
+ # The following sample program will write a dollar-sign to stderr every five seconds.
209
+ # (Of course if the program defined network clients and/or servers, they would
210
+ # be doing their work while the periodic timer is counting off.)
211
+ #
212
+ # EventMachine::run {
213
+ # EventMachine::add_periodic_timer( 5 ) { $stderr.write "$" }
214
+ # }
215
+ #
216
+ def EventMachine::add_periodic_timer *args, &block
217
+ interval = args.shift
218
+ code = args.shift || block
219
+ if code
220
+ block_1 = proc {
221
+ code.call
222
+ EventMachine::add_periodic_timer interval, code
223
+ }
224
+ add_timer interval, block_1
225
+ end
226
+ end
227
+
228
+
229
+ # stop_event_loop may called from within a callback method
230
+ # while EventMachine's processing loop is running.
231
+ # It causes the processing loop to stop executing, which
232
+ # will cause all open connections and accepting servers
233
+ # to be run down and closed. <i>Callbacks for connection-termination
234
+ # will be called</i> as part of the processing of stop_event_loop.
235
+ # (There currently is no option to panic-stop the loop without
236
+ # closing connections.) When all of this processing is complete,
237
+ # the call to EventMachine::run which started the processing loop
238
+ # will return and program flow will resume from the statement
239
+ # following EventMachine::run call.
240
+ #
241
+ # === Usage example
242
+ #
243
+ # require 'rubygems'
244
+ # require_gem 'eventmachine'
245
+ #
246
+ # module Redmond
247
+ #
248
+ # def post_init
249
+ # puts "We're sending a dumb HTTP request to the remote peer."
250
+ # send_data "GET / HTTP/1.1\r\nHost: www.microsoft.com\r\n\r\n"
251
+ # end
252
+ #
253
+ # def receive_data data
254
+ # puts "We received #{data.length} bytes from the remote peer."
255
+ # puts "We're going to stop the event loop now."
256
+ # EventMachine::stop_event_loop
257
+ # end
258
+ #
259
+ # def unbind
260
+ # puts "A connection has terminated."
261
+ # end
262
+ #
263
+ # end
264
+ #
265
+ # puts "We're starting the event loop now."
266
+ # EventMachine::run {
267
+ # EventMachine::connect "www.microsoft.com", 80, Redmond
268
+ # }
269
+ # puts "The event loop has stopped."
270
+ #
271
+ # This program will produce approximately the following output:
272
+ #
273
+ # We're starting the event loop now.
274
+ # We're sending a dumb HTTP request to the remote peer.
275
+ # We received 1440 bytes from the remote peer.
276
+ # We're going to stop the event loop now.
277
+ # A connection has terminated.
278
+ # The event loop has stopped.
279
+ #
280
+ #
281
+ def EventMachine::stop_event_loop
282
+ EventMachine::stop
283
+ end
284
+
285
+ # EventMachine::start_server initiates a TCP server (socket
286
+ # acceptor) on the specified IP address and port.
287
+ # The IP address must be valid on the machine where the program
288
+ # runs, and the process must be privileged enough to listen
289
+ # on the specified port (on Unix-like systems, superuser privileges
290
+ # are usually required to listen on any port lower than 1024).
291
+ # Only one listener may be running on any given address/port
292
+ # combination. start_server will fail if the given address and port
293
+ # are already listening on the machine, either because of a prior call
294
+ # to start_server or some unrelated process running on the machine.
295
+ # If start_server succeeds, the new network listener becomes active
296
+ # immediately and starts accepting connections from remote peers,
297
+ # and these connections generate callback events that are processed
298
+ # by the code specified in the handler parameter to start_server.
299
+ #
300
+ # The optional handler which is passed to start_server is the key
301
+ # to EventMachine's ability to handle particular network protocols.
302
+ # The handler parameter passed to start_server must be a Ruby Module
303
+ # that you must define. When the network server that is started by
304
+ # start_server accepts a new connection, it instantiates a new
305
+ # object of an anonymous class that is inherited from EventMachine::Connection,
306
+ # <i>into which the methods from your handler have been mixed.</i>
307
+ # Your handler module may redefine any of the methods in EventMachine::Connection
308
+ # in order to implement the specific behavior of the network protocol.
309
+ #
310
+ # Callbacks invoked in response to network events <i>always</i> take place
311
+ # within the execution context of the object derived from EventMachine::Connection
312
+ # extended by your handler module. There is one object per connection, and
313
+ # all of the callbacks invoked for a particular connection take the form
314
+ # of instance methods called against the corresponding EventMachine::Connection
315
+ # object. Therefore, you are free to define whatever instance variables you
316
+ # wish, in order to contain the per-connection state required by the network protocol you are
317
+ # implementing.
318
+ #
319
+ # start_server is often called inside the block passed to EventMachine::run,
320
+ # but it can be called from any EventMachine callback. start_server will fail
321
+ # unless the EventMachine event loop is currently running (which is why
322
+ # it's often called in the block suppled to EventMachine::run).
323
+ #
324
+ # You may call start_server any number of times to start up network
325
+ # listeners on different address/port combinations. The servers will
326
+ # all run simultaneously. More interestingly, each individual call to start_server
327
+ # can specify a different handler module and thus implement a different
328
+ # network protocol from all the others.
329
+ #
330
+ # === Usage example
331
+ # Here is an example of a server that counts lines of input from the remote
332
+ # peer and sends back the total number of lines received, after each line.
333
+ # Try the example with more than one client connection opened via telnet,
334
+ # and you will see that the line count increments independently on each
335
+ # of the client connections. Also very important to note, is that the
336
+ # handler for the receive_data function, which our handler redefines, may
337
+ # not assume that the data it receives observes any kind of message boundaries.
338
+ # Also, to use this example, be sure to change the server and port parameters
339
+ # to the start_server call to values appropriate for your environment.
340
+ #
341
+ # require 'rubygems'
342
+ # require_gem 'eventmachine'
343
+ #
344
+ # module LineCounter
345
+ #
346
+ # MaxLinesPerConnection = 10
347
+ #
348
+ # def post_init
349
+ # puts "Received a new connection"
350
+ # @data_received = ""
351
+ # @line_count = 0
352
+ # end
353
+ #
354
+ # def receive_data data
355
+ # @data_received << data
356
+ # while @data_received.slice!( /^[^\n]*[\n]/m )
357
+ # @line_count += 1
358
+ # send_data "received #{@line_count} lines so far\r\n"
359
+ # @line_count == MaxLinesPerConnection and close_connection_after_writing
360
+ # end
361
+ # end
362
+ #
363
+ # end # module LineCounter
364
+ #
365
+ # EventMachine::run {
366
+ # host,port = "192.168.0.100", 8090
367
+ # EventMachine::start_server host, port, LineCounter
368
+ # puts "Now accepting connections on address #{host}, port #{port}..."
369
+ # EventMachine::add_periodic_timer( 10 ) { $stderr.write "*" }
370
+ # }
371
+ #
372
+ #
373
+ def EventMachine::start_server server, port, handler=nil
374
+ s = start_tcp_server server, port
375
+ @acceptors[s] = Class.new( Connection ) {
376
+ handler and include handler
377
+ }
378
+ end
379
+
380
+ # EventMachine#connect initiates a TCP connection to a remote
381
+ # server and sets up event-handling for the connection.
382
+ # You can call EventMachine#connect in the block supplied
383
+ # to EventMachine#run or in any callback method.
384
+ #
385
+ # EventMachine#connect takes the IP address (or hostname) and
386
+ # port of the remote server you want to connect to.
387
+ # It also takes an optional handler Module which you must define, that
388
+ # contains the callbacks that will be invoked by the event loop
389
+ # on behalf of the connection.
390
+ #
391
+ # See the description of EventMachine#start_server for a discussion
392
+ # of the handler Module. All of the details given in that description
393
+ # apply for connections created with EventMachine#connect.
394
+ #
395
+ # === Usage Example
396
+ #
397
+ # Here's a program which connects to a web server, sends a naive
398
+ # request, parses the HTTP header of the response, and then
399
+ # (antisocially) ends the event loop, which automatically drops the connection
400
+ # (and incidentally calls the connection's unbind method).
401
+ #
402
+ # require 'rubygems'
403
+ # require_gem 'eventmachine'
404
+ #
405
+ # module DumbHttpClient
406
+ #
407
+ # def post_init
408
+ # send_data "GET / HTTP/1.1\r\nHost: _\r\n\r\n"
409
+ # @data = ""
410
+ # end
411
+ #
412
+ # def receive_data data
413
+ # @data << data
414
+ # if @data =~ /[\n][\r]*[\n]/m
415
+ # puts "RECEIVED HTTP HEADER:"
416
+ # $`.each {|line| puts ">>> #{line}" }
417
+ #
418
+ # puts "Now we'll terminate the loop, which will also close the connection"
419
+ # EventMachine::stop_event_loop
420
+ # end
421
+ # end
422
+ #
423
+ # def unbind
424
+ # puts "A connection has terminated"
425
+ # end
426
+ #
427
+ # end # DumbHttpClient
428
+ #
429
+ #
430
+ # EventMachine::run {
431
+ # EventMachine::connect "www.bayshorenetworks.com", 80, DumbHttpClient
432
+ # }
433
+ # puts "The event loop has ended"
434
+ #
435
+ #--
436
+ # EventMachine::connect initiates a TCP connection to a remote
437
+ # server and sets up event-handling for the connection.
438
+ # It internally creates an object that should not be handled
439
+ # by the caller. HOWEVER, it's often convenient to get the
440
+ # object to set up interfacing to other objects in the system.
441
+ # We return the newly-created anonymous-class object to the caller.
442
+ # It's expected that a considerable amount of code will depend
443
+ # on this behavior, so don't change it.
444
+ #
445
+ def EventMachine::connect server, port, handler=nil
446
+ s = connect_server server, port
447
+ klass = Class.new( Connection ) {
448
+ handler and include handler
449
+ }
450
+ c = klass.new s
451
+ @conns[s] = c
452
+ end
453
+
454
+
455
+ private
456
+ def EventMachine::event_callback conn_binding, opcode, data
457
+ case opcode
458
+ when ConnectionData
459
+ c = @conns[conn_binding] or raise ConnectionNotBound
460
+ c.receive_data data
461
+ when ConnectionUnbound
462
+ if c = @conns.delete( conn_binding )
463
+ c.unbind
464
+ elsif c = @acceptors.delete( conn_binding )
465
+ # no-op
466
+ else
467
+ raise ConnectionNotBound
468
+ end
469
+ when ConnectionAccepted
470
+ accep = @acceptors[conn_binding] or raise NoHandlerForAcceptedConnection
471
+ c = accep.new data
472
+ @conns[data] = c
473
+ when TimerFired
474
+ t = @timers.delete( data ) or raise UnknownTimerFired
475
+ t.call
476
+ end
477
+ end
478
+
479
+
480
+
481
+ # EventMachine::Connection is a class that is instantiated
482
+ # by EventMachine's processing loop whenever a new connection
483
+ # is created. (New connections can be either initiated locally
484
+ # to a remote server or accepted locally from a remote client.)
485
+ # When a Connection object is instantiated, it <i>mixes in</i>
486
+ # the functionality contained in the user-defined module
487
+ # specified in calls to EventMachine#connect or EventMachine#start_server.
488
+ # User-defined handler modules may redefine any or all of the standard
489
+ # methods defined here, as well as add arbitrary additional code
490
+ # that will also be mixed in.
491
+ #
492
+ # EventMachine manages one object inherited from EventMachine::Connection
493
+ # (and containing the mixed-in user code) for every network connection
494
+ # that is active at any given time.
495
+ # The event loop will automatically call methods on EventMachine::Connection
496
+ # objects whenever specific events occur on the corresponding connections,
497
+ # as described below.
498
+ #
499
+ # This class is never instantiated by user code, and does not publish an
500
+ # initialize method. The instance methods of EventMachine::Connection
501
+ # which may be called by the event loop are: post_init, receive_data,
502
+ # and unbind. All of the other instance methods defined here are called
503
+ # only by user code.
504
+ #
505
+ class Connection
506
+
507
+ def initialize sig #:nodoc:
508
+ @signature = sig
509
+ post_init
510
+ end
511
+
512
+ # EventMachine::Connection#post_init is called by the event loop
513
+ # immediately after the network connection has been established,
514
+ # and before resumption of the network loop.
515
+ # This method is generally not called by user code, but is called automatically
516
+ # by the event loop. The base-class implementation is a no-op.
517
+ # This is a very good place to initialize instance variables that will
518
+ # be used throughout the lifetime of the network connection.
519
+ #
520
+ def post_init
521
+ end
522
+
523
+ # EventMachine::Connection#receive_data is called by the event loop
524
+ # whenever data has been received by the network connection.
525
+ # It is never called by user code.
526
+ # receive_data is called with a single parameter, a String containing
527
+ # the network protocol data, which may of course be binary. You will
528
+ # generally redefine this method to perform your own processing of the incoming data.
529
+ #
530
+ # Here's a key point which is essential to understanding the event-driven
531
+ # programming model: <i>EventMachine knows absolutely nothing about the protocol
532
+ # which your code implements.</i> You must not make any assumptions about
533
+ # the size of the incoming data packets, or about their alignment on any
534
+ # particular intra-message or PDU boundaries (such as line breaks).
535
+ # receive_data can and will send you arbitrary chunks of data, with the
536
+ # only guarantee being that the data is presented to your code in the order
537
+ # it was collected from the network. Don't even assume that the chunks of
538
+ # data will correspond to network packets, as EventMachine can and will coalesce
539
+ # several incoming packets into one, to improve performance. The implication for your
540
+ # code is that you generally will need to implement some kind of a state machine
541
+ # in your redefined implementation of receive_data. For a better understanding
542
+ # of this, read through the examples of specific protocol handlers given
543
+ # elsewhere in this package. (STUB, WE MUST ADD THESE!)
544
+ #
545
+ # The base-class implementation of receive_data (which will be invoked if
546
+ # you don't redefine it) simply prints the size of each incoming data packet
547
+ # to stdout.
548
+ #
549
+ def receive_data data
550
+ puts "............>>>#{data.length}"
551
+ end
552
+
553
+ # EventMachine::Connection#unbind is called by the framework whenever a connection
554
+ # (either a server or client connection) is closed. The close can occur because
555
+ # your code intentionally closes it (see close_connection and close_connection_after_writing),
556
+ # because the remote peer closed the connection, or because of a network error.
557
+ # You may not assume that the network connection is still open and able to send or
558
+ # receive data when the callback to unbind is made. This is intended only to give
559
+ # you a chance to clean up associations your code may have made to the connection
560
+ # object while it was open.
561
+ #
562
+ def unbind
563
+ end
564
+
565
+ # EventMachine::Connection#close_connection is called only by user code, and never
566
+ # by the event loop. You may call this method against a connection object in any
567
+ # callback handler, whether or not the callback was made against the connection
568
+ # you want to close. close_connection <i>schedules</i> the connection to be closed
569
+ # at the next available opportunity within the event loop. You may not assume that
570
+ # the connection is closed when close_connection returns. In particular, the framework
571
+ # will callback the unbind method for the particular connection at a point shortly
572
+ # after you call close_connection. You may assume that the unbind callback will
573
+ # take place sometime after your call to close_connection completes. In other words,
574
+ # the unbind callback will not re-enter your code "inside" of your call to close_connection.
575
+ # However, it's not guaranteed that a future version of EventMachine will not change
576
+ # this behavior.
577
+ #
578
+ # close_connection will <i>silently discard</i> any outbound data which you have
579
+ # sent to the connection using EventMachine::Connection#send_data but which has not
580
+ # yet been sent across the network. If you want to avoid this behavior, use
581
+ # EventMachine::Connection#close_connection_after_writing.
582
+ #
583
+ def close_connection after_writing = false
584
+ EventMachine::close_connection @signature, after_writing
585
+ end
586
+
587
+ # EventMachine::Connection#close_connection_after_writing is a variant of close_connection.
588
+ # All of the descriptive comments given for close_connection also apply to
589
+ # close_connection_after_writing, <i>with one exception:</i> If the connection has
590
+ # outbound data sent using send_dat but which has not yet been sent across the network,
591
+ # close_connection_after_writing will schedule the connection to be closed <i>after</i>
592
+ # all of the outbound data has been safely written to the remote peer.
593
+ #
594
+ # Depending on the amount of outgoing data and the speed of the network,
595
+ # considerable time may elapse between your call to close_connection_after_writing
596
+ # and the actual closing of the socket (at which time the unbind callback will be called
597
+ # by the event loop). During this time, you <i>may not</i> call send_data to transmit
598
+ # additional data (that is, the connection is closed for further writes). In very
599
+ # rare cases, you may experience a receive_data callback after your call to close_connection_after_writing,
600
+ # depending on whether incoming data was in the process of being received on the connection
601
+ # at the moment when you called close_connection_after_writing. Your protocol handler must
602
+ # be prepared to properly deal with such data (probably by ignoring it).
603
+ #
604
+ def close_connection_after_writing
605
+ close_connection true
606
+ end
607
+
608
+ # EventMachine::Connection#send_data is only called by user code, never by
609
+ # the event loop. You call this method to send data to the remote end of the
610
+ # network connection. send_data is called with a single String argument, which
611
+ # may of course contain binary data. You can call send_data any number of times.
612
+ # send_data is an instance method of an object derived from EventMachine::Connection
613
+ # and containing your mixed-in handler code), so if you call it without qualification
614
+ # within a callback function, the data will be sent to the same network connection
615
+ # that generated the callback. Calling self.send_data is exactly equivalent.
616
+ #
617
+ # You can also call send_data to write to a connection <i>other than the one
618
+ # whose callback you are calling send_data from.</i> This is done by recording
619
+ # the value of the connection in any callback function (the value self), in any
620
+ # variable visible to other callback invocations on the same or different
621
+ # connection objects. (Need an example to make that clear.)
622
+ #
623
+ def send_data data
624
+ EventMachine::send_data @signature, data, data.length
625
+ end
626
+
627
+ end
628
+
629
+
630
+ end # module EventMachine
631
+