Skip to content

Commit 18505f6

Browse files
Merge pull request #508 from vladkol-eqwu/master
Dynamic server address:port for the client websocket, thanks to @vladkol
2 parents 06a2c49 + d2885f4 commit 18505f6

3 files changed

Lines changed: 29 additions & 11 deletions

File tree

README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
</h2>
1010

1111
<p align="center" style="white-space:pre">
12-
Remi is a GUI library for Python applications that gets rendered in web browsers.
12+
Remi is a GUI library for Python applications that gets rendered in web browsers.
1313
This allows you to access your interface locally and remotely.
1414
</p>
1515

@@ -166,7 +166,7 @@ Run the script. If it's all OK the GUI will be opened automatically in your brow
166166
You can customize optional parameters in the `start` call like:
167167

168168
```py
169-
start(MyApp, address='127.0.0.1', port=8081, multiple_instance=False, enable_file_cache=True, update_interval=0.1, start_browser=True)
169+
start(MyApp, address='127.0.0.1', port=8081, multiple_instance=False, enable_file_cache=True, update_interval=0.1, start_browser=True, dynamic_web_address=True)
170170
```
171171

172172
Parameters:
@@ -184,6 +184,8 @@ Additional Parameters:
184184
- certfile: SSL certificate filename
185185
- keyfile: SSL key file
186186
- ssl_version: authentication version (i.e. ssl.PROTOCOL_TLSv1_2). If None disables SSL encryption
187+
- dynamic_web_address: set it to `True` if the server is not aware of the IP address and the URL the user will be opening the app with.
188+
If so, the JavaScript code will use hostname and port in the browser. This parameter is `False` by default.
187189

188190
All widgets constructors accept two standards**kwargs that are:
189191
- width: can be expressed as int (and is interpreted as a pixel) or as str (and you can specify the measuring unit like '10%')
@@ -312,9 +314,10 @@ Remote access
312314
===
313315
If you are using your REMI app remotely, with a DNS and behind a firewall, you can specify special parameters in the `start` call:
314316
- **port**: HTTP server port. Don't forget to NAT this port on your router;
317+
- **dynamic_web_address**: set to `True` if the JavaScript code should use the actual URL's host and port for connecting back to the app, instead of provided IP address. This parameter is `False` by default.
315318

316319
```py
317-
start(MyApp, address='0.0.0.0', port=8081)
320+
start(MyApp, address='0.0.0.0', port=8081, dynamic_web_address=True)
318321
```
319322

320323

remi/gui.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1402,7 +1402,17 @@ def set_internal_js(self, app_identifier, net_interface_ip, pending_messages_que
14021402
14031403
var self = this;
14041404
try{
1405-
this._ws = new WebSocket(ws_wss + '://%(host)s/');
1405+
host = '%(host)s'
1406+
if (host !== ''){
1407+
wss_url = `${ws_wss}://${host}/`
1408+
}
1409+
else{
1410+
host = document.location.host;
1411+
pathname = document.location.pathname;
1412+
wss_url = `${ws_wss}://${document.location.host}${pathname}`;
1413+
}
1414+
1415+
this._ws = new WebSocket(wss_url);
14061416
console.debug('opening websocket');
14071417
14081418
this._ws.onopen = function(evt){

remi/server.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -437,8 +437,8 @@ def _instance(self):
437437
self._need_update_flag = client._need_update_flag
438438
if hasattr(client, '_update_thread'):
439439
self._update_thread = client._update_thread
440-
441-
net_interface_ip = self._net_interface_ip()
440+
441+
net_interface_ip = self._net_interface_ip() if not self.server.dynamic_web_address else ''
442442
websocket_timeout_timer_ms = str(self.server.websocket_timeout_timer_ms)
443443
pending_messages_queue_length = str(self.server.pending_messages_queue_length)
444444
self.page.children['head'].set_internal_js(str(id(self)), net_interface_ip, pending_messages_queue_length, websocket_timeout_timer_ms)
@@ -794,7 +794,9 @@ class ThreadedHTTPServer(socketserver.ThreadingMixIn, HTTPServer):
794794
def __init__(self, server_address, RequestHandlerClass,
795795
auth, multiple_instance, enable_file_cache, update_interval,
796796
websocket_timeout_timer_ms, pending_messages_queue_length,
797-
title, server_starter_instance, certfile, keyfile, ssl_version, *userdata):
797+
title, server_starter_instance, certfile, keyfile, ssl_version,
798+
dynamic_web_address,
799+
*userdata):
798800
HTTPServer.__init__(self, server_address, RequestHandlerClass)
799801
self.auth = auth
800802
self.multiple_instance = multiple_instance
@@ -804,6 +806,7 @@ def __init__(self, server_address, RequestHandlerClass,
804806
self.pending_messages_queue_length = pending_messages_queue_length
805807
self.title = title
806808
self.server_starter_instance = server_starter_instance
809+
self.dynamic_web_address = dynamic_web_address
807810
self.userdata = userdata
808811

809812
self.certfile = certfile
@@ -817,8 +820,8 @@ class Server(object):
817820
# noinspection PyShadowingNames
818821
def __init__(self, gui_class, title='', start=True, address='127.0.0.1', port=0, username=None, password=None,
819822
multiple_instance=False, enable_file_cache=True, update_interval=0.1, start_browser=True,
820-
websocket_timeout_timer_ms=1000, pending_messages_queue_length=1000,
821-
certfile=None, keyfile=None, ssl_version=None, userdata=()):
823+
websocket_timeout_timer_ms=1000, pending_messages_queue_length=1000,
824+
certfile=None, keyfile=None, ssl_version=None, userdata=(), dynamic_web_address=False):
822825

823826
self._gui = gui_class
824827
self._title = title or gui_class.__name__
@@ -837,6 +840,7 @@ def __init__(self, gui_class, title='', start=True, address='127.0.0.1', port=0,
837840
self._keyfile = keyfile
838841
self._ssl_version = ssl_version
839842
self._userdata = userdata
843+
self._dynamic_web_address = dynamic_web_address
840844
if username and password:
841845
self._auth = base64.b64encode(encode_text("%s:%s" % (username, password)))
842846
else:
@@ -866,8 +870,9 @@ def start(self):
866870
self._sserver = ThreadedHTTPServer((self._address, self._sport), self._gui, self._auth,
867871
self._multiple_instance, self._enable_file_cache,
868872
self._update_interval, self._websocket_timeout_timer_ms,
869-
self._pending_messages_queue_length, self._title,
870-
self, self._certfile, self._keyfile, self._ssl_version, *self._userdata)
873+
self._pending_messages_queue_length, self._title,
874+
self, self._certfile, self._keyfile, self._ssl_version, self._dynamic_web_address,
875+
*self._userdata)
871876
shost, sport = self._sserver.socket.getsockname()[:2]
872877
self._log.info('Started httpserver http://%s:%s/'%(shost,sport))
873878
# when listening on multiple net interfaces the browsers connects to localhost

0 commit comments

Comments
 (0)