/
denver2990
/
async_python_chat
Обзор
Документация
Войти
/
denver2990
/
async_python_chat
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
client.py
87 строк
3 KB
Eugene Popov
добавлена обработка команд /nick, /list, /pm на сервере
28 ноя 2025, 00:19
28 ноя 2025, 00:19
1f8316b
Код
Авторство
О чём код?
import asyncio HOST = "127.0.0.1" PORT = 8888 async def read_from_server(reader: asyncio.StreamReader) -> None: """Корутин для приёма сообщений от сервера и вывода их на экран.""" try: while True: data = await reader.readline() if not data: print("[CLIENT] Соединение закрыто сервером") break # Печатаем уже готовую строку от сервера print(data.decode("utf-8").rstrip("\n"), end = "\n> ") except asyncio.CancelledError: # Задачу могли отменить при завершении клиента pass async def send_user_input(writer: asyncio.StreamWriter) -> None: """Корутин для чтения ввода пользователя из консоли и отправки на сервер.""" loop = asyncio.get_running_loop() # ===== ЭТАП 3: можно запросить ник у пользователя и отправить его на сервер ===== # nick = await loop.run_in_executor(None, input, "Введите ваш ник: ") # writer.write((nick + "\n").encode("utf-8")) # await writer.drain() try: while True: # Чтение из консоли нельзя делать напрямую (input блокирует event loop), # поэтому используем run_in_executor. line = await loop.run_in_executor(None, input, "> ") if not line: continue # Локальная команда выхода if line.strip() == "/quit": print("[CLIENT] Завершение работы по команде /quit") break # ЭТАП 1: отправляем строку серверу (эха-ответ) # ЭТАП 2 и 3: сервер уже рассылает сообщение всем клиентам writer.write((line + "\n").encode("utf-8")) await writer.drain() except asyncio.CancelledError: # Задачу могли отменить при завершении клиента pass async def main() -> None: print(f"[CLIENT] Подключение к серверу {HOST}:{PORT} ...") reader, writer = await asyncio.open_connection(HOST, PORT) print("[CLIENT] Подключено. Введите сообщения (или /quit для выхода).") # Создаём две задачи: приём и отправка task_recv = asyncio.create_task(read_from_server(reader)) task_send = asyncio.create_task(send_user_input(writer)) # Ждём завершения любой из задач done, pending = await asyncio.wait( {task_recv, task_send}, return_when=asyncio.FIRST_COMPLETED, ) # Отменяем оставшиеся задачи (если есть) for task in pending: task.cancel() # Закрываем соединение writer.close() try: await writer.wait_closed() except Exception: pass print("[CLIENT] Соединение закрыто, клиент завершён.") if __name__ == "__main__": try: asyncio.run(main()) except KeyboardInterrupt: print("\n[CLIENT] Остановка по Ctrl+C")