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"?>
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">
7
<title>Twisted Documentation: Writing Servers</title>
8
<link href="stylesheet.css" rel="stylesheet" type="text/css"/>
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>
17
<h2>Overview<a name="auto0"/></h2>
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>
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>
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>
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>
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>
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
56
<p>This document will explain each step of the way.</p>
58
<h2>Protocols<a name="auto1"/></h2>
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>
66
<p>Here is a simple example:</p>
67
<pre class="python"><p class="py-linenumber">1
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>
36
75
<span class="py-src-keyword">class</span> <span class="py-src-identifier">Echo</span>(<span class="py-src-parameter">Protocol</span>):
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
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
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>
45
93
<span class="py-src-keyword">class</span> <span class="py-src-identifier">QOTD</span>(<span class="py-src-parameter">Protocol</span>):
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">"An apple a day keeps the doctor away\r\n"</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
100
<p>This protocol responds to the initial connection with a well
101
known quote, and then terminates the connection.</p>
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
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>
58
125
<span class="py-src-keyword">class</span> <span class="py-src-identifier">Echo</span>(<span class="py-src-parameter">Protocol</span>):
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
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
146
<h3>Using the Protocol<a name="auto2"/></h3>
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>
153
<p>Here is code that will run the QOTD server discussed
155
<pre class="python"><p class="py-linenumber"> 1
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>
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">"An apple a day keeps the doctor away\r\n"</span>)
87
178
<span class="py-src-variable">self</span>.<span class="py-src-variable">transport</span>.<span class="py-src-variable">loseConnection</span>()
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>
93
<span class="py-src-comment"># 8007 is the port you want to run under. Choose something >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 >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.
189
<p>Don't worry about the last 6 magic lines -- you will
190
understand what they do later in the document.</p>
192
<h3>Helper Protocols<a name="auto3"/></h3>
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>
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>
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
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
238
<p>Note that the delimiter is not part of the line.</p>
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
244
<h3>State Machines<a name="auto4"/></h3>
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>
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
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
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>
264
<h2>Factories<a name="auto5"/></h2>
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>
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
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>
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>
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
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>
148
305
<span class="py-src-keyword">class</span> <span class="py-src-identifier">QOTD</span>(<span class="py-src-parameter">Protocol</span>):
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
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>
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
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>
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">"configurable quote"</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
418
<p>The only lines you might not understand are the last two.</p>
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>
430
<p><a href="index.html">Index</a></p>
431
<span class="version">Version: 9.0.0</span>
b'\\ No newline at end of file'