~radix/corotwine/trunk

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()