pointsd now using tcp connections .. not tested

This commit is contained in:
Curt Hash 2010-02-09 16:27:46 -07:00
parent e8df83c83b
commit 09d5b1385c
1 changed files with 60 additions and 36 deletions

View File

@ -9,48 +9,72 @@ from . import config
house = config.get('global', 'house_team') house = config.get('global', 'house_team')
class MyHandler(asyncore.dispatcher): class PointsServer(asyncore.dispatcher):
''' Receive connections from client and passes them off to handler. '''
def __init__(self, port=6667): def __init__(self, port=6667):
asyncore.dispatcher.__init__(self) asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_DGRAM) self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.bind(('', port)) self.bind(('', port))
self.listen(5)
self.acked = set()
self.outq = []
def handle_accept(self):
''' Accept a connection from a client and pass it to the handler. '''
sock, addr = self.accept()
clientip = addr[0]
ClientHandler(sock, clientip)
class ClientHandler(asyncore.dispatcher):
''' Handles talking to clients. '''
def __init__(self, sock, clientip):
asyncore.dispatcher.__init__(self, sock=sock)
self.clientip = clientip
self.store = points.Storage(fix=True) self.store = points.Storage(fix=True)
self.acked = set() self.acked = set()
self.outq = [] self.outq = []
def writable(self): def writable(self):
''' If there is data in the queue, the socket is made writable. '''
return bool(self.outq) return bool(self.outq)
def handle_write(self): def handle_write(self):
dgram, peer = self.outq.pop(0) ''' Pop data from the queue and send it to the client. '''
self.socket.sendto(dgram, peer) resp = self.outq.pop(0)
self.send(resp)
# conversation over
self.close()
def handle_read(self): def handle_read(self):
''' Receive data from the client. '''
now = int(time.time()) now = int(time.time())
dgram, peer = self.socket.recvfrom(4096) data = self.recv(4096)
# decode their message
try: try:
id, when, cat, team, score = points.decode_request(dgram) id, when, cat, team, score = points.decode_request(data)
except ValueError as e: except ValueError as e:
return self.respond(peer, now, str(e)) return self.respond(now, str(e))
team = team or house team = team or house
# Replays can happen legitimately. # do points and send ACK
if not ((peer, id) in self.acked): if not ((self.clientip, id) in self.acked):
if not (now - 2 < when <= now): if not (now - 2 < when <= now):
return self.respond(peer, id, 'Your clock is off') return self.respond(id, 'Your clock is off')
self.store.add((when, cat, team, score)) self.store.add((when, cat, team, score))
self.acked.add((peer, id)) self.acked.add((self.clientip, id))
self.respond(peer, id, 'OK') self.respond(id, 'OK')
def respond(self, peer, id, txt): def respond(self, id, txt):
''' Queue responses to the client. '''
resp = points.encode_response(id, txt) resp = points.encode_response(id, txt)
self.outq.append((resp, peer)) self.outq.append(resp)
if __name__ == '__main__':
def start(): server = PointsServer()
return MyHandler()
if __name__ == "__main__":
h = start()
asyncore.loop() asyncore.loop()