Exemplo n.º 1
0
class SocketClient(General):
    def __init__(self, host="localhost", port=8080, _buffer=1024):
        self.host = host
        self.port = port
        self._buffer = _buffer
        self.socket = socket.socket()
        self.receiving = False
        # This variable determines whether the client socket is receiving data or not
        self.connected = False
        # This variable determines wheether the client socket is connected or not

        # Callback definitions
        self.onConnectCallback = self.emptyFunction
        self.onReceiveCallback = self.emptyFunction
        self.onSendCallback = self.emptyFunction
        self.onDisconnectCallback = self.emptyFunction

    def emptyFunction(self, *args, **kwargs):
        pass

    def connect(self, callback, _async=False):
        if not self.connected:
            if _async:
                self.setImmediate(self.onBeforeConnectCallback,
                                  {"callback": callback})
            else:
                self.onBeforeConnectCallback(callback=callback)

    def onBeforeConnectCallback(self, **kwargs):
        try:
            self.socket.connect((self.host, self.port))
            self.connected = True
            self.Clock = Clock()

            kwargs["callback"](True, None)
        except Exception as e:
            kwargs["callback"](False, e)

    def startRecvFrom(self, client, _async=False):
        self.startReceivingFromServer(client, _async)

    def startReceivingFromServer(self, _async=False):
        if _async:

            def method():
                self.receive()

            self.setInterval(method, 1)
        else:
            while True:
                self.receive()

    def recv(self, _async=False):
        self.receive(_async)

    def receive(self, _async=False):
        if self.connected:
            if _async:
                self.setImmediate(self.processReceivedData)
            else:
                self.processReceivedData()

    def processReceivedData(self):
        try:
            data = self.socket.recv(self._buffer)
            # Receive data from server
            data = data.decode("utf-8")
            # Decode the received data
            if not data == "":
                data = self.jsonize(data)
                # Convert the data to json format (i.e: dict)

                self.onReceiveCallback(data, None)
        except Exception as e:
            self.onReceiveCallback(False, e)

    def send(self, data, _async=False):
        if self.connected:
            if _async:
                self.setImmediate(self.onBeforeSendCallback, {"data": data})
            else:
                self.onBeforeSendCallback(data=data)

    def onBeforeSendCallback(self, **kwargs):
        try:
            data = {
                "date": self.Clock.date(),
                "time": self.Clock.time(),
                "data": kwargs["data"]
            }

            self.socket.send(self.unjsonize(data).encode("utf-8"))

            self.onSendCallback(data, None)
        except Exception as e:
            self.onSendCallback(False, e)

    def onReceive(self, callback):
        self.onReceiveCallback = callback

    def onSend(self, callback):
        self.onSendCallback = callback

    def onDisconnect(self, callback):
        self.onDisconnectCallback = callback

    def disconnect(self):
        if self.connected:
            self.socket.close()
Exemplo n.º 2
0
class SocketServer (General):
	def __init__ (self, host = "localhost", port = 8080, _buffer = 1024, maxConnections = 10, displayMsg = False, allowMultipleConnections = True):
		self.host = host;
		self.port = port;
		self._buffer = _buffer;
		self.maxConnections = maxConnections;
		self.waiting = False; # This variable shows whether the server is waiting for new connections
		self.shouldWait = True; # This variable determines whether the server should accept new incoming connections or not
		self.closing = False;
		self.closed = False;
		self.connections = []; # This list contains all successful connections to the server
		self.allowMultipleConnections = allowMultipleConnections; # The value of this variable determines whether multiple connections from the same IP address will be allowed

		if not displayMsg:
			self.displayMessageCallback = self.displayMsg;
		else:
			self.displayMessageCallback = displayMsg;

		# Callback definitions
		self.onStartCallback = self.emptyFunction;
		self.onConnectCallback = self.emptyFunction;
		self.onReceiveCallback = self.emptyFunction;
		self.onSendCallback = self.emptyFunction;
		self.onDisconnectCallback = self.emptyFunction;


	def displayMsg (self, code = 0):
		print(code);


	def emptyFunction (self, *args, **kwargs):
		pass;


	def start (self):
		try:
			self.server = socket.socket();
			self.server.bind((self.host, self.port));
			self.server.listen(self.maxConnections);
			self.Clock = Clock();

			self.onStartCallback(True, None);
		except Exception as e:
			self.onStartCallback(False, e);


	def waitForConnections (self, _async = False):
		def method (**kwargs):
			kwargs["self"].waitForConnection(kwargs["_async"]);

		self.setInterval(method, 1, {"self": self, "_async": _async});


	def waitForConnection (self, _async = False):
		if self.shouldWait:
			if not self.waiting:
				self.waiting = True;

				if _async:
					self.setImmediate(self.onBeforeConnectCallback);
				else:
					self.onBeforeConnectCallback();				


	def onBeforeConnectCallback (self):
		try:
			(conn, addr) = self.server.accept();

			if not self.shouldWait:
				return False;

			if not self.allowMultipleConnections:
				for client in self.connections:
					if client["ip"] == addr[0]:
						pass; # <- Code to disconnect the client goes here

			client = {
				"index": len(self.connections),
				"conn": conn,
				"ip": addr[0],
				"port": addr[1],
				"addr": addr,
				"isBlocked": False,
				"isReceiving": False,
				"isSending": False,
				"isConnected": True,
				"date": self.Clock.date(),
				"time": self.Clock.time()
			}

			self.connections.append(client);

			self.onConnectCallback(client, None); # Trigger callback
		except Exception as e:
			self.onConnectCallback(False, e); # Trigger callback


		self.waiting = False;


	def recv (self, client, _async = False):
		self.receive(client, _async);


	def receive (self, client, _async = False):
		if self.isClient(client):

			client = self.refreshClientData(client);

			if not client["isSending"]:
				self.setClientData(client, {"isSending": True});

				client = self.refreshClientData(client);

				if _async:
					self.setImmediate(self.onBeforeReceiveCallback, {"client": client});
				else:
					self.onBeforeReceiveCallback(client = client);


	def startRecvFrom (self, client, _async = False):
		self.startReceivingFrom(client, _async);


	def startReceivingFrom (self, client, _async = False):
		if _async:
			def method (**kwargs):
				if self.isClient(client):
					self.receive(client);

			self.setInterval(method, 1, {"self": self});
		else:
			while True:
				if self.isClient(client):
					self.receive(client);


	def onBeforeReceiveCallback (self, **kwargs):
		try:
			data = kwargs["client"]["conn"].recv(self._buffer); # Receieves data from client
			data = data.decode("utf-8"); # Decodes the received data
			if not data == "":
				data = self.jsonize(data); # Convert the data (in string format) to dict

				self.onReceiveCallback(data, kwargs["client"], None); # Trigger callback
		except Exception as e:
			self.onReceiveCallback(False, kwargs["client"], e); # Trigger callback


		self.setClientData(kwargs["client"], {"isSending": False});


	def send (self, client, data, _async = False):
		if self.isClient(client):

			client = self.refreshClientData(client);

			if not client["isReceiving"]:

				self.setClientData(client, {"isReceiving": True});

				if _async:
					self.setImmediate(self.onBeforeSendCallback, {"data": data, "client": client});
				else:
					self.onBeforeSendCallback(data = data, client = client);


	def onBeforeSendCallback (self, **kwargs):
		try:
			data = {
				"date": self.Clock.date(),
				"time": self.Clock.time(),
				"data": kwargs["data"]
			}

			kwargs["client"]["conn"].send(self.unjsonize(data).encode("utf-8"));

			self.onSendCallback(data, kwargs["client"], None);
		except Exception as e:
			self.onSendCallback(False, kwargs["client"], e);


		self.setClientData(kwargs["client"], {"isReceiving": False});


	def isClient (self, client):
		if not (client["index"] < len(self.connections)):
			return False;

		if not (client["ip"] == self.connections[client["index"]]["ip"]):
			return False;

		if not self.allowMultipleConnections:
			if not (client["port"] == self.connections[client["index"]]["port"]):
				return False

		if not (self.connections[client["index"]]["isConnected"]) or self.connections[client["index"]]["isBlocked"]:
			return False

		return True;


	def refreshClientData (self, client):
		if self.isClient(client):
			return self.connections[client["index"]];


	def setClientData (self, client, data):
		if self.isClient(client):
			self.connections[client["index"]] = {**self.connections[client["index"]], **data};


	def block (self, client):
		if self.isClient(client):
			self.connections[client["index"]]["isBlocked"] = True;


	def unBlock (self, client):
		if self.isClient(client):
			self.connections[client["index"]]["isBlocked"] = False;


	def disconnectAll (self, _async = False):
		if _async:
			self.setImmediate(self._disconnectAll);
		else:
			self._disconnectAll();


	def _disconnectAll (self):
		for client in self.connections:
			self.disconnect(client);


	def disconnect (self, client, _async = False):
		if _async:
			self.setImmediate(self.onBeforeDisconnectCallback, {"client": client});
		else:
			self.onBeforeDisconnectCallback(client = client);


	def onBeforeDisconnectCallback (self, **kwargs):
		if self.isClient(client):
			try:
				client = self.refreshClientData(kwargs["client"]);

				client["conn"].close(); # Close the client's connection

				self.setClientData(client, {"isConnected": False}); # Change the client's status to "disconnected"

				self.onDisconnectCallback(client, None); # Trigger the callback
			except Exception as e:
				self.onDisconnectCallback(False, e);


	def onStart (self, callback):
		self.onStartCallback = callback;


	def onConnect (self, callback):
		self.onConnectCallback = callback;


	def onReceive (self, callback):
		self.onReceiveCallback = callback


	def onRecv (self, callback):
		self.onReceiveCallback = callback


	def onSend (self, callback):
		self.onSendCallback = callback


	def onDisconnect (self, callback):
		self.onDisconnectCallback = callback;


	def close (self):
		self.shouldWait = False;
		self.closing = True;

		for client in self.connections:
			if client["isConnected"]:
				self.send(client, "Disconnecting you...");
				self.disconnect(client);

		self.server.close();
		self.closed = True;