server = WebsocketServer(WSPORT, host=WSHOST)
server.set_fn_new_client(ws_new_client)
server.set_fn_client_left(ws_client_left)
server.set_fn_message_received(ws_message_received)

mqtt_server = mqtt.Client("",True)
mqtt_server.on_connect = mqtt_on_connect
mqtt_server.on_disconnect = mqtt_on_disconnect
mqtt_server.on_message = mqtt_on_message
mqtt_server.on_log = mqtt_on_log

mqtt_server.connect(MQTTHOST, MQTTPORT, 60)
mqtt_server.loop_start()

t = threading.Thread(target=heartbeat)
t.daemon = True
t.start()

try:
    log.info("Listening on port %d for clients.." % server.port)
    server.serve_forever()
except KeyboardInterrupt:
    server.server_close()
    mqtt_server.loop_stop()
    log.info("Server terminated.")
except Exception as e:
    log.error(str(e), exc_info=True)

log.info('Ending')
Esempio n. 2
0
class CloudLink:
    def __init__(self):
        self.wss = None
        self.users = {}
        self.userlist = []
        self.handlers = []
        self.gdata = ""
        self.mode = 0  # 1=Host, 2=Client, 3=Plugin

    def host(self, port):
        if serverModeSupport:
            self.mode = 1
            self.wss = WebsocketServer(
                int(port)
            )  # Instanciate WebsocketServer alongside CloudLink module

            # Define callbacks to functions
            self.wss.set_fn_new_client(self.newConnection)
            self.wss.set_fn_message_received(self.gotPacket)
            self.wss.set_fn_client_left(self.closedConnection)

            # Run the server
            print("Now running in host mode on port {0}...".format(port))
            try:
                self.wss.serve_forever()
            except KeyboardInterrupt:
                if not len(self.users) == 0:
                    print("Shutdown in progress, please wait...")
                    # Tell all users to disconnect, and wait until all are disconnected
                    self.wss.send_message_to_all(json.dumps({"cmd": "ds"}))
                    while not len(self.users) == 0:
                        pass
                    print("All users disconnected, now exiting...")
                else:
                    print("Now exiting...")
                self.wss.server_close()
        else:
            print(
                "Error! Couldn't initialize mode 1: Support for Server mode has been disabled since you don't have the required websocket_server.py!"
            )
            sys.exit()

    def client(self):
        if clientOrPluginModeSupport:
            self.mode = 2
            print("Oops. This is a WIP feature. Sorry...")
            sys.exit()
        else:
            print(
                "Error! Couldn't initialize mode 2: Support for Client mode has been disabled since you don't have the required library websocket-client!"
            )
            sys.exit()

    def plugin(self):
        if clientOrPluginModeSupport:
            self.mode = 3
            print("Oops. This is a WIP feature. Sorry...")
            sys.exit()
        else:
            print(
                "Error! Couldn't initialize mode 3: Support for Plugin mode has been disabled since you don't have the required library websocket-client!"
            )
            sys.exit()

    def newConnection(self, client, server):
        if self.mode == 1:
            print("New connection: {0}".format(client['id']))
            self.users[str(client)] = {"name": "", "id": str(client['id'])}
            self.relayUserList(server, True, client)
            self.sendPacket(server, True, {
                "cmd": "gmsg",
                "id": client,
                "val": str(self.gdata)
            })

    def sendPacket(self, server, type, data):  # False:Public, True:Private
        if self.mode == 1:
            if "id" in data:
                id = data["id"]
                del data["id"]
            if type == False:
                server.send_message_to_all(json.dumps(data))
            elif type == True:
                server.send_message(id, json.dumps(data))

    def relayUserList(self, server, type, id):
        if self.mode == 1:
            y = ""
            for x in range(len(self.userlist)):
                y = str(y + self.userlist[x] + ";")
            self.sendPacket(server, type, {
                "cmd": "ulist",
                "id": id,
                "val": str(y)
            })

    def closedConnection(self, client, server):
        if self.mode == 1:
            if str(client) in self.users:
                if self.users[str(client)]['name'] in self.userlist:
                    print("Connection closed: {0} ({1})".format(
                        self.users[str(client)]['name'], client['id']))
                else:
                    print("Connection closed: {0}".format(client['id']))

                if self.users[str(client)]['name'] in self.userlist:
                    del self.userlist[self.userlist.index(
                        self.users[str(client)]['name'])]
                if client in self.handlers:
                    del self.handlers[self.handlers.index(client)]

                del self.users[str(client)]

                if not len(self.users) == 0:
                    self.relayUserList(server, False, client)

    def gotPacket(self, client, server, message):
        if self.mode == 1:
            err = False
            try:
                packet = json.loads(message)
            except Exception as e:
                err = True
            finally:
                if not err:
                    if "cmd" in packet:  # Check if the cmd parameter is specified
                        cmd = packet['cmd']
                        if "val" in packet:
                            val = packet["val"]
                        else:
                            val = ""
                        if "id" in packet:
                            try:
                                id = self.handlers[self.userlist.index(
                                    str(packet['id']))]
                            except Exception as e:
                                id = ""
                        else:
                            id = ""
                        if "name" in packet:
                            name = str(packet['name'])
                        else:
                            name = ""

                        if cmd == "clear":  # Clears comms
                            self.sendPacket(server, False, {
                                "cmd": "gmsg",
                                "val": ""
                            })
                            self.sendPacket(server, False, {
                                "cmd": "pmsg",
                                "val": ""
                            })
                        if cmd == "setid":  # Set username on server link
                            if "val" in packet:
                                if not client in self.handlers:
                                    self.userlist.append(val)
                                    self.handlers.append(client)
                                else:
                                    if self.users[str(
                                            client)]['name'] in self.userlist:
                                        self.userlist[self.userlist.index(
                                            self.users[str(
                                                client)]['name'])] = val
                                self.users[str(client)]['name'] = val
                                print("User {0} declared username: {1}".format(
                                    client['id'],
                                    self.users[str(client)]['name']))
                                self.relayUserList(server, False, client)
                        if cmd == "gmsg":  # Set global stream data values
                            self.gdata = str(val)
                            self.sendPacket(server, False, {
                                "cmd": "gmsg",
                                "val": self.gdata
                            })
                        if cmd == "pmsg":  # Set private stream data values
                            if not id == "":
                                self.sendPacket(server, True, {
                                    "cmd": "pmsg",
                                    "id": id,
                                    "val": val
                                })
                        if cmd == "gvar":  # Set global variable data values
                            self.sendPacket(server, False, {
                                "cmd": "gvar",
                                "name": name,
                                "val": val
                            })
                        if cmd == "pvar":  # Set private variable data values
                            if not id == "":
                                self.sendPacket(
                                    server, True, {
                                        "cmd": "pvar",
                                        "name": name,
                                        "id": id,
                                        "val": val
                                    })