From: <Blu...@us...> - 2009-11-28 23:27:02
|
Revision: 310 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=310&view=rev Author: BlueWolf_ Date: 2009-11-28 23:26:54 +0000 (Sat, 28 Nov 2009) Log Message: ----------- * uid is now a md5-hash, for privacy reasons * It will tell the client when the server is full * It will now kick a client properly after returning True in callback.connection_opened * Parser calls the function it needs * Changed the arguments in callback.connection_limit_exceeded * callback.connection_closed now has a reason! * Uses it own exceptions Modified Paths: -------------- trunk/server/core/callback.py trunk/server/core/server.py Modified: trunk/server/core/callback.py =================================================================== --- trunk/server/core/callback.py 2009-11-15 16:19:20 UTC (rev 309) +++ trunk/server/core/callback.py 2009-11-28 23:26:54 UTC (rev 310) @@ -41,9 +41,9 @@ client: The client class. Normally, you don't need this. host: - The IP adress for this user + The IP adress for this user. port: - The current port this connection uses. + The current port for this connection. This is placeholder. If you want to catch this event, @@ -51,7 +51,7 @@ """ pass - def connection_closed(self, uid): + def connection_closed(self, uid, reason): """ Called when a connection with a client is closed. This can be when they closed their connection themselves, or when we @@ -60,28 +60,37 @@ uid: The unique ID for this connection. This is usually 'ip:port'. + reason: + A string, representing the reason why it disconnected. + It currently has these options: + * "closed" - Client dropped the connection + unexpectedly + * "timeout" - Client timed out (No data for 45s) + * "manual" - Server (you) closed the connection + with .close() This is placeholder. If you want to catch this event, overwrite this in your own callback. """ - #TODO: Reason? pass - def connection_limit_exceeded(self, ip, current_connections, - max_connections): + def connection_limit_exceeded(self, current_connections, + max_connections, host, port): """ Called when a new client connects, but the maximum number of connections is exceeded. You can, however, still accept the connection by returning True in this function. - ip: - The IP-adress for this connection current_connections: Amount of current open connections max_connections: This is the same as in the config 'max_connections'. + host: + The IP adress for this user. + port: + The current port for this connection. This is placeholder. If you want to catch this event, Modified: trunk/server/core/server.py =================================================================== --- trunk/server/core/server.py 2009-11-15 16:19:20 UTC (rev 309) +++ trunk/server/core/server.py 2009-11-28 23:26:54 UTC (rev 310) @@ -15,7 +15,7 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -import simplejson, socket, threading, time +import simplejson, socket, threading, time, md5 from parser import Parser class Server(threading.Thread): @@ -93,7 +93,7 @@ #Isn't the server running already? if self.__sock: - raise Exception, "The server is already online!" + raise ConnectionError("The server is already online!") #Load our server socket self.__sock = socket.socket(socket.AF_INET, @@ -132,25 +132,34 @@ #We exceeded our connection limit, but maybe #this is a special occasion? Send callback! if not self.__call.connection_limit_exceeded( - addr[0], len(self.clients), - self.__config['max_connections']): + len(self.clients), + self.__config['max_connections'], + addr[0], addr[1]): #We're full, kick him out - #TODO: Tell him we're full? + #Tell him we're full + data = simplejson.dumps({ + "disconnect":{"reason":"full"} + }) + try: sock.send(data + chr(1)) + except: pass + sock.close() continue - uid = addr[0] + ':' + str(addr[1]) + # Chozo wanted the 8 so badly... + uid = md5.new(addr[0] + str(addr[1])).hexdigest()[:8] self.clients[uid] = Client(uid, sock, self.clients, self.__call, self.__parse) - self.clients[uid].start() if self.__call.connection_opened(uid, self.clients[uid], *addr): #User returned True -> drop user - time.sleep(0.1) #Let the `run` start self.clients[uid].close() + continue + self.clients[uid].start() + class Client(threading.Thread): @@ -186,12 +195,14 @@ while 1: try: data = self.__sock.recv(1024) + except socket.timeout: + if self.is_online: self.close("timeout") + return except: - #Ping timeout? - if self.is_online: self.close() + if self.is_online: self.close("closed") return if not data: - if self.is_online: self.close() + if self.is_online: self.close("closed") return buffer += data @@ -205,15 +216,17 @@ self.__parser(self.__uid, simplejson.loads(msg)) - def close(self): + def close(self, reason = "manual"): """ Closes the connection for this client and kills the socket. """ - + + try: self.__sock.shutdown(0); + except: pass self.__sock.close() self.is_online = False - self.__call.connection_closed(self.__uid) + self.__call.connection_closed(self.__uid, reason) del self.__clients[self.__uid] @@ -231,3 +244,5 @@ self.__sock.send(data + chr(1)) except: pass +class ConnectionError(Exception): + pass This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |