File size: 2,513 Bytes
9c72a28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import asyncio, json, time, sys

try:
    import websockets
except ImportError:
    print("pip install websockets")
    sys.exit(1)

messages = []
clients = set()

async def server_handler(ws):
    clients.add(ws)
    try:
        for m in messages:
            await ws.send(json.dumps(m))
        async for raw in ws:
            data = json.loads(raw)
            data['server_time'] = int(time.time() * 1000)
            messages.append(data)
            websockets.broadcast(clients, json.dumps(data))
    finally:
        clients.discard(ws)

async def run_server(host='127.0.0.1', port=7860):
    async with websockets.serve(server_handler, host, port):
        print(f"server on ws://{host}:{port}")
        await asyncio.Future()

async def client(uri, username):
    async with websockets.connect(uri) as ws:
        pending, next_id = {}, 0

        async def reader():
            async for raw in ws:
                data = json.loads(raw)
                now = int(time.time() * 1000)
                user, msg = data['user'], data['msg']
                line = f"{user}: {msg}"
                if user == username and data.get('id') in pending:
                    rtt = now - pending.pop(data['id'])
                    line += f" (rtt: {rtt}ms)"
                elif data.get('server_time'):
                    sp = now - data['server_time']
                    line += f" (sping: {sp}ms)"
                print(f"\r{'':<80}\r{line}\n{username}> ", end='', flush=True)

        async def writer():
            nonlocal next_id
            loop = asyncio.get_running_loop()
            print(f"{username}> ", end='', flush=True)
            while True:
                line = await loop.run_in_executor(None, input)
                if not line:
                    print(f"{username}> ", end='', flush=True)
                    continue
                nid = next_id
                next_id += 1
                pending[nid] = int(time.time() * 1000)
                await ws.send(json.dumps({"user": username, "msg": line, "id": nid}))

        await asyncio.gather(reader(), writer())

if __name__ == '__main__':
    if len(sys.argv) > 1 and sys.argv[1] == 'server':
        port = int(sys.argv[2]) if len(sys.argv) > 2 else 7860
        asyncio.run(run_server(port=port))
    else:
        uri = sys.argv[1] if len(sys.argv) > 1 else 'wss://vericudebuget-online-group.hf.space/ws'
        name = sys.argv[2] if len(sys.argv) > 2 else input("Username: ")
        asyncio.run(client(uri, name))