Initial import to Tizen
[profile/ivi/python-twisted.git] / doc / core / howto / tutorial / client.html
1 <?xml version="1.0" encoding="utf-8"?><!DOCTYPE html  PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN'  'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
2   <head>
3 <title>Twisted Documentation: The Evolution of Finger: a Twisted finger client</title>
4 <link href="../stylesheet.css" rel="stylesheet" type="text/css"/>
5   </head>
6
7   <body bgcolor="white">
8     <h1 class="title">The Evolution of Finger: a Twisted finger client</h1>
9     <div class="toc"><ol><li><a href="#auto0">Introduction</a></li><li><a href="#auto1">Finger Proxy</a></li></ol></div>
10     <div class="content">
11
12 <span/>
13
14 <h2>Introduction<a name="auto0"/></h2>
15
16 <p> This is the ninth part of the Twisted tutorial <a href="index.html" shape="rect">Twisted from Scratch, or The Evolution of Finger</a>.</p>
17
18 <p>In this part, we develop a client for the finger server: a proxy finger
19 server which forwards requests to another finger server.</p>
20
21 <h2>Finger Proxy<a name="auto1"/></h2>
22
23 <p>Writing new clients with Twisted is much like writing new servers.
24 We implement the protocol, which just gathers up all the data, and
25 give it to the factory. The factory keeps a deferred which is triggered
26 if the connection either fails or succeeds. When we use the client,
27 we first make sure the deferred will never fail, by producing a message
28 in that case. Implementing a wrapper around client which just returns
29 the deferred is a common pattern.  While less flexible than
30 using the factory directly, it's also more convenient.</p>
31
32
33 <div class="py-listing"><pre><p class="py-linenumber">  1
34   2
35   3
36   4
37   5
38   6
39   7
40   8
41   9
42  10
43  11
44  12
45  13
46  14
47  15
48  16
49  17
50  18
51  19
52  20
53  21
54  22
55  23
56  24
57  25
58  26
59  27
60  28
61  29
62  30
63  31
64  32
65  33
66  34
67  35
68  36
69  37
70  38
71  39
72  40
73  41
74  42
75  43
76  44
77  45
78  46
79  47
80  48
81  49
82  50
83  51
84  52
85  53
86  54
87  55
88  56
89  57
90  58
91  59
92  60
93  61
94  62
95  63
96  64
97  65
98  66
99  67
100  68
101  69
102  70
103  71
104  72
105  73
106  74
107  75
108  76
109  77
110  78
111  79
112  80
113  81
114  82
115  83
116  84
117  85
118  86
119  87
120  88
121  89
122  90
123  91
124  92
125  93
126  94
127  95
128  96
129  97
130  98
131  99
132 100
133 101
134 102
135 103
136 104
137 105
138 106
139 107
140 108
141 109
142 110
143 </p><span class="py-src-comment"># finger proxy</span>
144 <span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">application</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">internet</span>, <span class="py-src-variable">service</span>
145 <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">defer</span>, <span class="py-src-variable">protocol</span>, <span class="py-src-variable">reactor</span>
146 <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-keyword">import</span> <span class="py-src-variable">basic</span>
147 <span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">python</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">components</span>
148 <span class="py-src-keyword">from</span> <span class="py-src-variable">zope</span>.<span class="py-src-variable">interface</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Interface</span>, <span class="py-src-variable">implements</span>
149
150
151 <span class="py-src-keyword">def</span> <span class="py-src-identifier">catchError</span>(<span class="py-src-parameter">err</span>):
152     <span class="py-src-keyword">return</span> <span class="py-src-string">&quot;Internal error in server&quot;</span>
153
154 <span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerService</span>(<span class="py-src-parameter">Interface</span>):
155
156     <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUser</span>(<span class="py-src-parameter">user</span>):
157         <span class="py-src-string">&quot;&quot;&quot;Return a deferred returning a string&quot;&quot;&quot;</span>
158
159     <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUsers</span>():
160         <span class="py-src-string">&quot;&quot;&quot;Return a deferred returning a list of strings&quot;&quot;&quot;</span>
161
162
163 <span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerFactory</span>(<span class="py-src-parameter">Interface</span>):
164
165     <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUser</span>(<span class="py-src-parameter">user</span>):
166         <span class="py-src-string">&quot;&quot;&quot;Return a deferred returning a string&quot;&quot;&quot;</span>
167
168     <span class="py-src-keyword">def</span> <span class="py-src-identifier">buildProtocol</span>(<span class="py-src-parameter">addr</span>):
169         <span class="py-src-string">&quot;&quot;&quot;Return a protocol returning a string&quot;&quot;&quot;</span>
170
171 <span class="py-src-keyword">class</span> <span class="py-src-identifier">FingerProtocol</span>(<span class="py-src-parameter">basic</span>.<span class="py-src-parameter">LineReceiver</span>):
172
173     <span class="py-src-keyword">def</span> <span class="py-src-identifier">lineReceived</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">user</span>):
174         <span class="py-src-variable">d</span> = <span class="py-src-variable">self</span>.<span class="py-src-variable">factory</span>.<span class="py-src-variable">getUser</span>(<span class="py-src-variable">user</span>)
175         <span class="py-src-variable">d</span>.<span class="py-src-variable">addErrback</span>(<span class="py-src-variable">catchError</span>)
176         <span class="py-src-keyword">def</span> <span class="py-src-identifier">writeValue</span>(<span class="py-src-parameter">value</span>):
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-variable">value</span>)
178             <span class="py-src-variable">self</span>.<span class="py-src-variable">transport</span>.<span class="py-src-variable">loseConnection</span>()
179         <span class="py-src-variable">d</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">writeValue</span>)
180
181
182
183 <span class="py-src-keyword">class</span> <span class="py-src-identifier">FingerFactoryFromService</span>(<span class="py-src-parameter">protocol</span>.<span class="py-src-parameter">ClientFactory</span>):
184
185     <span class="py-src-variable">implements</span>(<span class="py-src-variable">IFingerFactory</span>)
186
187     <span class="py-src-variable">protocol</span> = <span class="py-src-variable">FingerProtocol</span>
188
189     <span class="py-src-keyword">def</span> <span class="py-src-identifier">__init__</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">service</span>):
190         <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span> = <span class="py-src-variable">service</span>
191
192     <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUser</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">user</span>):
193         <span class="py-src-keyword">return</span> <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span>.<span class="py-src-variable">getUser</span>(<span class="py-src-variable">user</span>)
194
195
196 <span class="py-src-variable">components</span>.<span class="py-src-variable">registerAdapter</span>(<span class="py-src-variable">FingerFactoryFromService</span>,
197                            <span class="py-src-variable">IFingerService</span>,
198                            <span class="py-src-variable">IFingerFactory</span>)
199
200 <span class="py-src-keyword">class</span> <span class="py-src-identifier">FingerClient</span>(<span class="py-src-parameter">protocol</span>.<span class="py-src-parameter">Protocol</span>):
201
202     <span class="py-src-keyword">def</span> <span class="py-src-identifier">connectionMade</span>(<span class="py-src-parameter">self</span>):
203         <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">self</span>.<span class="py-src-variable">factory</span>.<span class="py-src-variable">user</span>+<span class="py-src-string">&quot;\r\n&quot;</span>)
204         <span class="py-src-variable">self</span>.<span class="py-src-variable">buf</span> = []
205
206     <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>):
207         <span class="py-src-variable">self</span>.<span class="py-src-variable">buf</span>.<span class="py-src-variable">append</span>(<span class="py-src-variable">data</span>)
208
209     <span class="py-src-keyword">def</span> <span class="py-src-identifier">connectionLost</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">reason</span>):
210         <span class="py-src-variable">self</span>.<span class="py-src-variable">factory</span>.<span class="py-src-variable">gotData</span>(<span class="py-src-string">''</span>.<span class="py-src-variable">join</span>(<span class="py-src-variable">self</span>.<span class="py-src-variable">buf</span>))
211
212 <span class="py-src-keyword">class</span> <span class="py-src-identifier">FingerClientFactory</span>(<span class="py-src-parameter">protocol</span>.<span class="py-src-parameter">ClientFactory</span>):
213
214     <span class="py-src-variable">protocol</span> = <span class="py-src-variable">FingerClient</span>
215
216     <span class="py-src-keyword">def</span> <span class="py-src-identifier">__init__</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">user</span>):
217         <span class="py-src-variable">self</span>.<span class="py-src-variable">user</span> = <span class="py-src-variable">user</span>
218         <span class="py-src-variable">self</span>.<span class="py-src-variable">d</span> = <span class="py-src-variable">defer</span>.<span class="py-src-variable">Deferred</span>()
219
220     <span class="py-src-keyword">def</span> <span class="py-src-identifier">clientConnectionFailed</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">_</span>, <span class="py-src-parameter">reason</span>):
221         <span class="py-src-variable">self</span>.<span class="py-src-variable">d</span>.<span class="py-src-variable">errback</span>(<span class="py-src-variable">reason</span>)
222
223     <span class="py-src-keyword">def</span> <span class="py-src-identifier">gotData</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">data</span>):
224         <span class="py-src-variable">self</span>.<span class="py-src-variable">d</span>.<span class="py-src-variable">callback</span>(<span class="py-src-variable">data</span>)
225
226
227 <span class="py-src-keyword">def</span> <span class="py-src-identifier">finger</span>(<span class="py-src-parameter">user</span>, <span class="py-src-parameter">host</span>, <span class="py-src-parameter">port</span>=<span class="py-src-number">79</span>):
228     <span class="py-src-variable">f</span> = <span class="py-src-variable">FingerClientFactory</span>(<span class="py-src-variable">user</span>)
229     <span class="py-src-variable">reactor</span>.<span class="py-src-variable">connectTCP</span>(<span class="py-src-variable">host</span>, <span class="py-src-variable">port</span>, <span class="py-src-variable">f</span>)
230     <span class="py-src-keyword">return</span> <span class="py-src-variable">f</span>.<span class="py-src-variable">d</span>
231
232
233 <span class="py-src-keyword">class</span> <span class="py-src-identifier">ProxyFingerService</span>(<span class="py-src-parameter">service</span>.<span class="py-src-parameter">Service</span>):
234     <span class="py-src-variable">implements</span>(<span class="py-src-variable">IFingerService</span>)
235
236     <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUser</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">user</span>):
237         <span class="py-src-keyword">try</span>:
238             <span class="py-src-variable">user</span>, <span class="py-src-variable">host</span> = <span class="py-src-variable">user</span>.<span class="py-src-variable">split</span>(<span class="py-src-string">'@'</span>, <span class="py-src-number">1</span>)
239         <span class="py-src-keyword">except</span>:
240             <span class="py-src-variable">user</span> = <span class="py-src-variable">user</span>.<span class="py-src-variable">strip</span>()
241             <span class="py-src-variable">host</span> = <span class="py-src-string">'127.0.0.1'</span>
242         <span class="py-src-variable">ret</span> = <span class="py-src-variable">finger</span>(<span class="py-src-variable">user</span>, <span class="py-src-variable">host</span>)
243         <span class="py-src-variable">ret</span>.<span class="py-src-variable">addErrback</span>(<span class="py-src-keyword">lambda</span> <span class="py-src-variable">_</span>: <span class="py-src-string">&quot;Could not connect to remote host&quot;</span>)
244         <span class="py-src-keyword">return</span> <span class="py-src-variable">ret</span>
245
246     <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUsers</span>(<span class="py-src-parameter">self</span>):
247         <span class="py-src-keyword">return</span> <span class="py-src-variable">defer</span>.<span class="py-src-variable">succeed</span>([])
248
249 <span class="py-src-variable">application</span> = <span class="py-src-variable">service</span>.<span class="py-src-variable">Application</span>(<span class="py-src-string">'finger'</span>, <span class="py-src-variable">uid</span>=<span class="py-src-number">1</span>, <span class="py-src-variable">gid</span>=<span class="py-src-number">1</span>)
250 <span class="py-src-variable">f</span> = <span class="py-src-variable">ProxyFingerService</span>()
251 <span class="py-src-variable">internet</span>.<span class="py-src-variable">TCPServer</span>(<span class="py-src-number">7779</span>, <span class="py-src-variable">IFingerFactory</span>(<span class="py-src-variable">f</span>)).<span class="py-src-variable">setServiceParent</span>(
252     <span class="py-src-variable">service</span>.<span class="py-src-variable">IServiceCollection</span>(<span class="py-src-variable">application</span>))
253 </pre><div class="caption">Source listing - <a href="listings/finger/fingerproxy.tac"><span class="filename">listings/finger/fingerproxy.tac</span></a></div></div>
254
255 </div>
256
257     <p><a href="../index.html">Index</a></p>
258     <span class="version">Version: 12.1.0</span>
259   </body>
260 </html>