Reputation: 1476
Here is a small websockets client and server POC. It sends a single hard-coded message string from the (Python) server to the Javascript client page.
The question is, how to send further, ad-hoc messages? From the server to the client.
Tiny HTML client page with embedded Javascript:
<!DOCTYPE html>
<html lang="en">
<body> See console for messages </body>
<script>
# Create websocket
const socket = new WebSocket('ws://localhost:8000');
# Add listener to receive server messages
socket.addEventListener('open', function (event) {
socket.send('Connection Established');
});
# Add message to browser console
socket.addEventListener('message', function (event) {
console.log(event.data);
});
</script>
</html>
Here is the Python server code:
import asyncio
import websockets
import time
# Create handler for each connection
async def handler(websocket, path):
await websocket.send("message from websockets server")
# Start websocket server
start_server = websockets.serve(handler, "localhost", 8000)
# Start async code
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
This successfully sends a hard-coded message from server to client. You can see the message in the browser console. At this point the websocket is open.
The main application (not shown) now needs to send messages. These will be dynamic messages, not hard-coded.
How can we send later, dynamic messages from the server? After the code here runs?
I would like to put the socket into a global variable and call a send method but this is not possible because the server runs a continuous loop.
Upvotes: 1
Views: 1962
Reputation: 1476
You can insert further messages into the Python server code like this:
import asyncio
import datetime
from typing import Iterator
import websockets
import random
websocket_connections = set()
sock_port = 8000
sock_url = 'localhost'
global_socket = lambda: None
async def register(websocket):
print('register event received')
websocket_connections.add(websocket) # Add this client's socket
global_socket = websocket
async def poll_log():
await asyncio.sleep(0.3) # Settle
while True:
await asyncio.sleep(0.3) # Slow things down
# Send a dynamic message to the client after random delay
r = random.randint(1, 10)
if (r == 5): # Only send 10% of the time
a_msg = "srv -> cli: " + str(random.randint(1,10000))
print("sending msg: " + a_msg)
websockets.broadcast(websocket_connections, a_msg) # Send to all connected clients
async def main():
sock_server = websockets.serve(register, sock_url, sock_port)
await asyncio.sleep(0.3) # Start up time
async with sock_server: await poll_log()
if __name__ == "__main__":
print("Websockets server starting up ...")
asyncio.run(main())
There is a very helpful example of a complete, full-duplex Websockets application here. That example is part of the Websockets 10.4 documentation. It's very helpful as a reference and to understand how websockets are used.
Upvotes: 2