def onNetworkEvent(self, event): #print "onNetworkEvent" clientConn = event.clientConn message = event.message if clientConn != None and message.get('type') != 'ping': clientId = clientConn.id+1 if clientConn.id != None else "(no ID)" print 'client ', clientId, ': ', message t = message.get('type') if t == 'connect': if not self.gameController.running: # The game has not been started yet, so this is an initial # connection. if self.clients.count(None) == 0: # No open slots - close the connection. m = {'type': 'error', 'errorString': "There are no more available slots."} self.communicator.send(clientConn, m) # Make sure the error message is sent before disconnecting # FIXME: must be a better way. time.sleep(1) clientConn.close() else: # Create the ClientData and assign it to the first open # slot. clientConn.id = self.clients.index(None) client = ClientData(clientConn.id, None, 'Connected',\ Decimal('0.00'), clientConn) client.setRounding(self.rounding) self.clients[clientConn.id] = client self.listCtrl.updateClient(client) self.postMessage("Client " + str(clientConn.id+1)\ + " connected") # Send the login prompt self.communicator.send(clientConn, {'type': 'loginPrompt'}) # Set a timer that will run while waiting for the expected # login message. client.loginTimer = threading.Timer(loginTimeout, self.onLoginTimeout, [client]) client.loginTimer.start() else: # The game is in progress, so treat this as a reconnect. clientsDisconnected = False for c in self.clients: if c.connection == None: clientsDisconnected = True if not clientsDisconnected: # No disconnected clients - close the connection. m = {'type': 'error', 'errorString': 'There are no disconnected clients.'} self.communicator.send(clientConn, m) # Make sure the error message is sent before disconnecting # FIXME: must be a better way. time.sleep(1) clientConn.close() else: # Send the relogin prompt self.promptRelogin(clientConn) elif t == 'login': name = message.get('name') # Check for various error conditions. error = False if self.gameController.running: error = True errorString = "The game is already in progress. "\ + "Please click the Reconnect button." elif type(name) not in (str, unicode) or len(name) == 0: error = True errorString = "Please enter your name and try again." elif name in map( lambda(c): c.name if c != None else None, self.clients): error = True errorString = "That name is already taken. "\ + "Please enter a different one and try again." if error: # If there's an error with the login, send an error message to # the client and drop the client. m = {'type': 'error', 'errorString': errorString} self.communicator.send(clientConn, m) # Make sure the error message is sent before disconnecting # FIXME: must be a better way. time.sleep(1) clientConn.close() # If the game has not started yet, delete the client entirely. # (Otherwise, the connection has no id and is not associated # with a client - the subject probably clicked "connect" instead # of "reconnect".) if not self.gameController.running: client = self.clients[clientConn.id] client.loginTimer.cancel() client.loginTimer = None self.clients[client.id] = None else: # Everything's OK; accept the login. client = self.clients[clientConn.id] client.loginTimer.cancel() client.loginTimer = None client.name = message.get('name') self.listCtrl.updateClient(client) if self.allClientsLoggedIn(): print 'All clients logged in.' self.postMessage("All clients logged in.") self.startButton.Enable(True) if self.autostart: self.onStartClicked(None)
def onNetworkEvent(self, event): # print "onNetworkEvent" clientConn = event.clientConn message = event.message if clientConn != None and message.get("type") != "ping": clientId = clientConn.id + 1 if clientConn.id != None else "(no ID)" print "client ", clientId, ": ", message t = message.get("type") if t == "connect": if not self.gameController.running: # The game has not been started yet, so this is an initial # connection. if self.clients.count(None) == 0: # No open slots - close the connection. m = {"type": "error", "errorString": "There are no more available slots."} self.communicator.send(clientConn, m) # Make sure the error message is sent before disconnecting # FIXME: must be a better way. time.sleep(1) clientConn.close() else: # Create the ClientData and assign it to the first open # slot. clientConn.id = self.clients.index(None) client = ClientData(clientConn.id, None, "Connected", Decimal("0.00"), clientConn) client.setRounding(self.rounding) self.clients[clientConn.id] = client self.listCtrl.updateClient(client) self.postMessage("Client " + str(clientConn.id + 1) + " connected") # Send the login prompt self.communicator.send(clientConn, {"type": "loginPrompt"}) # Set a timer that will run while waiting for the expected # login message. client.loginTimer = threading.Timer(loginTimeout, self.onLoginTimeout, [client]) client.loginTimer.start() else: # The game is in progress, so treat this as a reconnect. clientsDisconnected = False for c in self.clients: if c.connection == None: clientsDisconnected = True if not clientsDisconnected: # No disconnected clients - close the connection. m = {"type": "error", "errorString": "There are no disconnected clients."} self.communicator.send(clientConn, m) # Make sure the error message is sent before disconnecting # FIXME: must be a better way. time.sleep(1) clientConn.close() else: # Send the relogin prompt self.promptRelogin(clientConn) elif t == "login": name = message.get("name") # Check for various error conditions. error = False if self.gameController.running: error = True errorString = "The game is already in progress. " + "Please click the Reconnect button." elif type(name) not in (str, unicode) or len(name) == 0: error = True errorString = "Please enter your name and try again." elif name in map(lambda (c): c.name if c != None else None, self.clients): error = True errorString = "That name is already taken. " + "Please enter a different one and try again." if error: # If there's an error with the login, send an error message to # the client and drop the client. m = {"type": "error", "errorString": errorString} self.communicator.send(clientConn, m) # Make sure the error message is sent before disconnecting # FIXME: must be a better way. time.sleep(1) clientConn.close() # If the game has not started yet, delete the client entirely. # (Otherwise, the connection has no id and is not associated # with a client - the subject probably clicked "connect" instead # of "reconnect".) if not self.gameController.running: client = self.clients[clientConn.id] client.loginTimer.cancel() client.loginTimer = None self.clients[client.id] = None else: # Everything's OK; accept the login. client = self.clients[clientConn.id] client.loginTimer.cancel() client.loginTimer = None client.name = message.get("name") self.listCtrl.updateClient(client) if self.allClientsLoggedIn(): print "All clients logged in." self.postMessage("All clients logged in.") self.startButton.Enable(True) if self.autostart: self.onStartClicked(None)
def onNetworkEvent(self, event): #print "onNetworkEvent" clientConn = event.clientConn message = event.message if clientConn != None and message['type'] != 'ping': print 'client ', clientConn.id, ': ', message #if clientConn != None: # self.postMessage("Received message from client " + # str(clientConn.id) + ": " + str(message)) if message['type'] == 'connect': self.postMessage("Client " + str(clientConn.id) + " connected") client = ClientData(clientConn.id, '', 'Connected', [], clientConn, self.exchangeRates) self.clients[clientConn.id] = client self.listCtrl.updateClient(client) elif message['type'] == 'all connected': self.postMessage("All clients connected.") # But not necessarily logged in... elif message['type'] == 'login': # Ignore login message if all clients already logged in # (it's probably from a disconnected client that clicked 'Log In' # by mistake instead of Reconnect) if self.clientsLoggedIn < len(self.clients): client = self.clients[clientConn.id] client.name = message['name'] self.listCtrl.updateClient(client) self.clientsLoggedIn += 1 if self.clientsLoggedIn == len(self.clients): print 'All clients logged in.' self.postMessage("All clients logged in.") self.startButton.Enable(True) if self.autostart: self.onStartClicked(None) elif message['type'] == 'ready': # Message from client that GUI has been created and is ready for the # game to begin (or resume, in the case of a reconnected client) if not self.gameController.running: # This is an initial ready message print 'initial ready message' self.gameController.clientReady(clientConn) else: # This is a ready message from a reconnecting client. # If there are no more clients who are still disconnected, # enable the unpause button. clientsStillDisconnected = False for c in self.clients: if c.status == 'Disconnected': clientsStillDisconnected = True break if not clientsStillDisconnected: self.pauseButton.Enable() elif message['type'] == 'chat': if self.chatEnabled: self.forwardChatMessage(clientConn, message) # Append to chat history for chat output file client = self.clients[clientConn.id] if client.group == None: groupID = '' else: groupID = str(client.group.id) if self.params['matches'][self.matchNum]['practice']: practice = 1 else: practice = 0 row = [self.sessionID, self.experimentID, self.matchNum+1,\ practice, self.roundNum+1, clientConn.id, groupID, message['message']] self.chatHistory.append(row) elif message['type'] == 'disconnect': # Pause and don't allow unpausing until client has reconnected self.pauseButton.Enable(False) self.communicator.pause() self.pauseClients() self.pauseButton.SetLabel("Unpause") client = self.clients[clientConn.id] client.status = 'Disconnected' self.listCtrl.updateClient(client) self.communicator.reconnectToClients(1) errorstring = "A client has disconnected." dlg = wx.MessageDialog(self, errorstring, 'Client Disconnected', wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() elif message['type'] == 'reconnect': self.promptRelogin(clientConn) elif message['type'] == 'relogin': # Reconnecting client's response to 'whoareyou'. # Check for valid selection id = message['id'] if self.clients[id].status == 'Disconnected': # OK, reconnect client with selected ID clientConn.id = id client = self.clients[id] client.connection = clientConn client.status = 'Connected' self.listCtrl.updateClient(client) self.gameController.reinitClient(client) else: # Selected client is not disconnected, so as 'whoareyou' again. self.promptRelogin(clientConn)