Как позволить клиенту обнаруживать обновленные данные с сервера? - PullRequest
0 голосов
/ 07 января 2019

В настоящее время я создаю простой чат-клиент-сервер, но я борюсь с тем, что должен делать сервер, когда появляется новое сообщение.

Мое текущее решение - просто отправить обновленные данные клиенту, когда они обновят свои. На практике это будет означать, что клиент будет получать новые сообщения только тогда, когда он сам отправляет сообщение. Не очень полезно ...

Я также подумал о другом способе, который заключается в том, чтобы клиент запрашивал у сервера информацию каждые 3 или около того секунд, но это привело бы к засорению сервера большим количеством людей.

Моя третья идея - подключить сервер к клиентам при появлении нового сообщения, но для этого потребуется, чтобы сервер запомнил их IP-адрес и чтобы клиент тоже использовал сервер. (Звучит как P2P.)

Большая часть моего кода скопирована с этой части документации , поэтому вы можете проверить это тоже.


Вот мой текущий код на стороне клиента. (Примечание. Чтобы отправить «сообщение», вам нужно набрать asyncio.run(echo_client('username', 'message')). Это только Python 3.7+.)

import asyncio

async def echo_client(user, message):
    reader, writer = await asyncio.open_connection(
        '127.0.0.1', 41001)

    user = str(user)
    message = ''.join(message.split('\n'))
    print(f'Sending from {user}: {message}')
    writer.write((user + '\n').encode())
    writer.write((message + '\n').encode())
    await writer.drain()

    data = await reader.readline()
    data = data.decode().strip()
    if data == 'Connection closed':
        print('User disconnected')
    else:
        print('Users info')
        for i in range(int(data)):
            user = await reader.readline()
            data = await reader.readline()
            user = user.decode().strip()
            data = data.decode().strip()
            print(f'{user}: {data}')
        # end for

    print('Connection closed')
    writer.close()

Вот мой код на стороне сервера. Это просто передает информацию, хранящуюся на его стороне, и обновляет их при необходимости.

import asyncio

users = {}

async def handle_echo(reader, writer):
    global users

    user = await reader.readline()
    data = await reader.readline()
    addr = writer.get_extra_info('peername')

    user = user.decode().strip()
    data = data.decode().strip()

    if data == '':
        print(f'Recieved empty message from {addr!r}')
        print(f'Closing connection to {addr!r}')
        writer.write(b'Connection closed')
        writer.close()
        del users[user]
        return

    if data != 'update':
        users[user] = data

    print(f'Received {data} from {addr!r}')

    print(f'Send: {[(i, j) for i, j in users.items()]}')
    writer.write(f'{len(users)}\n'.encode())
    await writer.drain()
    for user, data in users.items():
        writer.write(f'{user}\n{data}\n'.encode())
        await writer.drain()
    # end for

    print('Closed the connection')
    writer.close()

async def main():
    server = await asyncio.start_server(
        handle_echo, '127.0.0.1', 41001
    )

    addr = server.sockets[0].getsockname()
    print(f'Serving on {addr}')

    async with server:
        await server.serve_forever()

asyncio.run(main())

Мой код работает нормально, но мне интересно найти лучшую альтернативу. Пожалуйста, объясните, как работает ваша реализация и как она может улучшить код.

(Я скоро пойду спать, так что увидимся завтра.)
(Не сразу конечно ^ v ^)

1 Ответ

0 голосов
/ 07 января 2019

Я бы использовал библиотеку сокетов, такую ​​как https://python -socketio.readthedocs.io / en / latest / на основе socket.io

Приведенные здесь примеры помогут вам начать работу.

...