Left: | ||
Right: |
LEFT | RIGHT |
---|---|
1 # This file is part of the Juju GUI, which lets users view and manage Juju | 1 # This file is part of the Juju GUI, which lets users view and manage Juju |
2 # environments within a graphical interface (https://launchpad.net/juju-gui). | 2 # environments within a graphical interface (https://launchpad.net/juju-gui). |
3 # Copyright (C) 2013 Canonical Ltd. | 3 # Copyright (C) 2013 Canonical Ltd. |
4 # | 4 # |
5 # This program is free software: you can redistribute it and/or modify it under | 5 # This program is free software: you can redistribute it and/or modify it under |
6 # the terms of the GNU Affero General Public License version 3, as published by | 6 # the terms of the GNU Affero General Public License version 3, as published by |
7 # the Free Software Foundation. | 7 # the Free Software Foundation. |
8 # | 8 # |
9 # This program is distributed in the hope that it will be useful, but WITHOUT | 9 # This program is distributed in the hope that it will be useful, but WITHOUT |
10 # ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, | 10 # ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, |
(...skipping 14 matching lines...) Expand all Loading... | |
25 | 25 |
26 class WebSocketClient(tornadoclient.TornadoWebSocketClient): | 26 class WebSocketClient(tornadoclient.TornadoWebSocketClient): |
27 """WebSocket client implementation supporting secure WebSockets.""" | 27 """WebSocket client implementation supporting secure WebSockets.""" |
28 | 28 |
29 def __init__(self, url, on_message_received, *args, **kwargs): | 29 def __init__(self, url, on_message_received, *args, **kwargs): |
30 """Client initializer. | 30 """Client initializer. |
31 | 31 |
32 The WebSocket client receives two arguments: | 32 The WebSocket client receives two arguments: |
33 - url: the WebSocket URL to use for the connection; | 33 - url: the WebSocket URL to use for the connection; |
34 - on_message_received: a callback that will be called each time a | 34 - on_message_received: a callback that will be called each time a |
35 new message is received by the client. | 35 new message is received by the client. |
bac
2013/07/18 21:52:56
I'd say something about the optional *args and **k
frankban
2013/07/19 10:27:48
Done.
| |
36 | |
37 It also accepts all the args and kwargs accepted by | |
38 ws4py.client.tornadoclient.TornadoWebSocketClient. | |
36 """ | 39 """ |
37 super(WebSocketClient, self).__init__(url, *args, **kwargs) | 40 super(WebSocketClient, self).__init__(url, *args, **kwargs) |
38 self.connected = False | 41 self.connected = False |
39 self._connected_future = Future() | 42 self._connected_future = Future() |
40 self._closed_future = Future() | 43 self._closed_future = Future() |
41 self._queue = deque() | 44 self._queue = deque() |
42 self._on_message_received = on_message_received | 45 self._on_message_received = on_message_received |
43 | 46 |
44 def connect(self, *args, **kwargs): | 47 def connect(self, *args, **kwargs): |
45 super(WebSocketClient, self).connect(*args, **kwargs) | 48 super(WebSocketClient, self).connect(*args, **kwargs) |
46 return self._connected_future | 49 return self._connected_future |
47 | 50 |
48 def opened(self): | 51 def opened(self): |
49 """Hook called when the connection is initially established.""" | 52 """Hook called when the connection is initially established.""" |
50 logging.debug('ws client: connected') | 53 logging.debug('ws client: connected') |
51 self._connected_future.set_result(None) | 54 self._connected_future.set_result(None) |
52 self.connected = True | 55 self.connected = True |
53 # Send all the messages that have been enqueued before the connection | 56 # Send all the messages that have been enqueued before the connection |
54 # was established. | 57 # was established. |
55 queue = self._queue | 58 queue = self._queue |
56 while self.connected and len(queue): | 59 while self.connected and len(queue): |
57 self.send(queue.popleft()) | 60 self.send(queue.popleft()) |
58 | 61 |
59 def send(self, message, *args, **kwargs): | 62 def send(self, message, *args, **kwargs): |
60 """Override to fix the socket problem.""" | 63 """Override to fix the socket problem.""" |
61 # FIXME: find a way to avoid redifining self.sock here. | 64 # FIXME: find a way to avoid redefining self.sock here. |
bac
2013/07/18 21:52:56
typo: redefining
frankban
2013/07/19 10:27:48
Done.
| |
62 self.sock = self.io.socket | 65 self.sock = self.io.socket |
63 logging.debug('ws client: send message: {}'.format(message)) | 66 logging.debug('ws client: send message: {}'.format(message)) |
64 super(WebSocketClient, self).send(message, *args, **kwargs) | 67 super(WebSocketClient, self).send(message, *args, **kwargs) |
65 | 68 |
66 def write_message(self, message): | 69 def write_message(self, message): |
67 """Send a message on the WebSocket connection. | 70 """Send a message on the WebSocket connection. |
68 | 71 |
69 Wrap self.send so that messages sent before the connection is | 72 Wrap self.send so that messages sent before the connection is |
70 established are queued for later delivery. | 73 established are queued for later delivery. |
71 """ | 74 """ |
72 if self.connected: | 75 if self.connected: |
73 logging.debug('ws client: send message: {}'.format(message)) | 76 logging.debug('ws client: send message: {}'.format(message)) |
74 return self.send(message) | 77 return self.send(message) |
75 logging.debug('ws client: queue message: {}'.format(message)) | 78 logging.debug('ws client: queue message: {}'.format(message)) |
76 self._queue.append(message) | 79 self._queue.append(message) |
77 | 80 |
78 def received_message(self, message): | 81 def received_message(self, message): |
79 """Hook called when a new message is received.""" | 82 """Hook called when a new message is received.""" |
80 logging.debug('ws client: received message: {}'.format(message)) | 83 logging.debug('ws client: received message: {}'.format(message)) |
81 self._on_message_received(message.data) | 84 self._on_message_received(message.data) |
82 | 85 |
83 def close(self, *args, **kwargs): | 86 def close(self, *args, **kwargs): |
84 # FIXME: find a way to avoid redifining self.sock here. | 87 # FIXME: find a way to avoid redefining self.sock here. |
bac
2013/07/18 21:52:56
same typo
frankban
2013/07/19 10:27:48
Done.
| |
85 self.sock = self.io.socket | 88 self.sock = self.io.socket |
86 super(WebSocketClient, self).close(*args, **kwargs) | 89 super(WebSocketClient, self).close(*args, **kwargs) |
87 return self._closed_future | 90 return self._closed_future |
88 | 91 |
89 def closed(self, code, reason=None): | 92 def closed(self, code, reason=None): |
90 """Hook called when the connection is terminated.""" | 93 """Hook called when the connection is terminated.""" |
91 logging.debug('ws client: closed ({})'.format(code)) | 94 logging.debug('ws client: closed ({})'.format(code)) |
92 # FIXME: closed should be called only once. | 95 # FIXME: closed should be called only once. |
93 if not self._closed_future.done(): | 96 if not self._closed_future.done(): |
94 self._closed_future.set_result(None) | 97 self._closed_future.set_result(None) |
95 self.connected = False | 98 self.connected = False |
96 | 99 |
97 def _cleanup(self, *args, **kwargs): | 100 def _cleanup(self, *args, **kwargs): |
98 # FIXME: this seems clearly an error in ws4py. | 101 # FIXME: this seems clearly an error in ws4py. The internal |
bac
2013/07/18 21:52:56
Maybe explain what you're referring to here.
frankban
2013/07/19 10:27:48
Done.
| |
102 # TornadoWebSocketClient.__stream_closed method calls an undefined | |
103 # self._cleanup(). | |
99 pass | 104 pass |
LEFT | RIGHT |