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

« back to all changes in this revision

Viewing changes to doc/howto/pclients.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: Managing Clients of Perspectives</title><link href="stylesheet.css" type="text/css" rel="stylesheet" /><link href="http://twistedmatrix.com/users/acapnotic/" rel="author" title="Kevin Turner" /></head><body bgcolor="white"><h1 class="title">Managing Clients of Perspectives</h1><div class="toc"><ol><li><a href="#auto0">Overview</a></li><li><a href="#auto1">Managing Avatars</a></li><li><a href="#auto2">Managing Clients</a></li></ol></div><div class="content"><span></span><h2>Overview<a name="auto0"></a></h2><p>In all the <code class="API"><a href="http://twistedmatrix.com/documents/8.2.0/api/twisted.spread.pb.IPerspective.html" title="twisted.spread.pb.IPerspective">IPerspective</a></code>
 
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: Managing Clients of Perspectives</title>
 
8
<link href="stylesheet.css" rel="stylesheet" type="text/css"/>
 
9
  <link href="http://twistedmatrix.com/users/acapnotic/" rel="author" title="Kevin Turner"/></head>
 
10
 
 
11
  <body bgcolor="white">
 
12
    <h1 class="title">Managing Clients of Perspectives</h1>
 
13
    <div class="toc"><ol><li><a href="#auto0">Overview</a></li><li><a href="#auto1">Managing Avatars</a></li><li><a href="#auto2">Managing Clients</a></li></ol></div>
 
14
    <div class="content">
 
15
<span/>
 
16
 
 
17
<h2>Overview<a name="auto0"/></h2>
 
18
 
 
19
<p>In all the <code class="API"><a href="http://twistedmatrix.com/documents/9.0.0/api/twisted.spread.pb.IPerspective.html" title="twisted.spread.pb.IPerspective">IPerspective</a></code>
3
20
we have shown so far, we ignored the <code>mind</code> argument and created
4
21
a new <code>Avatar</code> for every connection. This is usually an easy
5
 
design choice, and it works well for simple cases.</p><p>In more complicated cases, for example an <code>Avatar</code> that
 
22
design choice, and it works well for simple cases.</p>
 
23
 
 
24
<p>In more complicated cases, for example an <code>Avatar</code> that
6
25
represents a player object which is persistent in the game universe,
7
26
we will want connections from the same player to use the same
8
 
<code>Avatar</code>.</p><p>Another thing which is necessary in more complicated scenarios
 
27
<code>Avatar</code>.</p>
 
28
 
 
29
<p>Another thing which is necessary in more complicated scenarios
9
30
is notifying a player asynchronously. While it is possible, of
10
31
course, to allow a player to call
11
32
<code>perspective_remoteListener(referencable)</code> that would
12
33
mean both duplication of code and a higher latency in logging in,
13
 
both bad.</p><p>In previous sections all realms looked to be identical.
 
34
both bad.</p>
 
35
 
 
36
<p>In previous sections all realms looked to be identical.
14
37
In this one we will show the usefulness of realms in accomplishing
15
 
those two objectives.</p><h2>Managing Avatars<a name="auto1"></a></h2><p>The simplest way to manage persistent avatars is to use a straight-forward
16
 
caching mechanism:</p><pre class="python">
17
 
<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">implements</span>
 
38
those two objectives.</p>
 
39
 
 
40
<h2>Managing Avatars<a name="auto1"/></h2>
 
41
 
 
42
<p>The simplest way to manage persistent avatars is to use a straight-forward
 
43
caching mechanism:</p>
 
44
 
 
45
<pre class="python"><p class="py-linenumber"> 1
 
46
 2
 
47
 3
 
48
 4
 
49
 5
 
50
 6
 
51
 7
 
52
 8
 
53
 9
 
54
10
 
55
11
 
56
12
 
57
13
 
58
14
 
59
15
 
60
16
 
61
17
 
62
18
 
63
19
 
64
20
 
65
21
 
66
22
 
67
23
 
68
</p><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">implements</span>
18
69
 
19
70
<span class="py-src-keyword">class</span> <span class="py-src-identifier">SimpleAvatar</span>(<span class="py-src-parameter">pb</span>.<span class="py-src-parameter">Avatar</span>):
20
71
    <span class="py-src-variable">greetings</span> = <span class="py-src-number">0</span>
37
88
        <span class="py-src-keyword">else</span>: 
38
89
            <span class="py-src-variable">p</span> = <span class="py-src-variable">self</span>.<span class="py-src-variable">avatars</span>[<span class="py-src-variable">avatarId</span>] = <span class="py-src-variable">SimpleAvatar</span>(<span class="py-src-variable">avatarId</span>)
39
90
        <span class="py-src-keyword">return</span> <span class="py-src-variable">pb</span>.<span class="py-src-variable">IPerspective</span>, <span class="py-src-variable">p</span>, <span class="py-src-keyword">lambda</span>:<span class="py-src-variable">None</span>
40
 
</pre><p>This gives us a perspective which counts the number of greetings it
 
91
</pre>       
 
92
 
 
93
<p>This gives us a perspective which counts the number of greetings it
41
94
sent its client. Implementing a caching strategy, as opposed to generating
42
95
a realm with the correct avatars already in it, is usually easier. This
43
96
makes adding new checkers to the portal, or adding new users to a checker
44
97
database, transparent. Otherwise, careful synchronization is needed between
45
98
the checker and avatar is needed (much like the synchronization between
46
 
UNIX's <code>/etc/shadow</code> and <code>/etc/passwd</code>).</p><p>Sometimes, however, an avatar will need enough per-connection state
 
99
UNIX's <code>/etc/shadow</code> and <code>/etc/passwd</code>).</p>
 
100
 
 
101
<p>Sometimes, however, an avatar will need enough per-connection state
47
102
that it would be easier to generate a new avatar and cache something
48
 
else. Here is an example of that:</p><pre class="python">
49
 
<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">implements</span>
 
103
else. Here is an example of that:</p>
 
104
 
 
105
<pre class="python"><p class="py-linenumber"> 1
 
106
 2
 
107
 3
 
108
 4
 
109
 5
 
110
 6
 
111
 7
 
112
 8
 
113
 9
 
114
10
 
115
11
 
116
12
 
117
13
 
118
14
 
119
15
 
120
16
 
121
17
 
122
18
 
123
19
 
124
20
 
125
21
 
126
22
 
127
23
 
128
24
 
129
25
 
130
26
 
131
27
 
132
28
 
133
29
 
134
</p><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">implements</span>
50
135
 
51
136
<span class="py-src-keyword">class</span> <span class="py-src-identifier">Greeter</span>:
52
137
    <span class="py-src-variable">greetings</span> = <span class="py-src-number">0</span>
75
160
        <span class="py-src-keyword">else</span>: 
76
161
            <span class="py-src-variable">p</span> = <span class="py-src-variable">self</span>.<span class="py-src-variable">greeters</span>[<span class="py-src-variable">avatarId</span>] = <span class="py-src-variable">Greeter</span>()
77
162
        <span class="py-src-keyword">return</span> <span class="py-src-variable">pb</span>.<span class="py-src-variable">IPerspective</span>, <span class="py-src-variable">SimpleAvatar</span>(<span class="py-src-variable">avatarId</span>, <span class="py-src-variable">p</span>), <span class="py-src-keyword">lambda</span>:<span class="py-src-variable">None</span>
78
 
</pre><p>It might seem tempting to use this pattern to have an avatar which
 
163
</pre>
 
164
 
 
165
<p>It might seem tempting to use this pattern to have an avatar which
79
166
is notified of new connections. However, the problems here are twofold:
80
167
it would lead to a thin class which needs to forward all of its methods,
81
168
and it would be impossible to know when disconnections occur. Luckily,
82
 
there is a better pattern:</p><pre class="python">
83
 
<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">implements</span>
 
169
there is a better pattern:</p>
 
170
 
 
171
<pre class="python"><p class="py-linenumber"> 1
 
172
 2
 
173
 3
 
174
 4
 
175
 5
 
176
 6
 
177
 7
 
178
 8
 
179
 9
 
180
10
 
181
11
 
182
12
 
183
13
 
184
14
 
185
15
 
186
16
 
187
17
 
188
18
 
189
19
 
190
20
 
191
21
 
192
22
 
193
23
 
194
24
 
195
25
 
196
26
 
197
27
 
198
28
 
199
29
 
200
</p><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">implements</span>
84
201
 
85
202
<span class="py-src-keyword">class</span> <span class="py-src-identifier">SimpleAvatar</span>(<span class="py-src-parameter">pb</span>.<span class="py-src-parameter">Avatar</span>):
86
203
    <span class="py-src-variable">greetings</span> = <span class="py-src-number">0</span>
109
226
            <span class="py-src-variable">p</span> = <span class="py-src-variable">self</span>.<span class="py-src-variable">avatars</span>[<span class="py-src-variable">avatarId</span>] = <span class="py-src-variable">SimpleAvatar</span>(<span class="py-src-variable">avatarId</span>)
110
227
        <span class="py-src-variable">p</span>.<span class="py-src-variable">connect</span>()
111
228
        <span class="py-src-keyword">return</span> <span class="py-src-variable">pb</span>.<span class="py-src-variable">IPerspective</span>, <span class="py-src-variable">p</span>, <span class="py-src-variable">p</span>.<span class="py-src-variable">disconnect</span>
112
 
</pre><p>It is possible to use such a pattern to define an arbitrary limit for
113
 
the number of concurrent connections:</p><pre class="python">
114
 
<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">implements</span>
 
229
</pre>
 
230
 
 
231
<p>It is possible to use such a pattern to define an arbitrary limit for
 
232
the number of concurrent connections:</p>
 
233
 
 
234
<pre class="python"><p class="py-linenumber"> 1
 
235
 2
 
236
 3
 
237
 4
 
238
 5
 
239
 6
 
240
 7
 
241
 8
 
242
 9
 
243
10
 
244
11
 
245
12
 
246
13
 
247
14
 
248
15
 
249
16
 
250
17
 
251
18
 
252
19
 
253
20
 
254
21
 
255
22
 
256
23
 
257
24
 
258
25
 
259
26
 
260
27
 
261
28
 
262
29
 
263
30
 
264
31
 
265
32
 
266
</p><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">implements</span>
115
267
 
116
268
<span class="py-src-keyword">class</span> <span class="py-src-identifier">SimpleAvatar</span>(<span class="py-src-parameter">pb</span>.<span class="py-src-parameter">Avatar</span>):
117
269
    <span class="py-src-variable">greetings</span> = <span class="py-src-number">0</span>
143
295
            <span class="py-src-keyword">raise</span> <span class="py-src-variable">ValueError</span>(<span class="py-src-string">&quot;too many connections&quot;</span>)
144
296
        <span class="py-src-variable">p</span>.<span class="py-src-variable">connect</span>()
145
297
        <span class="py-src-keyword">return</span> <span class="py-src-variable">pb</span>.<span class="py-src-variable">IPerspective</span>, <span class="py-src-variable">p</span>, <span class="py-src-variable">p</span>.<span class="py-src-variable">disconnect</span>
146
 
</pre><h2>Managing Clients<a name="auto2"></a></h2><p>So far, all our realms have ignored the <code>mind</code> argument.
 
298
</pre>
 
299
 
 
300
<h2>Managing Clients<a name="auto2"/></h2>
 
301
 
 
302
<p>So far, all our realms have ignored the <code>mind</code> argument.
147
303
In the case of PB, the <code>mind</code> is an object supplied by
148
304
the remote login method -- usually, when it passes over the wire,
149
305
it becomes a <code>pb.RemoteReference</code>. This object allows
150
306
sending messages to the client as soon as the connection is established
151
 
and authenticated.</p><p>Here is a simple remote-clock application which shows the usefulness
152
 
of the <code>mind</code> argument:</p><pre class="python">
153
 
<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">implements</span>
 
307
and authenticated.</p>
 
308
 
 
309
<p>Here is a simple remote-clock application which shows the usefulness
 
310
of the <code>mind</code> argument:</p>
 
311
 
 
312
<pre class="python"><p class="py-linenumber"> 1
 
313
 2
 
314
 3
 
315
 4
 
316
 5
 
317
 6
 
318
 7
 
319
 8
 
320
 9
 
321
10
 
322
11
 
323
12
 
324
13
 
325
14
 
326
15
 
327
16
 
328
17
 
329
18
 
330
19
 
331
20
 
332
21
 
333
22
 
334
23
 
335
</p><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">implements</span>
154
336
 
155
337
<span class="py-src-keyword">class</span> <span class="py-src-identifier">SimpleAvatar</span>(<span class="py-src-parameter">pb</span>.<span class="py-src-parameter">Avatar</span>):
156
338
    <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">client</span>):
173
355
        <span class="py-src-keyword">if</span> <span class="py-src-variable">pb</span>.<span class="py-src-variable">IPerspective</span> <span class="py-src-keyword">not</span> <span class="py-src-keyword">in</span> <span class="py-src-variable">interfaces</span>: <span class="py-src-keyword">raise</span> <span class="py-src-variable">NotImplementedError</span>
174
356
        <span class="py-src-variable">p</span> = <span class="py-src-variable">SimpleAvatar</span>(<span class="py-src-variable">mind</span>)
175
357
        <span class="py-src-keyword">return</span> <span class="py-src-variable">pb</span>.<span class="py-src-variable">IPerspective</span>, <span class="py-src-variable">p</span>, <span class="py-src-variable">p</span>.<span class="py-src-variable">logout</span>
176
 
</pre><p>In more complicated situations, you might want to cache the avatars
177
 
and give each one a set of <q>current clients</q> or something similar.</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'
 
358
</pre>
 
359
 
 
360
<p>In more complicated situations, you might want to cache the avatars
 
361
and give each one a set of <q>current clients</q> or something similar.</p>
 
362
 
 
363
</div>
 
364
 
 
365
    <p><a href="index.html">Index</a></p>
 
366
    <span class="version">Version: 9.0.0</span>
 
367
  </body>
 
368
</html>
 
 
b'\\ No newline at end of file'