comparison lib/twisted_sse_demo/sse_client.py @ 452:a8073bcddd8b

rewrite sse_demo for py3, better connection close behavior Ignore-this: eda5b7fcd8914eb9a751ec8471626cea
author drewp@bigasterisk.com
date Fri, 19 Apr 2019 04:18:44 -0700
parents 3d51d4b63497
children
comparison
equal deleted inserted replaced
451:17a556ddc5ac 452:a8073bcddd8b
1 from twisted.protocols.basic import LineReceiver 1 from twisted.protocols.basic import LineReceiver
2 2
3 3
4 class EventSourceProtocol(LineReceiver): 4 class EventSourceProtocol(LineReceiver):
5 def __init__(self): 5 def __init__(self, onConnectionLost):
6 self.onConnectionLost = onConnectionLost
7 self.delimiter = b'\n'
6 self.MAX_LENGTH = 1 << 20 8 self.MAX_LENGTH = 1 << 20
7 self.callbacks = {} 9 self.callbacks = {}
8 self.finished = None 10 self.finished = None
9 # Initialize the event and data buffers 11 # Initialize the event and data buffers
10 self.event = 'message' 12 self.event = b'message'
11 self.data = '' 13 self.data = b''
12 14
13 def lineLengthExceeded(self, line): 15 def lineLengthExceeded(self, line):
14 raise NotImplementedError('line too long') 16 raise NotImplementedError('line too long')
15 17
16 def setFinishedDeferred(self, d): 18 def setFinishedDeferred(self, d):
18 20
19 def addCallback(self, event, func): 21 def addCallback(self, event, func):
20 self.callbacks[event] = func 22 self.callbacks[event] = func
21 23
22 def lineReceived(self, line): 24 def lineReceived(self, line):
23 if line == '': 25 if line == b'':
24 # Dispatch event 26 # Dispatch event
25 self.dispatchEvent() 27 self.dispatchEvent()
26 else: 28 else:
27 try: 29 try:
28 field, value = line.split(':', 1) 30 field, value = line.split(b':', 1)
29 # If value starts with a space, strip it. 31 # If value starts with a space, strip it.
30 value = lstrip(value) 32 value = lstrip(value)
31 except ValueError: 33 except ValueError:
32 # We got a line with no colon, treat it as a field(ignore) 34 # We got a line with no colon, treat it as a field(ignore)
33 return 35 return
34 36
35 if field == '': 37 if field == b'':
36 # This is a comment; ignore 38 # This is a comment; ignore
37 pass 39 pass
38 elif field == 'data': 40 elif field == b'data':
39 self.data += value + '\n' 41 self.data += value + b'\n'
40 elif field == 'event': 42 elif field == b'event':
41 self.event = value 43 self.event = value
42 elif field == 'id': 44 elif field == b'id':
43 # Not implemented 45 # Not implemented
44 pass 46 pass
45 elif field == 'retry': 47 elif field == b'retry':
46 # Not implemented 48 # Not implemented
47 pass 49 pass
48 50
49 def connectionLost(self, reason): 51 def connectionLost(self, reason):
50 if self.finished: 52 self.onConnectionLost(reason)
51 self.finished.callback(None)
52 53
53 def dispatchEvent(self): 54 def dispatchEvent(self):
54 """ 55 """
55 Dispatch the event 56 Dispatch the event
56 """ 57 """
57 # If last character is LF, strip it. 58 # If last character is LF, strip it.
58 if self.data.endswith('\n'): 59 if self.data.endswith(b'\n'):
59 self.data = self.data[:-1] 60 self.data = self.data[:-1]
60 if self.event in self.callbacks: 61 if self.event in self.callbacks:
61 self.callbacks[self.event](self.data) 62 self.callbacks[self.event](self.data)
62 self.data = '' 63 self.data = b''
63 self.event = 'message' 64 self.event = b'message'
64 65
65 def lstrip(value): 66 def lstrip(value):
66 return value[1:] if value.startswith(' ') else value 67 return value[1:] if value.startswith(b' ') else value