Bottle server with WebSocket (without other third-party libraries)

379 views Asked by At

I have read Bottle + WebSocket and the Github project bottle-websocket, but they all use gevent, or other third party tools.

Question: nowadays (2023), is there a way to do a simple Bottle + WebSocket hello world example, without any third party tool?

This is a beginning but it fails (see JS console) with:

(index):12 WebSocket connection to 'ws://127.0.0.1:5000/ws' failed

import bottle, random
app = bottle.Bottle()
@bottle.route("/")
def index():
    return bottle.static_file("index.html", root=".")
@bottle.route("/ws")
def ws():
    wsock = bottle.request.environ.get('wsgi.websocket')
    if not wsock:
        print('Expected WebSocket request.')
    while True:
        try:
            message = wsock.receive()
            wsock.send("Your message was: %r" % message)
        except:
            break
bottle.run(threaded=False, port=5000, debug=True)

HTML+JS code for index.html:

<html>
<body>
<div>
    hello
</div>
<script>
var ws = new WebSocket("ws://127.0.0.1:5000/ws");
ws.onopen = () => {
    ws.send("Hello, world");
 };
ws.onmessage = (evt) => {
    console.log(evt.data);
};
</script>
</body>
</html>
1

There are 1 answers

2
VonC On

"without any third party tool?": unlikely.

In your Python script, you're trying to access a WebSocket object (wsgi.websocket) from the WSGI (Web Server Gateway Interface) environment. However, the WSGI standard does not natively support WebSockets, and the Bottle web framework adheres to the WSGI standard. This means that it cannot handle WebSocket connections without additional tools that provide WebSocket support, such as gevent-websocket.

The error message (index):12 WebSocket connection to 'ws://127.0.0.1:5000/ws' failed is a result of this issue. The WebSocket connection request is made to the /ws route, but since Bottle does not support WebSockets, it does not know how to handle this request, so the connection fails.


If you want to create a WebSocket server in Python without any third-party libraries, you would typically use the websockets module in the Python standard library. However, Bottle does not natively support WebSockets, and the Python standard library does not include a WebSocket server or client.

Implementing WebSockets involves handling upgrade requests, managing connection state, and parsing and constructing WebSocket frames, which is non-trivial. Therefore, it's typically done using third-party libraries like gevent-websocket for Bottle, or websockets or aiohttp for Python in general.

It is theoretically possible to implement WebSocket support directly in a Bottle application by manually handling the HTTP upgrade request and then the WebSocket frames. However, this would essentially involve reimplementing a significant portion of what these third-party libraries do, and it would be quite complex. It would also likely be less efficient and less robust than using a dedicated WebSocket library.

If you want to avoid using third-party libraries, you might want to consider using a different framework that has built-in WebSocket support.
Like Flask framework, which has built-in WebSocket support via the Flask-Sock extension, and the Django framework, which has built-in WebSocket support via Django Channels. There's also Starlette, a lightweight ASGI framework that has native WebSocket support.

In any case, if you want to implement WebSockets in a Bottle application without using any third-party libraries, you would likely need to do a significant amount of low-level network programming, and you would need a deep understanding of the WebSocket protocol and how it interacts with the HTTP protocol.