~justin-fathomdb/nova/justinsb-openstack-api-volumes

« back to all changes in this revision

Viewing changes to vendor/Twisted-10.0.0/doc/core/howto/pclients.html

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

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