I'm just trying to get a very basic websocket connection over internet. The code seems fine - because it works when connecting to localhost - but for some reason fails when I try to use it over the internet. I'm using the websockets library, and my server looks like this:
#!/usr/bin/env python3
import asyncio
import websockets
from logging import getLogger, INFO, StreamHandler
logger = getLogger('websockets')
logger.setLevel(INFO)
logger.addHandler(StreamHandler())
clients = set()
async def handler(websocket, path):
global clients
clients.add(websocket)
try:
await asyncio.wait([ws.send("Hello!") for ws in clients])
await asyncio.sleep(10)
finally:
clients.remove(websocket)
start_server = websockets.serve(handler, host='127.0.0.1', port=6969)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
and the client looks like this:
<!DOCTYPE html>
<html lang="en"><head>
<meta charset="UTF-8">
<title>Chat</title>
</head>
<body style="margin:0">
<script type="text/javascript">
var ws = new WebSocket("ws://127.0.0.1:6969/");
var messages = document.getElementById('messages');
ws.onmessage = function (event) {
var messages = document.getElementById('messages');
var message = document.createElement('li');
var content = document.createTextNode(event.data);
message.appendChild(content);
messages.appendChild(message);
};
</script>
Messages:
<ul id="messages"><li>Hello!</li></ul>
</body></html>
So the issue is that the client above works fine, until I run the server on my Ubuntu machine (and I've made sure to forward port 6969 to that machine) and try to connect over the internet. Hostname resolution is working fine, because I can ssh
in to start the server, but trying to connect to the websocket always shows me the error message:
Firefox can’t establish a connection to the server at ws://<remote server url>:6969/.
or similiar for other browsers. Also, in case anyone was wondering, the logger isn't outputting anything useful (since the connection is failing the server isn't doing anything).
Your line:
websockets.serve(handler, host='127.0.0.1', port=6969)
provides a specific address on which the websockets server listens. Your server will only listen on that address; any requests to any other address will never be seen.
From https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.create_server :
The
host
parameter can be a string, in that case the TCP server is bound tohost
andport
. The host parameter can also be a sequence of strings and in that case the TCP server is bound to all hosts of the sequence. Ifhost
is an empty string orNone
, all interfaces are assumed and a list of multiple sockets will be returned (most likely one for IPv4 and another one for IPv6).
You have bound your webserver to 127.0.0.1
, which is a special address that only ever refers to the local machine. This address is also known as localhost
. No other machine can ever connect to your localhost
.
The solution is to provide an empty string or None
(the default value). In this case, your web server will listen for requests sent to any address.
websockets.serve(handler, port=6969)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With