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).
3
# Copyright (C) 2013 Canonical Ltd.
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
7
# the Free Software Foundation.
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,
11
# SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
# Affero General Public License for more details.
14
# You should have received a copy of the GNU Affero General Public License
15
# along with this program. If not, see <http://www.gnu.org/licenses/>.
17
"""Juju GUI server websocket clients."""
26
def websocket_connect(io_loop, url, on_message_callback, headers=None):
27
"""WebSocket client connection factory.
29
The client factory receives the following arguments:
30
- io_loop: the Tornado IO loop instance;
31
- url: the WebSocket URL to use for the connection;
32
- on_message_callback: a callback that will be called each time
33
a new message is received by the client;
34
- headers (optional): a dict of additional headers to include in the
37
Return a Future whose result is a WebSocketClientConnection.
39
request = httpclient.HTTPRequest(
40
url, validate_cert=False, request_timeout=100)
41
if headers is not None:
42
request.headers.update(headers)
43
conn = WebSocketClientConnection(io_loop, request, on_message_callback)
44
return conn.connect_future
47
class WebSocketClientConnection(websocket.WebSocketClientConnection):
48
"""WebSocket client connection supporting secure WebSockets.
50
Use this connection as described in
51
<http://www.tornadoweb.org/en/stable/websocket.html#client-side-support>.
54
def __init__(self, io_loop, request, on_message_callback):
55
"""Client initializer.
57
The WebSocket client receives all the arguments accepted by
58
tornado.websocket.WebSocketClientConnection and a callback that will be
59
called each time a new message is received by the client.
61
super(WebSocketClientConnection, self).__init__(io_loop, request)
62
self._on_message_callback = on_message_callback
63
self.close_future = concurrent.Future()
65
def on_message(self, message):
66
"""Hook called when a new message is received.
68
The on_message_callback is called passing it the message.
70
super(WebSocketClientConnection, self).on_message(message)
71
self._on_message_callback(message)
74
"""Close the client connection.
76
Return a Future that is fired when the connection is terminated.
79
return self.close_future
82
"""Fire the close_future and send a None message."""
83
super(WebSocketClientConnection, self)._on_close()
84
# Since this is just a notification the Future result is set to None.
85
self.close_future.set_result(None)