Преглед на файлове

Streamline messaging

master
Roderic Day преди 5 години
родител
ревизия
01967df09c
променени са 2 файла, в които са добавени 56 реда и са изтрити 52 реда
  1. +14
    -12
      pico.py
  2. +42
    -40
      test.py

+ 14
- 12
pico.py Целия файл

@@ -60,7 +60,7 @@ async def recv_json(websocket):
return {}


async def core(ws, path, server_name):
async def handle(ws, path, server_name):
room = rooms[path]
usernames = room.keys()
sockets = room.values()
@@ -69,7 +69,8 @@ async def core(ws, path, server_name):
while True:
data = await recv_json(ws)
ts = datetime.datetime.now().isoformat() + 'Z'
emit = partial(send_json_many, kind=data['kind'], value=data.get('value'), ts=ts)

emit = partial(send_json_many, kind=data['kind'], ts=ts)
broadcast = partial(emit, targets=sockets)
reply = partial(emit, targets=[ws])
error = partial(reply, kind='error')
@@ -86,12 +87,10 @@ async def core(ws, path, server_name):
await error(value='Username taken')
break

others = list(sockets)
room[username] = ws
online = list(usernames)
await reply(online=online)
await broadcast(kind='post', value=f'{username} joined', online=online, targets=others)
await reply(kind='post', value=f'Welcome to {path}')
await reply(kind='state', username=username)
await broadcast(kind='state', online=online)

elif username not in room:
await error(value='Login required')
@@ -100,20 +99,23 @@ async def core(ws, path, server_name):
elif data['kind'] == 'logout':
del room[username]
online = list(usernames)
await broadcast(kind='post', value=f'{username} left', online=online)
await broadcast(kind='state', online=online)
break

else:
value = data.get('value')
if 'target' in data:
targets = {v for k, v in room.items() if k in {username, data['target']}}
await broadcast(source=username, targets=targets)
recipients = {username, data['target']}
targets = {v for k, v in room.items() if k in recipients}
await broadcast(source=username, value=value, targets=targets)
else:
await broadcast(source=username)
await broadcast(source=username, value=value)


async def start_server(host, port, server_name):
bound_core = partial(core, server_name=server_name)
return await websockets.serve(bound_core, host, port, create_protocol=PicoProtocol)
bound_handle = partial(handle, server_name=server_name)
bound_serve = partial(websockets.serve, create_protocol=PicoProtocol)
return await bound_serve(bound_handle, host, port)


if __name__ == '__main__':

+ 42
- 40
test.py Целия файл

@@ -29,9 +29,8 @@ async def _make_client(path, timeout, script):
if kind == 'recv':
A, B = message, await recv_json(websocket)
B.pop('ts')
if B['kind'] == 'login':
username = B['value']
state.update(message)
if B['kind'] == 'state':
state.update(B)
if A != B:
error = True
print('-', A)
@@ -41,7 +40,7 @@ async def _make_client(path, timeout, script):
await send_json(websocket, **message)

while 'online' in state:
if state['online'][0] == username:
if state['online'][0] == state['username']:
break
message = await recv_json(websocket)
message.pop('ts')
@@ -72,8 +71,8 @@ async def _test(*clients):
def test_happy_path():
client = _make_client('ws://localhost:8642/A', 0.1, Script()
+ {'kind': 'login', 'value': 'TestUser'}
- {'kind': 'login', 'value': 'TestUser', 'online': ['TestUser']}
- {'kind': 'post', 'value': 'Welcome to /A'}
- {'kind': 'state', 'username': 'TestUser'}
- {'kind': 'state', 'online': ['TestUser']}
+ {'kind': 'post', 'value': 'Hello World!'}
- {'kind': 'post', 'value': 'Hello World!', 'source': 'TestUser'}
)
@@ -83,9 +82,9 @@ def test_happy_path():
def test_name_taken():
client1 = _make_client('ws://localhost:8642/', 0.10, Script()
+ {'kind': 'login', 'value': 'A'}
- {'kind': 'login', 'value': 'A', 'online': ['A']}
- {'kind': 'post', 'value': 'Welcome to /'}
- {'kind': 'post', 'value': 'B joined', 'online': ['A', 'B']}
- {'kind': 'state', 'username': 'A'}
- {'kind': 'state', 'online': ['A']}
- {'kind': 'state', 'online': ['A', 'B']}
)
client2 = _make_client('ws://localhost:8642/', 0.11, Script()
+ {'kind': 'login', 'value': 'A'}
@@ -93,9 +92,9 @@ def test_name_taken():
)
client3 = _make_client('ws://localhost:8642/', 0.12, Script()
+ {'kind': 'login', 'value': 'B'}
- {'kind': 'login', 'value': 'B', 'online': ['A', 'B']}
- {'kind': 'post', 'value': 'Welcome to /'}
- {'kind': 'post', 'value': 'A left', 'online': ['B']}
- {'kind': 'state', 'username': 'B'}
- {'kind': 'state', 'online': ['A', 'B']}
- {'kind': 'state', 'online': ['B']}
)
return _test(client1, client2, client3)

@@ -103,21 +102,21 @@ def test_name_taken():
def test_interaction():
client1 = _make_client('ws://localhost:8642/', 0.10, Script()
+ {'kind': 'login', 'value': 'Alice'}
- {'kind': 'login', 'value': 'Alice', 'online': ['Alice']}
- {'kind': 'post', 'value': 'Welcome to /'}
- {'kind': 'post', 'value': 'Bob joined', 'online': ['Alice', 'Bob']}
- {'kind': 'state', 'username': 'Alice'}
- {'kind': 'state', 'online': ['Alice']}
- {'kind': 'state', 'online': ['Alice', 'Bob']}
+ {'kind': 'post', 'value': 'Hey Bob!'}
- {'kind': 'post', 'value': 'Hey Bob!', 'source': 'Alice'}
- {'kind': 'post', 'value': 'Howdy!', 'source': 'Bob'}
)
client2 = _make_client('ws://localhost:8642/', 0.11, Script()
+ {'kind': 'login', 'value': 'Bob'}
- {'kind': 'login', 'value': 'Bob', 'online': ['Alice', 'Bob']}
- {'kind': 'post', 'value': 'Welcome to /'}
- {'kind': 'state', 'username': 'Bob'}
- {'kind': 'state', 'online': ['Alice', 'Bob']}
- {'kind': 'post', 'value': 'Hey Bob!', 'source': 'Alice'}
+ {'kind': 'post', 'value': 'Howdy!'}
- {'kind': 'post', 'value': 'Howdy!', 'source': 'Bob'}
- {'kind': 'post', 'value': 'Alice left', 'online': ['Bob']}
- {'kind': 'state', 'online': ['Bob']}
)
return _test(client1, client2)

@@ -125,15 +124,15 @@ def test_interaction():
def test_rooms():
client1 = _make_client('ws://localhost:8642/A', 0.10, Script()
+ {'kind': 'login', 'value': 'Dandy'}
- {'kind': 'login', 'value': 'Dandy', 'online': ['Dandy']}
- {'kind': 'post', 'value': 'Welcome to /A'}
- {'kind': 'state', 'username': 'Dandy'}
- {'kind': 'state', 'online': ['Dandy']}
+ {'kind': 'post', 'value': 'Hi', 'source': 'Dandy'}
- {'kind': 'post', 'value': 'Hi', 'source': 'Dandy'}
)
client2 = _make_client('ws://localhost:8642/B', 0.10, Script()
+ {'kind': 'login', 'value': 'Dandy'}
- {'kind': 'login', 'value': 'Dandy', 'online': ['Dandy']}
- {'kind': 'post', 'value': 'Welcome to /B'}
- {'kind': 'state', 'username': 'Dandy'}
- {'kind': 'state', 'online': ['Dandy']}
+ {'kind': 'post', 'value': 'Hi', 'source': 'Dandy'}
- {'kind': 'post', 'value': 'Hi', 'source': 'Dandy'}
)
@@ -143,30 +142,33 @@ def test_rooms():
def test_private_message():
client1 = _make_client('ws://localhost:8642/', 0.10, Script()
+ {'kind': 'login', 'value': 'Norman'}
- {'kind': 'login', 'value': 'Norman', 'online': ['Norman']}
- {'kind': 'post', 'value': 'Welcome to /'}
- {'kind': 'post', 'value': 'Ray joined', 'online': ['Norman', 'Ray']}
- {'kind': 'post', 'value': 'Emma joined', 'online': ['Norman', 'Ray', 'Emma']}
+ {'kind': 'post', 'value': 'なに?', 'target': 'Emma'}
- {'kind': 'post', 'value': 'なに?', 'source': 'Norman'}
- {'kind': 'state', 'username': 'Norman'}
- {'kind': 'state', 'online': ['Norman']}
- {'kind': 'state', 'online': ['Norman', 'Ray']}
- {'kind': 'state', 'online': ['Norman', 'Ray', 'Emma']}
+ {'kind': 'post', 'value': '1', 'target': 'Ray'}
- {'kind': 'post', 'value': '1', 'source': 'Norman'}
- {'kind': 'post', 'value': '3', 'source': 'Emma'}
)
client2 = _make_client('ws://localhost:8642/', 0.11, Script()
+ {'kind': 'login', 'value': 'Ray'}
- {'kind': 'login', 'value': 'Ray', 'online': ['Norman', 'Ray']}
- {'kind': 'post', 'value': 'Welcome to /'}
- {'kind': 'post', 'value': 'Emma joined', 'online': ['Norman', 'Ray', 'Emma']}
- {'kind': 'post', 'value': '秘密!', 'source': 'Emma'}
- {'kind': 'post', 'value': 'Norman left', 'online': ['Ray', 'Emma']}
- {'kind': 'state', 'username': 'Ray'}
- {'kind': 'state', 'online': ['Norman', 'Ray']}
- {'kind': 'state', 'online': ['Norman', 'Ray', 'Emma']}
- {'kind': 'post', 'value': '1', 'source': 'Norman'}
+ {'kind': 'post', 'value': '2', 'target': 'Emma'}
- {'kind': 'post', 'value': '2', 'source': 'Ray'}
- {'kind': 'state', 'online': ['Ray', 'Emma']}
)
client3 = _make_client('ws://localhost:8642/', 0.12, Script()
+ {'kind': 'login', 'value': 'Emma'}
- {'kind': 'login', 'value': 'Emma', 'online': ['Norman', 'Ray', 'Emma']}
- {'kind': 'post', 'value': 'Welcome to /'}
- {'kind': 'post', 'value': 'なに?', 'source': 'Norman'}
+ {'kind': 'post', 'value': '秘密!', 'target': 'Ray'}
- {'kind': 'post', 'value': '秘密!', 'source': 'Emma'}
- {'kind': 'post', 'value': 'Norman left', 'online': ['Ray', 'Emma']}
- {'kind': 'post', 'value': 'Ray left', 'online': ['Emma']}
- {'kind': 'state', 'username': 'Emma'}
- {'kind': 'state', 'online': ['Norman', 'Ray', 'Emma']}
- {'kind': 'post', 'value': '2', 'source': 'Ray'}
+ {'kind': 'post', 'value': '3', 'target': 'Norman'}
- {'kind': 'post', 'value': '3', 'source': 'Emma'}
- {'kind': 'state', 'online': ['Ray', 'Emma']}
- {'kind': 'state', 'online': ['Emma']}
)
return _test(client1, client2, client3)


Loading…
Отказ
Запис