Compare commits
No commits in common. "d5f1e76383d7f808de4d82e005244fcfeb10231b" and "0465e66ee9804735b559eb023cb4d34a89fd5ad8" have entirely different histories.
d5f1e76383
...
0465e66ee9
|
|
@ -1,49 +0,0 @@
|
||||||
InstantChat WebSocket Protocol
|
|
||||||
==============================
|
|
||||||
|
|
||||||
Messages from client to server (commands)
|
|
||||||
-----------------------------------------
|
|
||||||
|
|
||||||
JSON objects. Key `action` determines type of message.
|
|
||||||
|
|
||||||
### init
|
|
||||||
Initialize the connection, set nickname and join/create a chat.
|
|
||||||
|
|
||||||
**Parameters:**
|
|
||||||
* `action` = `"init"`
|
|
||||||
* `chat_id`: either an existing ID of a chat instance or *[TODO: ?]* empty string to
|
|
||||||
create a new chat
|
|
||||||
* `nickname`: user's chosen nickname *[TODO: valid characters?]*
|
|
||||||
|
|
||||||
**Example:**
|
|
||||||
|
|
||||||
{
|
|
||||||
"action": "init",
|
|
||||||
"chat_id": "42",
|
|
||||||
"nickname": "Alice"
|
|
||||||
}
|
|
||||||
|
|
||||||
### send (?)
|
|
||||||
Send a message...
|
|
||||||
|
|
||||||
*[TODO]*
|
|
||||||
|
|
||||||
|
|
||||||
Messages from server to client (responses/events)
|
|
||||||
-------------------------------------------------
|
|
||||||
|
|
||||||
JSON objects. Key `type` determines type of message.
|
|
||||||
|
|
||||||
### init
|
|
||||||
Response to `init` command. Confirms initialization and chat join.
|
|
||||||
|
|
||||||
**Parameters:**
|
|
||||||
* `type` = `"init"`
|
|
||||||
* ***[TODO]***
|
|
||||||
|
|
||||||
**Example:**
|
|
||||||
|
|
||||||
{
|
|
||||||
"type": "init",
|
|
||||||
TODO ???
|
|
||||||
}
|
|
||||||
|
|
@ -1,59 +1,33 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
# Example code from:
|
||||||
|
# https://websockets.readthedocs.io/en/stable/intro.html
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import json
|
|
||||||
import websockets
|
import websockets
|
||||||
|
|
||||||
|
|
||||||
def log_message_error(error, message_text):
|
|
||||||
print(f"[E] {error}")
|
|
||||||
print(f" Message: {message_text}")
|
|
||||||
|
|
||||||
|
|
||||||
async def parse_client_message(websocket, message_text):
|
async def parse_client_message(websocket, message_text):
|
||||||
"""Parse a message (JSON object) from a client."""
|
"""Parse a message (JSON object) from a client."""
|
||||||
|
|
||||||
try:
|
# TODO parse JSON
|
||||||
# Parse JSON
|
response = f"Hello {message_text}!"
|
||||||
message = json.loads(message_text)
|
|
||||||
|
|
||||||
# Handle message types
|
|
||||||
if message['action'] == 'init':
|
|
||||||
await handle_client_init(websocket, message)
|
|
||||||
else:
|
|
||||||
log_message_error(f"Unknown action '{message['action']}'", message_text)
|
|
||||||
except json.decoder.JSONDecodeError as e:
|
|
||||||
log_message_error(f"JSON decode error: {e}", message_text)
|
|
||||||
except KeyError as e:
|
|
||||||
log_message_error(f"Missing key {e} in JSON message", message_text)
|
|
||||||
|
|
||||||
|
|
||||||
async def handle_client_init(websocket, message):
|
|
||||||
"""Handle client 'init' message."""
|
|
||||||
|
|
||||||
print(f"< init: chat_id='{message['chat_id']}', nickname='{message['nickname']}'")
|
|
||||||
|
|
||||||
# Send response to client
|
|
||||||
response = json.dumps({
|
|
||||||
'type': 'init'
|
|
||||||
})
|
|
||||||
print(f"> {response}")
|
|
||||||
await websocket.send(response)
|
await websocket.send(response)
|
||||||
|
print(f"> {response}")
|
||||||
|
|
||||||
|
|
||||||
async def client_handler(websocket, path):
|
async def client_handler(websocket, path):
|
||||||
"""Handle client connection."""
|
"""Handle client connection."""
|
||||||
|
|
||||||
print(f"++ New client {websocket.remote_address}")
|
print(f"++ New client")
|
||||||
try:
|
try:
|
||||||
# Read and parse messages until connection is closed
|
# Read and parse messages until connection is closed
|
||||||
async for message_text in websocket:
|
async for message_text in websocket:
|
||||||
|
print(f"< {message_text}")
|
||||||
await parse_client_message(websocket, message_text)
|
await parse_client_message(websocket, message_text)
|
||||||
except websockets.exceptions.ConnectionClosed:
|
|
||||||
# Ignore ConnectionClosed exceptions because we handle this in finally
|
|
||||||
pass
|
|
||||||
finally:
|
finally:
|
||||||
print(f"-- Client connection closed {websocket.remote_address}")
|
print(f"-- Client connection closed")
|
||||||
|
|
||||||
# Create WebSocket listener
|
# Create WebSocket listener
|
||||||
start_server = websockets.serve(client_handler, '0.0.0.0', 32715)
|
start_server = websockets.serve(client_handler, '0.0.0.0', 32715)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue