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