|
1
by Christopher Armstrong
Initial import of Corotwine. |
1 |
"""
|
2 |
Some sample protocols. This is meant to be an example; please read the source
|
|
3 |
code, not the API docs.
|
|
4 |
"""
|
|
5 |
import string, random |
|
6 |
||
|
6
by Christopher Armstrong
switch back to raising the original twisted reason exception for connection |
7 |
from twisted.internet.error import ConnectionClosed |
|
1
by Christopher Armstrong
Initial import of Corotwine. |
8 |
from twisted.protocols.amp import AMP, Command, String |
9 |
from twisted.web.client import getPage |
|
10 |
||
11 |
from corotwine.protocol import gListenTCP, gConnectTCP, LineBuffer |
|
12 |
from corotwine.defer import blockOn, deferredGreenlet |
|
|
14.1.1
by Jean-Paul Calderone
Centralize the choice about which greenlet library to use. Then add a fallback to that decision to the plain "greenlet" module if "py.magic.greenlet" is unavailable. |
13 |
from corotwine import greenlet |
|
1
by Christopher Armstrong
Initial import of Corotwine. |
14 |
|
15 |
||
16 |
def echo(transport): |
|
17 |
while 1: |
|
18 |
try: |
|
19 |
transport.write(transport.read()) |
|
20 |
except ConnectionClosed: |
|
21 |
return
|
|
22 |
||
23 |
||
24 |
def discard(transport): |
|
25 |
while 1: |
|
26 |
try: |
|
27 |
transport.read() |
|
28 |
except ConnectionClosed: |
|
29 |
return
|
|
30 |
||
31 |
||
32 |
def qotd(transport): |
|
33 |
transport.write("An apple a day keeps the doctor away.\r\n") |
|
34 |
||
35 |
||
36 |
def chargen(transport): |
|
37 |
# Sample of efficient streaming. transport.write switches back to the
|
|
38 |
# reactor greenlet when buffers are full.
|
|
39 |
while 1: |
|
40 |
try: |
|
41 |
transport.write(''.join(random.choice(string.letters) |
|
42 |
for i in range(1024))) |
|
43 |
except ConnectionClosed: |
|
44 |
return
|
|
45 |
||
46 |
||
47 |
class Chat(object): |
|
48 |
def __init__(self): |
|
49 |
self.clients = [] |
|
50 |
||
51 |
def handleConnection(self, transport): |
|
52 |
transport = LineBuffer(transport) |
|
53 |
self.clients.append(transport) |
|
54 |
try: |
|
55 |
try: |
|
56 |
for line in transport: |
|
57 |
for client in self.clients: |
|
58 |
if client is not transport: |
|
59 |
client.writeLine(line) |
|
60 |
finally: |
|
61 |
self.clients.remove(transport) |
|
|
9
by Christopher Armstrong
d'oh, ConnectionClosed not ConnectionLost |
62 |
except ConnectionClosed: |
|
1
by Christopher Armstrong
Initial import of Corotwine. |
63 |
return
|
64 |
||
65 |
||
66 |
def fetchGoogle(transport): |
|
67 |
result = blockOn(getPage("http://google.com/")) |
|
68 |
transport.write(result) |
|
69 |
||
70 |
||
|
12
by Christopher Armstrong
describe the return/raise semantics of connection-handling functions. |
71 |
|
|
1
by Christopher Armstrong
Initial import of Corotwine. |
72 |
## And an amp example, to show off deferredGreenlet
|
73 |
||
74 |
class FetchGoogle(Command): |
|
75 |
arguments = [] |
|
76 |
response = [("google", String())] |
|
77 |
||
78 |
class GoogleGetter(AMP): |
|
79 |
@FetchGoogle.responder
|
|
80 |
@deferredGreenlet
|
|
81 |
def fetchGoogle(self): |
|
82 |
return {"google": blockOn(getPage("http://google.com/"))} |
|
83 |
||
84 |
||
85 |
||
86 |
## Clients!
|
|
87 |
||
88 |
def echoclient(): |
|
89 |
transport = gConnectTCP("localhost", 1027) |
|
90 |
transport.write("Heyo!") |
|
91 |
if transport.read() == "Heyo!": |
|
92 |
print "Echo server test succeeded!" |
|
93 |
else: |
|
94 |
print "Echo server test failed :-(" |
|
95 |
||
96 |
||
97 |
def googleAMPClient(): |
|
98 |
from twisted.internet.protocol import ClientCreator |
|
99 |
cc = ClientCreator(reactor, AMP) |
|
100 |
ampConnection = blockOn(cc.connectTCP("localhost", 1030)) |
|
101 |
result = blockOn(ampConnection.callRemote(FetchGoogle)) |
|
102 |
if "I'm Feeling Lucky" in result["google"]: |
|
103 |
print "Google AMP Client test succeeded" |
|
104 |
else: |
|
105 |
print "Google AMP client test failed :-(" |
|
106 |
ampConnection.transport.loseConnection() |
|
107 |
||
108 |
||
109 |
# Deployment code
|
|
110 |
||
111 |
def startServers(): |
|
112 |
gListenTCP(1025, discard) |
|
113 |
gListenTCP(1026, qotd) |
|
114 |
gListenTCP(1027, echo) |
|
115 |
gListenTCP(1028, chargen) |
|
116 |
gListenTCP(1029, fetchGoogle) |
|
117 |
||
118 |
from twisted.internet.protocol import Factory |
|
119 |
ampf = Factory() |
|
120 |
ampf.protocol = GoogleGetter |
|
121 |
reactor.listenTCP(1030, ampf) |
|
122 |
||
123 |
chat = Chat() |
|
124 |
gListenTCP(1031, chat.handleConnection) |
|
125 |
||
126 |
||
127 |
if __name__ == '__main__': |
|
128 |
from twisted.internet import reactor |
|
129 |
from twisted.python.log import startLogging |
|
130 |
import sys |
|
131 |
startLogging(sys.stdout) |
|
132 |
||
133 |
startServers() |
|
134 |
greenlet(echoclient).switch() |
|
135 |
||
136 |
# Uncomment to test google thingy.
|
|
137 |
#greenlet(googleAMPClient).switch()
|
|
138 |
||
139 |
reactor.run() |