Simple webserver

Chris Angelico rosuav at gmail.com
Wed Oct 18 19:23:41 EDT 2023


On Thu, 19 Oct 2023 at 10:07, Janis Papanagnou via Python-list
<python-list at python.org> wrote:
>
> I am pondering about writing a client/server software with
> websockets as communication protocol. The clients will run
> in browser as Javascript programs and the server may be in
> any (any sensible) programming language running standalone
> to be connected remotely by the browser-based JS clients.
>
> I found a Python sample[*] but I am neither familiar with
> Python nor with the 'simple_websocket_server' package that
> is used in that sample code. But the code looks so simple
> that I'm considering to learn and use Python for the task.
>
> The requirements I have are quite simple; I want to get the
> client "address"/identifier from an incoming message, store
> it in a list, and send responses to all active clients for
> which addresses have been stored.
>
> Can anyone tell me whether a simple extension of that "echo
> incoming message" sample[*] would be easily possible with
> Python and with that 'simple_websocket_server' package used?
>
> Thanks for any hints (or search keywords, or code samples)!

Oooh you've touched on one of my favourite topics. I *love* networking
and communication, and websockets are one of my well-used
technologies. Let's do this!!

I've never used the "simple_websocket_server" you mentioned, but I've
used this one in a few projects:

https://pypi.org/project/websockets/

Be aware that it is designed with asyncio in mind, so if you prefer
different concurrency models, you may need to look elsewhere. But I've
had good success with this one.

Broadly speaking, your ideas are great. Any programming language CAN
be used for the server (and I've used several, not just Python).

My personal preference is to build a protocol on top of websockets, for example:

* All messages are "text", and are JSON-encoded
* All messages represent objects (in Python, dictionaries) with a
"cmd" attribute
* The first message sent by the client has cmd "init" and specifies a
"type" and "group".
* The server tracks all connected clients by their groups, and can
broadcast messages to everyone in a group.

Here's one example, actually one of my brother's projects but I
contributed to the websocket aspects:

https://github.com/stephenangelico/BioBox/blob/master/browser.py

And here's one that doesn't actually use Python, but uses all the same
ideas; this is the JS end:

https://github.com/Rosuav/StilleBot/blob/master/httpstatic/ws_sync.js

(It has quite a bit more sophistication than you'll need to get
started with, but shows how the protocol can expand as needed.)

So! Tying this back in with your goals:

> The requirements I have are quite simple; I want to get the
> client "address"/identifier from an incoming message, store
> it in a list, and send responses to all active clients for
> which addresses have been stored.

Sounds to me like the best way would be for the socket group to be the
identifier of the client. You could augment the "init" message to
include some sort of authentication, or alternatively, rely on other
forms of authentication; a websocket established to the same origin as
the page itself can take advantage of regular browser credentials.

Once that's established, you can have a message from one client result
in the server sending out that message to all clients for the
recipient's address.

The reason I'm talking about "groups" here instead of simply having
one client per address is that it scales well to one person having
multiple tabs open, or having the app on their phone as well as their
computer, or anything like that. Messages will arrive on all of them.

Hope that's enough to get you started! I'd be delighted to help
further if you run into difficulties.

ChrisA


More information about the Python-list mailing list