Skip to content

Instantly share code, notes, and snippets.

@k9ert
Created July 4, 2022 14:43
Show Gist options
  • Save k9ert/9f91bfe94e9942ea0e02733e958fc26d to your computer and use it in GitHub Desktop.
Save k9ert/9f91bfe94e9942ea0e02733e958fc26d to your computer and use it in GitHub Desktop.
websockets with server-side code sending msgs out to clients
#!/usr/bin/env python3
import asyncio
import os
import subprocess
import sys
import time
import websockets
from websockets import connect
from flask import Flask, request, Response
python_path = sys.executable
script_path = os.path.realpath(__file__)
domain = 'localhost'
http_port = '5050'
ws_port = '5051'
### Flask Stuff
app = Flask(__name__)
html_page = '''<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebSocket Example</title>
</head>
<body>
<input id="textField" />
<p id="outputField" />
<script>
'''
html_page += f'websocket = new WebSocket("ws://{domain}:{ws_port}/");'
html_page += '''
textField = document.getElementById('textField');
outputField = document.getElementById('outputField');
textField.addEventListener('input', () => {
currentText = textField.value;
websocket.send(currentText);
});
websocket.addEventListener('message', (event) => {
outputField.innerHTML = event.data
})
</script>
</body>
</html>
'''
@app.route('/', methods=['GET'])
def respond2():
return Response(
status=200,
response=html_page
)
async def send_from_server(uri,msg):
async with connect(uri) as websocket:
await websocket.send(msg)
await websocket.recv()
@app.route('/input/<input>', methods=['GET'])
def input(input):
asyncio.run(send_from_server(f"ws://{domain}:{ws_port}/", input))
return Response(
status=200,
response=html_page
)
### Websocket stuff
CONNECTIONS = set()
async def register(websocket):
CONNECTIONS.add(websocket)
async def unregister(websocket):
CONNECTIONS.remove(websocket)
async def notify_users(message, websocket):
connection_list = []
for connection in CONNECTIONS:
if connection != websocket:
connection_list.append(connection)
await asyncio.wait([
connection.send(message) for connection in connection_list
])
async def message_control(websocket, path):
await register(websocket)
try:
await websocket.send("Connected")
async for message in websocket:
print(message)
await notify_users(message, websocket)
finally:
await unregister(websocket)
if len(sys.argv) == 2:
if sys.argv[1] == 'run_socket':
print("\nStarting websocker server")
start_server = websockets.serve(message_control, domain, ws_port)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
else:
time.sleep(1)
print("Triggering websocket server")
return_value = (subprocess.Popen([
python_path,
script_path,
'run_socket'
]))
print("Starting flask server")
app.run(port=http_port)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment