Commit 6d851d68 authored by Ralf's avatar Ralf
Browse files

add a player class for buffer splitting etc.

parent 27fe4cac
......@@ -2,35 +2,31 @@
import selectors
import socket
import atexit
from player import Player
sel = selectors.DefaultSelector()
players = []
def accept(sock, mask):
conn, addr = sock.accept() # Should be ready
print('accepted', conn, 'from', addr)
conn.setblocking(False)
sel.register(conn, selectors.EVENT_READ, read)
def read(conn, mask):
data = conn.recv(1000) # Should be ready
if data:
print('echoing', repr(data), 'to', conn)
conn.send(data) # Hope it won't block
conn.send('Danke für Ihre Nachricht!'.encode("utf-8"))
else:
print('closing', conn)
sel.unregister(conn)
conn.close()
player = Player(sel, conn)
players.append(player)
sel.register(conn, selectors.EVENT_READ, player.read)
sock = socket.socket()
sock.bind(('0.0.0.0', 1234))
sock.listen(100)
sock.setblocking(False)
sel.register(sock, selectors.EVENT_READ, accept)
while True:
events = sel.select()
for key, mask in events:
callback = key.data
callback(key.fileobj, mask)
try:
while True:
events = sel.select()
for key, mask in events:
callback = key.data
callback(key.fileobj, mask)
finally:
sock.close()
for player in players:
player.close()
from util import *
class Player:
def __init__(self, sel, conn):
self.buffer = b""
self.sel = sel
self.conn = conn
# low-level functions
def send(self, data):
assert type(data) == str
send_async(self.conn, (data+"\n").encode('utf-8'))
def close(self):
self.conn.close()
def read(self, conn, mask):
assert self.conn == conn, "The player's connection changed?"
data = conn.recv(1024) # Should be ready
if data:
self.buffer += data
pos = self.buffer.find(b'\n')
if pos >= 0:
cmd = self.buffer[:pos]
self.buffer = self.buffer[pos+1:]
self.readCmd(cmd.decode('utf-8'))
else:
log_stdout('closing', conn)
self.sel.unregister(conn)
conn.close()
# high(er)-level functions
def readCmd(self, cmd):
self.send("Selber "+cmd)
import threading, traceback, sys
# run a Python command asynchronously
def fire_and_forget(f):
def _fire_and_forget():
try:
f()
except Exception:
log_stderr("fire_and_forget: Got exception out of callback:\n%s" % traceback.format_exc())
t = threading.Thread(target=_fire_and_forget)
t.start()
def send_async(conn, data):
fire_and_forget(lambda: conn.send(data))
def log_stdout(*args):
print(*args, file=sys.stdout, flush=True)
def log_stderr(*args):
print(*args, file=sys.stdout, flush=True)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment