Replace Unix-style select logic with asynchronous IO for better Windows support

This commit is contained in:
Kayomn 2021-10-05 00:55:17 +01:00
parent b328d07269
commit 4a05ef6543
1 changed files with 26 additions and 22 deletions

View File

@ -3,10 +3,10 @@ __version__ = "0.0.1"
__status__ = "Development" __status__ = "Development"
if (__name__ == "__main__"): if (__name__ == "__main__"):
import asyncio
import chattle import chattle
import config import config
import socket import socket
import select
import sys import sys
username = input("username: ") username = input("username: ")
@ -15,34 +15,38 @@ if (__name__ == "__main__"):
print("Starting connection to", address) print("Starting connection to", address)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server_socket: with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server_socket:
server_socket.setblocking(False)
server_socket.connect_ex(address) server_socket.connect_ex(address)
print(server_socket.recv(config.message_max).decode("utf-8"))
# Input may be written by the user or received from the server. Both cases have to be handled. async def listen_server():
inputs = [sys.stdin, server_socket] response_data = server_socket.recv(config.message_max)
while True: while response_data:
# Listen for input. print(response_data.decode("utf-8"))
readable_io, _, _ = select.select(inputs, [], [])
for io in readable_io: response_data = server_socket.recv(config.message_max)
if (io == server_socket):
response_data = io.recv(config.message_max)
if not response_data: # Listening for server responses has to be done on a separate unit of computation, such as an asynchronous
exit(0) # operation, so as not to block the console from working.
asyncio.get_event_loop().create_task(listen_server())
print(response_data.decode("utf-8")) is_running = True
elif (io == sys.stdin): while is_running:
# Messages produced by this client are written to the terminal locally, rather than sending it to line = sys.stdin.readline().strip()
# server to then receive it back.
line = sys.stdin.readline()
if not line.startswith("/"): if line:
sys.stdout.write("<You> ") # Messages produced by this client are written to the terminal locally, rather than sending it to
sys.stdout.write(line) # server to then receive it back.
sys.stdout.flush() if not line.startswith("/"):
sys.stdout.write("<You> ")
sys.stdout.write(line)
sys.stdout.write("\n")
sys.stdout.flush()
server_socket.send(chattle.encode_message(username, line)) server_socket.send(chattle.encode_message(username, line))
if (line.lower() == "/quit"):
# Handle exiting on the client-side.
is_running = False