Skip to content

Instantly share code, notes, and snippets.

@xprilion
Last active December 17, 2025 20:06
Show Gist options
  • Select an option

  • Save xprilion/ceab48ec77a70be1d403e396170991e6 to your computer and use it in GitHub Desktop.

Select an option

Save xprilion/ceab48ec77a70be1d403e396170991e6 to your computer and use it in GitHub Desktop.

Revisions

  1. xprilion revised this gist Nov 21, 2022. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion Python Websockets SSL with Let's Encrypt
    Original file line number Diff line number Diff line change
    @@ -6,4 +6,4 @@ You'll need to generate the certificate and keyfile using Let's Encrypt.

    After generating the files correctly, you need to make them accessible to the current user who runs the script, my way of doing this was to copy it to the home directory of the current user and change the owner to the current user, set the permissions of the files to 400.

    To know more about this process, read the blog here - (https://xprilion.com/python-websockets-ssl-with-lets-encrypt/)[https://xprilion.com/python-websockets-ssl-with-lets-encrypt/]
    To know more about this process, read the blog here - https://xprilion.com/python-websockets-ssl-with-lets-encrypt/
  2. xprilion revised this gist Nov 21, 2022. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion Python Websockets SSL with Let's Encrypt
    Original file line number Diff line number Diff line change
    @@ -6,4 +6,4 @@ You'll need to generate the certificate and keyfile using Let's Encrypt.

    After generating the files correctly, you need to make them accessible to the current user who runs the script, my way of doing this was to copy it to the home directory of the current user and change the owner to the current user, set the permissions of the files to 400.

    To know more about this process, read the blog here - [https://xprilion.com/python-websockets-ssl-with-lets-encrypt/](https://xprilion.com/python-websockets-ssl-with-lets-encrypt/)
    To know more about this process, read the blog here - (https://xprilion.com/python-websockets-ssl-with-lets-encrypt/)[https://xprilion.com/python-websockets-ssl-with-lets-encrypt/]
  3. xprilion revised this gist Nov 21, 2022. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion Python Websockets SSL with Let's Encrypt
    Original file line number Diff line number Diff line change
    @@ -6,4 +6,4 @@ You'll need to generate the certificate and keyfile using Let's Encrypt.

    After generating the files correctly, you need to make them accessible to the current user who runs the script, my way of doing this was to copy it to the home directory of the current user and change the owner to the current user, set the permissions of the files to 400.

    To know more about this process, read the blog here - https://xprilion.com/python-websockets-ssl-with-lets-encrypt/
    To know more about this process, read the blog here - [https://xprilion.com/python-websockets-ssl-with-lets-encrypt/](https://xprilion.com/python-websockets-ssl-with-lets-encrypt/)
  4. xprilion revised this gist Nov 21, 2022. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion Python Websockets SSL with Let's Encrypt
    Original file line number Diff line number Diff line change
    @@ -4,4 +4,6 @@ This code uses the `python-websockets` library.

    You'll need to generate the certificate and keyfile using Let's Encrypt.

    After generating the files correctly, you need to make them accessible to the current user who runs the script, my way of doing this was to copy it to the home directory of the current user and change the owner to the current user, set the permissions of the files to 400.
    After generating the files correctly, you need to make them accessible to the current user who runs the script, my way of doing this was to copy it to the home directory of the current user and change the owner to the current user, set the permissions of the files to 400.

    To know more about this process, read the blog here - https://xprilion.com/python-websockets-ssl-with-lets-encrypt/
  5. xprilion revised this gist Apr 5, 2021. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion socket_client.html
    Original file line number Diff line number Diff line change
    @@ -51,7 +51,7 @@
    plus = document.querySelector('.plus'),
    value = document.querySelector('.value'),
    users = document.querySelector('.users'),
    websocket = new WebSocket("wss://gpu.dpi.one:6789/");
    websocket = new WebSocket("wss://localhost:6789/");
    minus.onclick = function (event) {
    websocket.send(JSON.stringify({action: 'minus'}));
    }
  6. xprilion revised this gist Apr 1, 2021. 2 changed files with 0 additions and 0 deletions.
    File renamed without changes.
    File renamed without changes.
  7. xprilion revised this gist Apr 1, 2021. No changes.
  8. xprilion renamed this gist Apr 1, 2021. 1 changed file with 0 additions and 0 deletions.
  9. xprilion revised this gist Apr 1, 2021. 3 changed files with 5 additions and 1 deletion.
    6 changes: 5 additions & 1 deletion Python Websockets SSL with Let's Encrypt.md
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,7 @@
    ## Python Websockets SSL with Lets Encrypt

    Needs to be used with a Client, example: https://gist.github.com/xprilion/aec07a8878882b7b06c596c174fd8b5b
    This code uses the `python-websockets` library.

    You'll need to generate the certificate and keyfile using Let's Encrypt.

    After generating the files correctly, you need to make them accessible to the current user who runs the script, my way of doing this was to copy it to the home directory of the current user and change the owner to the current user, set the permissions of the files to 400.
    File renamed without changes.
    File renamed without changes.
  10. xprilion renamed this gist Apr 1, 2021. 1 changed file with 0 additions and 0 deletions.
  11. xprilion revised this gist Apr 1, 2021. 2 changed files with 79 additions and 0 deletions.
    79 changes: 79 additions & 0 deletions socket_client.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,79 @@
    <html>
    <head>
    <title>WebSocket demo</title>
    <style type="text/css">
    body {
    font-family: "Courier New", sans-serif;
    text-align: center;
    }
    .buttons {
    font-size: 4em;
    display: flex;
    justify-content: center;
    }
    .button, .value {
    line-height: 1;
    padding: 2rem;
    margin: 2rem;
    border: medium solid;
    min-height: 1em;
    min-width: 1em;
    }
    .button {
    cursor: pointer;
    user-select: none;
    }
    .minus {
    color: red;
    }
    .plus {
    color: green;
    }
    .value {
    min-width: 2em;
    }
    .state {
    font-size: 2em;
    }
    </style>
    </head>
    <body>
    <div class="buttons">
    <div class="minus button">-</div>
    <div class="value">?</div>
    <div class="plus button">+</div>
    </div>
    <div class="state">
    <span class="users">?</span> online
    </div>
    <script>
    var minus = document.querySelector('.minus'),
    plus = document.querySelector('.plus'),
    value = document.querySelector('.value'),
    users = document.querySelector('.users'),
    websocket = new WebSocket("wss://gpu.dpi.one:6789/");
    minus.onclick = function (event) {
    websocket.send(JSON.stringify({action: 'minus'}));
    }
    plus.onclick = function (event) {
    websocket.send(JSON.stringify({action: 'plus'}));
    }
    websocket.onmessage = function (event) {
    data = JSON.parse(event.data);
    switch (data.type) {
    case 'state':
    value.textContent = data.value;
    break;
    case 'users':
    users.textContent = (
    data.count.toString() + " user" +
    (data.count == 1 ? "" : "s"));
    break;
    default:
    console.error(
    "unsupported event", data);
    }
    };
    </script>
    </body>
    </html
  12. xprilion renamed this gist Apr 1, 2021. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  13. xprilion revised this gist Apr 1, 2021. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -1 +1,3 @@
    ABC
    ## Python Websockets SSL with Lets Encrypt

    Needs to be used with a Client, example: https://gist.github.com/xprilion/aec07a8878882b7b06c596c174fd8b5b
  14. xprilion created this gist Apr 1, 2021.
    1 change: 1 addition & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    ABC
    77 changes: 77 additions & 0 deletions socket_server.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,77 @@
    #!/usr/bin/env python

    # WS server example that synchronizes state across clients

    import asyncio
    import json
    import logging
    import websockets
    import ssl

    logging.basicConfig()
    ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)

    # Generate with Lets Encrypt, copied to this location, chown to current user and 400 permissions
    ssl_cert = "/home/username/fullchain.pem"
    ssl_key = "/home/username/privkey.pem"

    ssl_context.load_cert_chain(ssl_cert, keyfile=ssl_key)

    STATE = {"value": 0}

    USERS = set()


    def state_event():
    return json.dumps({"type": "state", **STATE})


    def users_event():
    return json.dumps({"type": "users", "count": len(USERS)})


    async def notify_state():
    if USERS: # asyncio.wait doesn't accept an empty list
    message = state_event()
    await asyncio.wait([user.send(message) for user in USERS])


    async def notify_users():
    if USERS: # asyncio.wait doesn't accept an empty list
    message = users_event()
    await asyncio.wait([user.send(message) for user in USERS])


    async def register(websocket):
    USERS.add(websocket)
    await notify_users()


    async def unregister(websocket):
    USERS.remove(websocket)
    await notify_users()


    async def counter(websocket, path):
    # register(websocket) sends user_event() to websocket
    await register(websocket)
    try:
    await websocket.send(state_event())
    async for message in websocket:
    data = json.loads(message)
    if data["action"] == "minus":
    STATE["value"] -= 1
    await notify_state()
    elif data["action"] == "plus":
    STATE["value"] += 1
    await notify_state()
    else:
    logging.error("unsupported event: {}", data)
    finally:
    await unregister(websocket)


    start_server = websockets.serve(counter, "0.0.0.0", 6789, ssl=ssl_context)

    asyncio.get_event_loop().run_until_complete(start_server)
    asyncio.get_event_loop().run_forever()