~certify-web-dev/twisted/certify-staging

« back to all changes in this revision

Viewing changes to doc/howto/servers.html

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2010-01-02 19:38:17 UTC
  • mfrom: (2.2.4 sid)
  • Revision ID: james.westby@ubuntu.com-20100102193817-jphp464ppwh7dulg
Tags: 9.0.0-1
* python-twisted: Depend on the python-twisted-* 9.0 packages.
* python-twisted: Depend on python-zope.interface only. Closes: #557781.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
<?xml version="1.0"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><title>Twisted Documentation: Writing Servers</title><link href="stylesheet.css" type="text/css" rel="stylesheet" /></head><body bgcolor="white"><h1 class="title">Writing Servers</h1><div class="toc"><ol><li><a href="#auto0">Overview</a></li><li><a href="#auto1">Protocols</a></li><ul><li><a href="#auto2">Using the Protocol</a></li><li><a href="#auto3">Helper Protocols</a></li><li><a href="#auto4">State Machines</a></li></ul><li><a href="#auto5">Factories</a></li><ul><li><a href="#auto6">Putting it All Together</a></li></ul></ol></div><div class="content"><span></span><h2>Overview<a name="auto0"></a></h2><p>Twisted is a framework designed to be very flexible and let
 
1
<?xml version="1.0" encoding="utf-8"?>
 
2
<!DOCTYPE html
 
3
  PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN'
 
4
  'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
 
5
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
 
6
  <head>
 
7
<title>Twisted Documentation: Writing Servers</title>
 
8
<link href="stylesheet.css" rel="stylesheet" type="text/css"/>
 
9
  </head>
 
10
 
 
11
  <body bgcolor="white">
 
12
    <h1 class="title">Writing Servers</h1>
 
13
    <div class="toc"><ol><li><a href="#auto0">Overview</a></li><li><a href="#auto1">Protocols</a></li><ul><li><a href="#auto2">Using the Protocol</a></li><li><a href="#auto3">Helper Protocols</a></li><li><a href="#auto4">State Machines</a></li></ul><li><a href="#auto5">Factories</a></li><ul><li><a href="#auto6">Putting it All Together</a></li></ul></ol></div>
 
14
    <div class="content">
 
15
    <span/>
 
16
 
 
17
    <h2>Overview<a name="auto0"/></h2>
 
18
 
 
19
    <p>Twisted is a framework designed to be very flexible and let
3
20
    you write powerful servers. The cost of this flexibility is a
4
 
    few layers in the way to writing your server.</p><p>This document describes the
5
 
    <code class="API"><a href="http://twistedmatrix.com/documents/8.2.0/api/twisted.internet.protocol.Protocol.html" title="twisted.internet.protocol.Protocol">Protocol</a></code>
 
21
    few layers in the way to writing your server.</p>
 
22
 
 
23
    <p>This document describes the
 
24
    <code class="API"><a href="http://twistedmatrix.com/documents/9.0.0/api/twisted.internet.protocol.Protocol.html" title="twisted.internet.protocol.Protocol">Protocol</a></code>
6
25
    layer, where you 
7
26
    implement protocol parsing and handling.  If you are implementing 
8
27
    an application then you should read this document second, after 
9
28
    first reading the top level overview of how to begin writing your 
10
 
    Twisted application, in <a href="plugin.html">Writing Plug-Ins 
 
29
    Twisted application, in <a href="plugin.html" shape="rect">Writing Plug-Ins 
11
30
    for Twisted</a>. This document is only relevant to TCP, SSL and
12
 
    Unix socket servers, there is a <a href="udp.html">separate document</a>
13
 
     for UDP.</p><p>Your protocol handling class will usually subclass <code class="API"><a href="http://twistedmatrix.com/documents/8.2.0/api/twisted.internet.protocol.Protocol.html" title="twisted.internet.protocol.Protocol">twisted.internet.protocol.Protocol</a></code>. Most
 
31
    Unix socket servers, there is a <a href="udp.html" shape="rect">separate document</a>
 
32
     for UDP.</p>
 
33
 
 
34
    <p>Your protocol handling class will usually subclass <code class="API"><a href="http://twistedmatrix.com/documents/9.0.0/api/twisted.internet.protocol.Protocol.html" title="twisted.internet.protocol.Protocol">twisted.internet.protocol.Protocol</a></code>. Most
14
35
    protocol handlers inherit either from this class or from one of
15
36
    its convenience children. An instance of the protocol class
16
37
    might be instantiated per-connection, on demand, and might go
17
38
    away when the connection is finished. This means that
18
39
    persistent configuration is not saved in the
19
 
    <code>Protocol</code>.</p><p>The persistent configuration is kept in a Factory class,
20
 
    which usually inherits from <code class="API"><a href="http://twistedmatrix.com/documents/8.2.0/api/twisted.internet.protocol.Factory.html" title="twisted.internet.protocol.Factory">twisted.internet.protocol.Factory</a></code>. The
 
40
    <code>Protocol</code>.</p>
 
41
 
 
42
    <p>The persistent configuration is kept in a Factory class,
 
43
    which usually inherits from <code class="API"><a href="http://twistedmatrix.com/documents/9.0.0/api/twisted.internet.protocol.Factory.html" title="twisted.internet.protocol.Factory">twisted.internet.protocol.Factory</a></code>. The
21
44
    default factory class just instantiates each <code>Protocol</code>, and then
22
45
    sets on it an attribute called <code>factory</code> which
23
46
    points to itself. This lets every <code>Protocol</code> access,
24
 
    and possibly modify, the persistent configuration.</p><p>It is usually useful to be able to offer the same service on
 
47
    and possibly modify, the persistent configuration.</p>
 
48
 
 
49
    <p>It is usually useful to be able to offer the same service on
25
50
    multiple ports or network addresses. This is why the <code>Factory</code>
26
51
    does not listen to connections, and in fact does not
27
 
    know anything about the network. See <code class="API"><a href="http://twistedmatrix.com/documents/8.2.0/api/twisted.internet.interfaces.IReactorTCP.listenTCP.html" title="twisted.internet.interfaces.IReactorTCP.listenTCP">twisted.internet.interfaces.IReactorTCP.listenTCP</a></code>,
 
52
    know anything about the network. See <code class="API"><a href="http://twistedmatrix.com/documents/9.0.0/api/twisted.internet.interfaces.IReactorTCP.listenTCP.html" title="twisted.internet.interfaces.IReactorTCP.listenTCP">twisted.internet.interfaces.IReactorTCP.listenTCP</a></code>,
28
53
    and the other <code>IReactor*.listen*</code> APIs for more
29
 
    information.</p><p>This document will explain each step of the way.</p><h2>Protocols<a name="auto1"></a></h2><p>As mentioned above, this, along with auxiliary classes and
 
54
    information.</p>
 
55
 
 
56
    <p>This document will explain each step of the way.</p>
 
57
 
 
58
    <h2>Protocols<a name="auto1"/></h2>
 
59
 
 
60
    <p>As mentioned above, this, along with auxiliary classes and
30
61
    functions, is where most of the code is. A Twisted protocol
31
62
    handles data in an asynchronous manner. What this means is that
32
63
    the protocol never waits for an event, but rather responds to
33
 
    events as they arrive from the network.</p><p>Here is a simple example:</p><pre class="python">
34
 
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span>.<span class="py-src-variable">protocol</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Protocol</span>
 
64
    events as they arrive from the network.</p>
 
65
 
 
66
    <p>Here is a simple example:</p>
 
67
<pre class="python"><p class="py-linenumber">1
 
68
2
 
69
3
 
70
4
 
71
5
 
72
6
 
73
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span>.<span class="py-src-variable">protocol</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Protocol</span>
35
74
 
36
75
<span class="py-src-keyword">class</span> <span class="py-src-identifier">Echo</span>(<span class="py-src-parameter">Protocol</span>):
37
76
 
38
77
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">dataReceived</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">data</span>):
39
78
        <span class="py-src-variable">self</span>.<span class="py-src-variable">transport</span>.<span class="py-src-variable">write</span>(<span class="py-src-variable">data</span>)
40
 
</pre><p>This is one of the simplest protocols. It simply writes back
 
79
</pre>
 
80
 
 
81
    <p>This is one of the simplest protocols. It simply writes back
41
82
    whatever is written to it, and does not respond to all events. Here is an
42
 
    example of a Protocol responding to another event:</p><pre class="python">
43
 
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span>.<span class="py-src-variable">protocol</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Protocol</span>
 
83
    example of a Protocol responding to another event:</p>
 
84
<pre class="python"><p class="py-linenumber">1
 
85
2
 
86
3
 
87
4
 
88
5
 
89
6
 
90
7
 
91
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span>.<span class="py-src-variable">protocol</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Protocol</span>
44
92
 
45
93
<span class="py-src-keyword">class</span> <span class="py-src-identifier">QOTD</span>(<span class="py-src-parameter">Protocol</span>):
46
94
 
47
95
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">connectionMade</span>(<span class="py-src-parameter">self</span>):
48
96
        <span class="py-src-variable">self</span>.<span class="py-src-variable">transport</span>.<span class="py-src-variable">write</span>(<span class="py-src-string">&quot;An apple a day keeps the doctor away\r\n&quot;</span>) 
49
97
        <span class="py-src-variable">self</span>.<span class="py-src-variable">transport</span>.<span class="py-src-variable">loseConnection</span>()
50
 
</pre><p>This protocol responds to the initial connection with a well
51
 
    known quote, and then terminates the connection.</p><p>The connectionMade event is usually where set up of the
 
98
</pre>
 
99
 
 
100
    <p>This protocol responds to the initial connection with a well
 
101
    known quote, and then terminates the connection.</p>
 
102
 
 
103
    <p>The connectionMade event is usually where set up of the
52
104
    connection object happens, as well as any initial greetings (as
53
105
    in the QOTD protocol above, which is actually based on RFC
54
106
    865). The <code>connectionLost</code> event is where tearing down of any
55
 
    connection-specific objects is done. Here is an example:</p><pre class="python">
56
 
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span>.<span class="py-src-variable">protocol</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Protocol</span>
 
107
    connection-specific objects is done. Here is an example:</p>
 
108
<pre class="python"><p class="py-linenumber"> 1
 
109
 2
 
110
 3
 
111
 4
 
112
 5
 
113
 6
 
114
 7
 
115
 8
 
116
 9
 
117
10
 
118
11
 
119
12
 
120
13
 
121
14
 
122
15
 
123
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span>.<span class="py-src-variable">protocol</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Protocol</span>
57
124
 
58
125
<span class="py-src-keyword">class</span> <span class="py-src-identifier">Echo</span>(<span class="py-src-parameter">Protocol</span>):
59
126
 
68
135
 
69
136
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">dataReceived</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">data</span>):
70
137
        <span class="py-src-variable">self</span>.<span class="py-src-variable">transport</span>.<span class="py-src-variable">write</span>(<span class="py-src-variable">data</span>)
71
 
</pre><p>Here <code>connectionMade</code> and
 
138
</pre>
 
139
 
 
140
    <p>Here <code>connectionMade</code> and
72
141
    <code>connectionLost</code> cooperate to keep a count of the
73
142
    active protocols in the factory. <code>connectionMade</code>
74
143
    immediately closes the connection if there are too many active
75
 
    protocols.</p><h3>Using the Protocol<a name="auto2"></a></h3><p>In this section, I will explain how to test your protocol
 
144
    protocols.</p>
 
145
 
 
146
    <h3>Using the Protocol<a name="auto2"/></h3>
 
147
 
 
148
    <p>In this section, I will explain how to test your protocol
76
149
    easily. (In order to see how you should write a production-grade Twisted
77
 
    server, though, you should read the <a href="plugin.html">Writing Plug-Ins
78
 
    for Twisted</a> HOWTO as well).</p><p>Here is code that will run the QOTD server discussed
79
 
    earlier</p><pre class="python">
80
 
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span>.<span class="py-src-variable">protocol</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Protocol</span>, <span class="py-src-variable">Factory</span>
 
150
    server, though, you should read the <a href="plugin.html" shape="rect">Writing Plug-Ins
 
151
    for Twisted</a> HOWTO as well).</p>
 
152
 
 
153
    <p>Here is code that will run the QOTD server discussed
 
154
    earlier</p>
 
155
<pre class="python"><p class="py-linenumber"> 1
 
156
 2
 
157
 3
 
158
 4
 
159
 5
 
160
 6
 
161
 7
 
162
 8
 
163
 9
 
164
10
 
165
11
 
166
12
 
167
13
 
168
14
 
169
15
 
170
16
 
171
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span>.<span class="py-src-variable">protocol</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Protocol</span>, <span class="py-src-variable">Factory</span>
81
172
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">reactor</span>
82
173
 
83
174
<span class="py-src-keyword">class</span> <span class="py-src-identifier">QOTD</span>(<span class="py-src-parameter">Protocol</span>):
86
177
        <span class="py-src-variable">self</span>.<span class="py-src-variable">transport</span>.<span class="py-src-variable">write</span>(<span class="py-src-string">&quot;An apple a day keeps the doctor away\r\n&quot;</span>) 
87
178
        <span class="py-src-variable">self</span>.<span class="py-src-variable">transport</span>.<span class="py-src-variable">loseConnection</span>()
88
179
 
89
 
<span class="py-src-comment"># Next lines are magic:
90
 
</span><span class="py-src-variable">factory</span> = <span class="py-src-variable">Factory</span>()
 
180
<span class="py-src-comment"># Next lines are magic:</span>
 
181
<span class="py-src-variable">factory</span> = <span class="py-src-variable">Factory</span>()
91
182
<span class="py-src-variable">factory</span>.<span class="py-src-variable">protocol</span> = <span class="py-src-variable">QOTD</span>
92
183
 
93
 
<span class="py-src-comment"># 8007 is the port you want to run under. Choose something &gt;1024
94
 
</span><span class="py-src-variable">reactor</span>.<span class="py-src-variable">listenTCP</span>(<span class="py-src-number">8007</span>, <span class="py-src-variable">factory</span>)
 
184
<span class="py-src-comment"># 8007 is the port you want to run under. Choose something &gt;1024</span>
 
185
<span class="py-src-variable">reactor</span>.<span class="py-src-variable">listenTCP</span>(<span class="py-src-number">8007</span>, <span class="py-src-variable">factory</span>)
95
186
<span class="py-src-variable">reactor</span>.<span class="py-src-variable">run</span>()
96
 
</pre><p>Don't worry about the last 6 magic lines -- you will
97
 
    understand what they do later in the document.</p><h3>Helper Protocols<a name="auto3"></a></h3><p>Many protocols build upon similar lower-level abstraction.
 
187
</pre>
 
188
 
 
189
    <p>Don't worry about the last 6 magic lines -- you will
 
190
    understand what they do later in the document.</p>
 
191
 
 
192
    <h3>Helper Protocols<a name="auto3"/></h3>
 
193
 
 
194
    <p>Many protocols build upon similar lower-level abstraction.
98
195
    The most popular in internet protocols is being line-based.
99
 
    Lines are usually terminated with a CR-LF combinations.</p><p>However, quite a few protocols are mixed - they have
 
196
    Lines are usually terminated with a CR-LF combinations.</p>
 
197
 
 
198
    <p>However, quite a few protocols are mixed - they have
100
199
    line-based sections and then raw data sections. Examples
101
 
    include HTTP/1.1 and the Freenet protocol.</p><p>For those cases, there is the <code>LineReceiver</code>
 
200
    include HTTP/1.1 and the Freenet protocol.</p>
 
201
 
 
202
    <p>For those cases, there is the <code>LineReceiver</code>
102
203
    protocol. This protocol dispatches to two different event
103
204
    handlers - <code>lineReceived</code> and
104
205
    <code>rawDataReceived</code>. By default, only
106
207
    However, if <code>setRawMode</code> is called, the protocol
107
208
    will call <code>rawDataReceived</code> until
108
209
    <code>setLineMode</code> is called, which returns it to using
109
 
    <code>lineReceived</code>.</p><p>Here is an example for a simple use of the line
110
 
    receiver:</p><pre class="python">
111
 
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">protocols</span>.<span class="py-src-variable">basic</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">LineReceiver</span>
 
210
    <code>lineReceived</code>.</p>
 
211
 
 
212
    <p>Here is an example for a simple use of the line
 
213
    receiver:</p>
 
214
<pre class="python"><p class="py-linenumber"> 1
 
215
 2
 
216
 3
 
217
 4
 
218
 5
 
219
 6
 
220
 7
 
221
 8
 
222
 9
 
223
10
 
224
11
 
225
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">protocols</span>.<span class="py-src-variable">basic</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">LineReceiver</span>
112
226
 
113
227
<span class="py-src-keyword">class</span> <span class="py-src-identifier">Answer</span>(<span class="py-src-parameter">LineReceiver</span>):
114
228
 
119
233
            <span class="py-src-variable">self</span>.<span class="py-src-variable">sendLine</span>(<span class="py-src-variable">self</span>.<span class="py-src-variable">answers</span>[<span class="py-src-variable">line</span>])
120
234
        <span class="py-src-keyword">else</span>:
121
235
            <span class="py-src-variable">self</span>.<span class="py-src-variable">sendLine</span>(<span class="py-src-variable">self</span>.<span class="py-src-variable">answers</span>[<span class="py-src-variable">None</span>])
122
 
</pre><p>Note that the delimiter is not part of the line.</p><p>Several other, less popular, helpers exist, such as a
 
236
</pre>
 
237
 
 
238
    <p>Note that the delimiter is not part of the line.</p>
 
239
 
 
240
    <p>Several other, less popular, helpers exist, such as a
123
241
    netstring based protocol and a prefixed-message-length
124
 
    protocol.</p><h3>State Machines<a name="auto4"></a></h3><p>Many Twisted protocol handlers need to write a state machine
 
242
    protocol.</p>
 
243
 
 
244
    <h3>State Machines<a name="auto4"/></h3>
 
245
 
 
246
    <p>Many Twisted protocol handlers need to write a state machine
125
247
    to record the state they are at. Here are some pieces of advice
126
 
    which help to write state machines:</p><ul><li>Don't write big state machines. Prefer to write a state
 
248
    which help to write state machines:</p>
 
249
 
 
250
    <ul>
 
251
      <li>Don't write big state machines. Prefer to write a state
127
252
      machine which deals with one level of abstraction at a
128
 
      time.</li><li>Use Python's dynamicity to create open ended state
 
253
      time.</li>
 
254
 
 
255
      <li>Use Python's dynamicity to create open ended state
129
256
      machines. See, for example, the code for the SMTP
130
 
      client.</li><li>Don't mix application-specific code with Protocol
 
257
      client.</li>
 
258
 
 
259
      <li>Don't mix application-specific code with Protocol
131
260
      handling code. When the protocol handler has to make an
132
 
      application-specific call, keep it as a method call.</li></ul><h2>Factories<a name="auto5"></a></h2><p>As mentioned before, usually the class <code class="API"><a href="http://twistedmatrix.com/documents/8.2.0/api/twisted.internet.protocol.Factory.html" title="twisted.internet.protocol.Factory">twisted.internet.protocol.Factory</a></code> works,
 
261
      application-specific call, keep it as a method call.</li>
 
262
    </ul>
 
263
 
 
264
    <h2>Factories<a name="auto5"/></h2>
 
265
 
 
266
    <p>As mentioned before, usually the class <code class="API"><a href="http://twistedmatrix.com/documents/9.0.0/api/twisted.internet.protocol.Factory.html" title="twisted.internet.protocol.Factory">twisted.internet.protocol.Factory</a></code> works,
133
267
    and there is no need to subclass it. However, sometimes there
134
268
    can be factory-specific configuration of the protocols, or
135
269
    other considerations. In those cases, there is a need to
136
 
    subclass <code>Factory</code>.</p><p>For a factory which simply instantiates instances of a
 
270
    subclass <code>Factory</code>.</p>
 
271
 
 
272
    <p>For a factory which simply instantiates instances of a
137
273
    specific protocol class, simply instantiate
138
 
    <code>Factory</code>, and sets its <code>protocol</code> attribute:</p><pre class="python">
139
 
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span>.<span class="py-src-variable">protocol</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Factory</span>
 
274
    <code>Factory</code>, and sets its <code>protocol</code> attribute:</p>
 
275
<pre class="python"><p class="py-linenumber">1
 
276
2
 
277
3
 
278
4
 
279
5
 
280
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span>.<span class="py-src-variable">protocol</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Factory</span>
140
281
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">protocols</span>.<span class="py-src-variable">wire</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Echo</span>
141
282
 
142
283
<span class="py-src-variable">myFactory</span> = <span class="py-src-variable">Factory</span>()
143
284
<span class="py-src-variable">myFactory</span>.<span class="py-src-variable">protocol</span> = <span class="py-src-variable">Echo</span>
144
 
</pre><p>If there is a need to easily construct factories for a
145
 
    specific configuration, a factory function is often useful:</p><pre class="python">
146
 
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span>.<span class="py-src-variable">protocol</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Factory</span>, <span class="py-src-variable">Protocol</span>
 
285
</pre>
 
286
 
 
287
    <p>If there is a need to easily construct factories for a
 
288
    specific configuration, a factory function is often useful:</p>
 
289
<pre class="python"><p class="py-linenumber"> 1
 
290
 2
 
291
 3
 
292
 4
 
293
 5
 
294
 6
 
295
 7
 
296
 8
 
297
 9
 
298
10
 
299
11
 
300
12
 
301
13
 
302
14
 
303
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span>.<span class="py-src-variable">protocol</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Factory</span>, <span class="py-src-variable">Protocol</span>
147
304
 
148
305
<span class="py-src-keyword">class</span> <span class="py-src-identifier">QOTD</span>(<span class="py-src-parameter">Protocol</span>):
149
306
 
157
314
    <span class="py-src-variable">factory</span>.<span class="py-src-variable">protocol</span> = <span class="py-src-variable">QOTD</span>
158
315
    <span class="py-src-variable">factory</span>.<span class="py-src-variable">quote</span> = <span class="py-src-variable">quote</span> <span class="py-src-keyword">or</span> <span class="py-src-string">'An apple a day keeps the doctor away'</span>
159
316
    <span class="py-src-keyword">return</span> <span class="py-src-variable">factory</span>
160
 
</pre><p>A Factory has two methods to perform application-specific
 
317
</pre>
 
318
 
 
319
    <p>A Factory has two methods to perform application-specific
161
320
    building up and tearing down (since a Factory is frequently
162
321
    persisted, it is often not appropriate to do them in <code>__init__</code>
163
 
    or <code>__del__</code>, and would frequently be too early or too late).</p><p>Here is an example of a factory which allows its Protocols
164
 
    to write to a special log-file:</p><pre class="python">
165
 
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span>.<span class="py-src-variable">protocol</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Factory</span>
 
322
    or <code>__del__</code>, and would frequently be too early or too late).</p>
 
323
 
 
324
    <p>Here is an example of a factory which allows its Protocols
 
325
    to write to a special log-file:</p>
 
326
<pre class="python"><p class="py-linenumber"> 1
 
327
 2
 
328
 3
 
329
 4
 
330
 5
 
331
 6
 
332
 7
 
333
 8
 
334
 9
 
335
10
 
336
11
 
337
12
 
338
13
 
339
14
 
340
15
 
341
16
 
342
17
 
343
18
 
344
19
 
345
20
 
346
21
 
347
22
 
348
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span>.<span class="py-src-variable">protocol</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Factory</span>
166
349
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">protocols</span>.<span class="py-src-variable">basic</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">LineReceiver</span>
167
350
 
168
351
 
184
367
 
185
368
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">stopFactory</span>(<span class="py-src-parameter">self</span>):
186
369
        <span class="py-src-variable">self</span>.<span class="py-src-variable">fp</span>.<span class="py-src-variable">close</span>()
187
 
</pre><h3>Putting it All Together<a name="auto6"></a></h3><p>So, you know what factories are, and want to run the QOTD
 
370
</pre>
 
371
 
 
372
    <h3>Putting it All Together<a name="auto6"/></h3>
 
373
 
 
374
    <p>So, you know what factories are, and want to run the QOTD
188
375
    with configurable quote server, do you? No problems, here is an
189
 
    example.</p><pre class="python">
190
 
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span>.<span class="py-src-variable">protocol</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Factory</span>, <span class="py-src-variable">Protocol</span>
 
376
    example.</p>
 
377
 
 
378
<pre class="python"><p class="py-linenumber"> 1
 
379
 2
 
380
 3
 
381
 4
 
382
 5
 
383
 6
 
384
 7
 
385
 8
 
386
 9
 
387
10
 
388
11
 
389
12
 
390
13
 
391
14
 
392
15
 
393
16
 
394
17
 
395
18
 
396
19
 
397
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span>.<span class="py-src-variable">protocol</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Factory</span>, <span class="py-src-variable">Protocol</span>
191
398
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">reactor</span>
192
399
 
193
400
<span class="py-src-keyword">class</span> <span class="py-src-identifier">QOTD</span>(<span class="py-src-parameter">Protocol</span>):
206
413
 
207
414
<span class="py-src-variable">reactor</span>.<span class="py-src-variable">listenTCP</span>(<span class="py-src-number">8007</span>, <span class="py-src-variable">QOTDFactory</span>(<span class="py-src-string">&quot;configurable quote&quot;</span>))
208
415
<span class="py-src-variable">reactor</span>.<span class="py-src-variable">run</span>()
209
 
</pre><p>The only lines you might not understand are the last two.</p><p><code class="API"><a href="http://twistedmatrix.com/documents/8.2.0/api/twisted.internet.interfaces.IReactorTCP.listenTCP.html" title="twisted.internet.interfaces.IReactorTCP.listenTCP">listenTCP</a></code> is
 
416
</pre>
 
417
 
 
418
    <p>The only lines you might not understand are the last two.</p>
 
419
 
 
420
<p><code class="API"><a href="http://twistedmatrix.com/documents/9.0.0/api/twisted.internet.interfaces.IReactorTCP.listenTCP.html" title="twisted.internet.interfaces.IReactorTCP.listenTCP">listenTCP</a></code> is
210
421
the method which connects a <code>Factory</code> to the network.
211
422
It uses the reactor interface, which lets many different loops handle
212
423
the networking code, without modifying end-user code, like this.
213
424
As mentioned above, if you want to write your code to be a production-grade
214
425
Twisted server, and not a mere 20-line hack, you will want to
215
 
use <a href="application.html">the Application object</a>.</p></div><p><a href="index.html">Index</a></p><span class="version">Version: 8.2.0</span></body></html>
 
 
b'\\ No newline at end of file'
 
426
use <a href="application.html" shape="rect">the Application object</a>.</p>
 
427
 
 
428
  </div>
 
429
 
 
430
    <p><a href="index.html">Index</a></p>
 
431
    <span class="version">Version: 9.0.0</span>
 
432
  </body>
 
433
</html>
 
 
b'\\ No newline at end of file'