Exemple #1
0
class Websocket_Server():

    def __init__(self, host, port):
        self.client_id_username_map = {}
        self.server = WebsocketServer(port, host = host, loglevel = logging.DEBUG)

    def new_client(self, client, server):
        print("new client connected and was given id {}".format(client['id']))
        self.server.send_message(client,"make connection : success!!")

    def client_left(self, client, server):
        print("client({}) disconnected".format(client['id']))

    def message_received(self, client, server, message):
        if message.startswith("init:username:"******"init:username:"******"")
            print(username)
            self.client_id_username_map[client["id"]] = username
            self.server.send_message_to_all(message)
        else:

            self.server.send_message_to_all(message)
    
    def run(self):
        self.server.set_fn_new_client(self.new_client)
        self.server.set_fn_client_left(self.client_left)
        self.server.set_fn_message_received(self.message_received) 
        self.server.run_forever()
Exemple #2
0
class RpiServerWS():
    """docstring for WebsocketServer"""
    server = None

    def __init__(self, parent):
        self.parent = parent
        self.server = WebsocketServer(8050,
                                      host=hosthome,
                                      loglevel=logging.INFO)
        self.server.set_fn_new_client(self.new_client)
        self.server.set_fn_message_received(self.message_received)
        self.server.set_fn_client_left(self.client_left)
        print('Websocket Server started, waiting for clients to connect')
        self.server.run_forever()

    def new_client(self, client, server):
        #print('Connected by ', client)
        self.parent.clientSockets.append(client)
        greeting = '{"functionName":"connected", "args":{} }'
        self.server.send_message(client, greeting)

    def message_received(self, client, server, message):
        item = (message, self.server, client)
        #print('putting ', item, 'in the queue')
        self.parent.callbackQueue.put(item)
        #self.server.send_message(client, 'WS: Message put in queue')

    def client_left(self, client, server):
        self.parent.clientSockets.remove(client)
Exemple #3
0
class Environment:
    """Clase de ambiente"""

    actions = {Action.HIT: 'HIT', Action.STAND: 'STAND'}
    duration = 0.01

    def __init__(self, host, port):
        print("host:" + host + " port:" + str(port))
        self.queue = multiprocessing.Queue()
        self.server = WebsocketServer(port, host=host)
        self.server.set_fn_new_client(self.new_client)
        self.server.set_fn_message_received(self.new_message)
        self.game_client = None
        thread = threading.Thread(target=self.server.run_forever)
        thread.daemon = True
        thread.start()

    def new_client(self, client, server):
        self.game_client = client
        self.server.send_message(self.game_client, "Connected! :)")

    def new_message(self, client, server, message):
        #Por lo general se envia la accion que se quiera tomar
        data = json.loads(message)
        state, score, finished = data['state'], data['reward'], data[
            'finished']
        # print(state, score, finished)
        self.queue.put((state, score, finished))

    def start_game(self):
        # game can not be started as long as the browser is not ready
        while self.game_client is None:
            time.sleep(self.duration)
        #Empezar el juego!
        self.server.send_message(self.game_client, "START")
        time.sleep(self.duration)
        return self.get_state()

    def refresh_game(self):
        #Empezar el juego!
        print("Refreshing")
        self.server.send_message(self.game_client, "START")
        time.sleep(self.duration)

    def do_action(self, action):
        print(self.actions[action])
        self.server.send_message(self.game_client, self.actions[action])
        time.sleep(self.duration)
        return self.get_state()

    def get_state(self):
        self.server.send_message(self.game_client, "STATE")
        time.sleep(self.duration)
        state, score, finished = self.queue.get()
        print("Actual hand(state):", state, "Score:", score, "Finished:",
              finished)
        return state, score, finished
 def on_export_data(self, client, server: WebsocketServer, file_name: str,
                    json_data: str):
     excel_data = self.converter.json_to_excel(json_data)
     ext = file_name.split('.')[1]
     excel: Any
     if ext == 'xls':
         excel = excel_data.xls
     if ext == 'xlsx':
         excel = excel_data.xlsx
     try:
         open('output/%s' % file_name, 'wb').write(excel)
         server.send_message(client, 'res|info|io')
     except:
         print('Error occured while trying to write file.')
         server.send_message(client, 'res|error|io')
Exemple #5
0
def message_received(client, server, message):
    if len(message) > 200:
        message = message[:200]+'..'
    print("Client(%d) said: %s" % (client['id'], message))
    try:
        msg = json.loads(message)
        if msg['type'] == "GET":
            response = json.dumps({"port":1081})
            WebsocketServer.send_message(server, client, response)
            print('config sent')
        if msg['type'] == "SET":
            config = msg["conf"]
            print(config)
            print('config updated!')
    except Exception as e:
        pass
Exemple #6
0
class Server(object):
    def __init__(self, ip, port):
        self.__ip = ip
        self.__port = port
        self.__server = None

    def __new_client(self, client, server):
        logging.info(client)
        logging.info(server.clients)
    
    def __client_left(self, client, server):
        logging.info(client)
        logging.info(server.clients)
    
    def __recv_ping(self, client, data=''):
        self.__send_msg_client(client, str({'timestamp' : int(1000 * time.time())}))

    def __message_received(self, client, server, message):
        if not message:
            self.__recv_ping(client, message)
        logging.info(client)
        logging.info(message)
        self.__send_msg(message)

    def __run(self):
        try:
            self.__server = WebsocketServer(self.__ip, self.__port) 
            self.__server.set_fn_new_client(self.__new_client)            
            self.__server.set_fn_client_left(self.__client_left)              
            self.__server.set_fn_message_received(self.__message_received)    
            self.__server.run_forever()
        except Exception as e:
            logging.exception(e)
            self.__server = None
   
    def __send_msg_client(self, client, message):
        if self.__server:
            self.__server.send_message(client, message)

    def __send_msg(self, message):
        if self.__server:
            self.__server.send_message_to_all(message)

    def start(self):
        #while True:
        self.__run()
Exemple #7
0
class ParentMain(Parent):
  def new_client(self, client, server):
    values["clients"] = server.clients

  def client_left(self, client, server):
    values["clients"] = server.clients

  def message_received(self, client, server, message):
    values["messages"].append({client["id"]: message})
    values["newest"][client["id"]] = message
  
  def __init__(self, config: dict):
    super().__init__(config)
    __port = config['port']
    self.__server = WebsocketServer(port=__port, host='0.0.0.0')
    self.__server.set_fn_new_client(self.new_client)
    self.__server.set_fn_client_left(self.client_left)
    self.__server.set_fn_message_received(self.message_received)
    th = threading.Thread(target=self.__server.run_forever)
    th.setDaemon(True)
    th.start()

  def read(self, params):
    super().read(params)
    __tag = params["tag"]
    if __tag in values:
      return values[__tag]
    else:
      return None

  def write(self, value, params):
    super().write(value, params)
    __tag = params["tag"]
    __client = params["client"]
    if __tag == "send_to_client":
      if "client" in params:
        __client = params["client"]
        self.__server.send_message(__client, value)
    elif __tag == "send_to_all":
      self.__server.send_message_to_all(value)

  def __del__(self):
    super().__del__()
    del self.__server
Exemple #8
0
class IPCWebSocket(object):
    def __init__(self, ipc):
        self.ipc = ipc
        self.server = WebsocketServer(9000)
        self._set_callbacks(self.server)

        self.clients = []

    def start(self):
        from threading import Thread

        def run():
            self.server.run_forever()
        t = Thread(target=run)
        t.daemon = True
        t.start()

    def _set_callbacks(self, server):
        server.set_fn_new_client(self.on_connect)
        server.set_fn_client_left(self.on_disconnect)
        server.set_fn_message_received(self.on_message)

    def on_connect(self, client, server):
        print("New client connected")
        self.clients.append(client)

    def on_disconnect(self, client, server):
        print("Client disconnected")
        self.clients = [c for c in self.clients if c['id'] != client['id']]

    def on_message(self, client, server, message):
        message = json.loads(message)
        self.ipc.on_message(client, message)

    def broadcast(self, message):
        message = json.dumps(message)
        for c in self.clients:
            self.server.send_message(c, message)
        print("broadcasted message to {} clients".format(len(self.clients)))

    def send(self, client, message):
        self.server.send_message(client, json.dumps(message))
Exemple #9
0
class IPCWebSocket(object):
    def __init__(self, ipc, port):
        self.ipc = ipc
        self.server = WebsocketServer(port)
        self._set_callbacks(self.server)

        self.clients = []

    def start(self):
        from threading import Thread

        def run():
            self.server.run_forever()

        t = Thread(target=run)
        t.daemon = True
        t.start()

    def _set_callbacks(self, server):
        server.set_fn_new_client(self.on_connect)
        server.set_fn_client_left(self.on_disconnect)
        server.set_fn_message_received(self.on_message)

    def on_connect(self, client, server):
        self.clients.append(client)

    def on_disconnect(self, client, server):
        self.clients = [c for c in self.clients if c['id'] != client['id']]

    def on_message(self, client, server, message):
        message = json.loads(message)
        self.ipc.on_message(client, message)

    def broadcast(self, message):
        message = json.dumps(message)
        for c in self.clients:
            self.server.send_message(c, message)

    def send(self, client, message):
        self.server.send_message(client, json.dumps(message))
Exemple #10
0
class OrderingHub():
  def __init__(self, host='localhost', port=7777, isdebug=True):
    self.server = WebsocketServer(port, host)
    self.server.set_fn_new_client(self.new_client)
    self.server.set_fn_client_left(self.client_left)
    self.clients = {}
    self.clientId = 0
    self.orderId = 0;
    return

  def run(self):
    self.server.run_forever()
    return

  def set_callback(self, callback):
    # self.server.set_fn_message_received(lambda client, server,message: callback(json.loads(message), self.send_all))
    self.server.set_fn_message_received(lambda client, server,message: callback(self, json.loads(message), self.send_all))
    return

  def send_all(self, message):
    for c in self.clients.values():
      self.server.send_message(c, json.dumps(message))
    return

  def new_client(self, client, server):
    print('hello clinet')
    client['id'] = self.clientId
    self.clients[self.clientId] = client
    print('add client(id={})'.format(self.clientId))
    self.clientId = self.clientId+1
    return
  
  def client_left(self, client, server):
    print('closing clientid={}'.format(client['id']))
    del self.clients[client['id']]
    return 
 def on_get_version(self, client, server: WebsocketServer):
     version = self.database.get_version()
     server.send_message(client, 'res|version|%s' % version[0])
Exemple #12
0
class WebSocket(Agent):

    autostart = True

    def __init__(self):
        super(WebSocket, self).__init__()
        self.target = self.identifier
        self.server = WebsocketServer(5601, "0.0.0.0")
        self.wsThread = threading.Thread(target=self.server.run_forever)
        self.clients = self.server.clients
        self.subscriptions = []

        @self.server.set_fn_new_client
        def new_client(client, server):
            client["subscriptions"] = []

        @self.server.set_fn_client_left
        def client_left(client, server):
            logging.info("Client(%d) disconnected" % client['id'])

        @self.server.set_fn_message_received
        def message_received(client, server, msg):
            if msg:
                try:
                    event = json.loads(msg)
                    event_type = event["type"]
                    event_data = event["data"]
                    if event_type == "subscribe":
                        self._subscribe(client, event_data)
                    elif event_type == "unsubscribe":
                        self._unsubscribe(client, msg)
                    else:
                        Dispatcher().put_event(Event(type=event_type, data=event_data))
                except json.decoder.JSONDecodeError as e:
                    pass

    def run(self):
        self.wsThread.start()
        self._listener()

    def _listener(self):
        while self.wsThread.isAlive():
            event = self.next_event()
            event_type = event["type"]
            event_data = event["data"]
            for client in self.clients:
                if event_type in client["subscriptions"]:
                    self.server.send_message(client, json.dumps(event))

    def _subscribe(self, client, event_data):
        client["subscriptions"].append(str(event_data))
        if not str(event_data) in self.subscriptions:
            self.subscriptions.append(str(event_data))
            Dispatcher().bind(self, event_data)
        logging.info("Client subscribed to " + event_data)

    def _unsubscribe(self, client, event_data):
        if str(event_data) in client["subscriptions"]:
            client["subscriptions"].remove(event_data)
            othersubscriber = False
            for otherclient in self.clients:
                if str(event_data) in otherclient["subscriptions"]:
                    othersubscriber = True
            if not othersubscriber:
                self.subscriptions.remove(str(event_data))
            logging.info("Client unsubscribed from " + event_data)
        else:
            # Client wasn't found in subscribers list
            pass
Exemple #13
0
class SerialServer(object):
    ''' 串口硬件  ==>  串口服务器(ws server)  ==>  电脑浏览器(ws client)
        电脑浏览器(ws client) ==>  串口服务器(ws server)  ==>  串口硬件
    '''
    def __init__(self, websocket_server_port):
        super(SerialServer, self).__init__()

        self.ser = Serial()

        self.ws_client = None

        self.ws = WebsocketServer(port=websocket_server_port)
        self.ws.set_fn_new_client(
            lambda client, server: self.ws_new_client(client))
        self.ws.set_fn_message_received(
            lambda client, server, message: self.ws_message_received(message))

        threading.Thread(target=self.ws.run_forever).start()

        threading.Thread(target=self.ser_receive).start()

    def ws_new_client(self, client):
        self.ws_client = client

    def ws_message_received(self, message):
        msg = json.loads(message)
        if 'cmd' in msg:
            if msg['cmd'] == 'open serial':
                print(msg['port'])
                print(msg['baud'])

                if not self.ser.is_open:
                    try:
                        self.ser.port = msg['port']
                        self.ser.baudrate = msg['baud']
                        self.ser.open()
                    except Exception as e:
                        print(e)
                        self.ws.send_message(
                            self.ws_client,
                            json.dumps({'cmd': 'serial closed'}))
                    else:
                        self.ws.send_message(
                            self.ws_client,
                            json.dumps({'cmd': 'serial opened'}))

            elif msg['cmd'] == 'close serial':
                print('close')

                if self.ser.is_open:
                    self.ser.close()

                    self.ws.send_message(self.ws_client,
                                         json.dumps({'cmd': 'serial closed'}))

        elif 'data' in msg:
            print(msg['data'])
            if self.ser.is_open:
                self.ser.write(msg['data'].encode())

    def ser_receive(self):
        while True:
            if self.ser.is_open:
                num = self.ser.in_waiting
                if num > 0:
                    bytes = self.ser.read(num)
                    print(bytes)

                    if self.ws_client:
                        self.ws.send_message(
                            self.ws_client,
                            json.dumps({'data': bytes.decode()}))

            time.sleep(0.1)
Exemple #14
0
class SyncPlayerServer():
    clients = {}
    log = []

    player_filenum = '1'
    player_time = 0.0
    player_start_time = 0.0
    player_is_playing = False

    def __init__(self, host, port):
        self.server = WebsocketServer(port, host=host, loglevel=logging.DEBUG)

    # on new client
    def new_client(self, client, server):
        self.clients[client['id']] = {
            'name': 'id' + str(client['id']),
            'is_ready': False
        }
        self.send_client_list()
        self.send_text('[SERVER]',
                       self.clients[client['id']]['name'] + 'が参加しました')

        obj = { \
            'message_kind': 'player_load', \
            'filenum': self.player_filenum}
        self.server.send_message(client, json.dumps(obj))

    # on client left
    def client_left(self, client, server):
        print("client({}) disconnected".format(client['id']))
        self.server.clients.remove(client)
        if (len(self.server.clients) > 0):
            self.send_client_list()
            self.send_text('[SERVER]',
                           self.clients[client['id']]['name'] + 'が退出しました')
        self.clients.pop(client['id'])

    # on message received
    def message_received(self, client, server, message_raw):
        print("client({}) said: {}".format(client['id'], message_raw))

        message = json.loads(message_raw)

        # クライアントの名前を設定する
        if message['message_kind'] in 'set_name':
            self.send_text(
                '[SERVER]', '名前変更 ' + self.clients[client['id']]['name'] +
                ' → ' + message['name'])
            self.clients[client['id']]['name'] = message['name']
            self.send_client_list()
        elif message['message_kind'] in 'text':
            self.send_text(self.clients[client['id']]['name'],
                           message['content'])

        # ファイルを読み込む
        elif message['message_kind'] in 'player_load':
            self.player_filenum = message['filenum']
            self.player_time = 0.0
            self.player_start_time = 0.0
            self.player_is_playing = False

            obj = { \
                'message_kind': 'player_load', \
                'filenum': self.player_filenum}
            self.send_message_exclude_a_client(client, json.dumps(obj))
            self.send_text(
                '[SERVER]', self.clients[client['id']]['name'] + 'が' +
                self.player_filenum + 'をロードしました')

            for key in self.clients:
                self.clients[key]['is_ready'] = False
            self.send_client_list()

        # 再生したりポーズしたり
        elif message['message_kind'] in 'player_play_pause':
            self.player_time = message['time']
            self.player_start_time = time.time()
            self.player_is_playing = message['is_playing']

            obj = { \
                'message_kind': 'player_play_pause', \
                'time': self.player_time,\
                'is_playing': self.player_is_playing}
            self.send_message_exclude_a_client(client, json.dumps(obj))
            if self.player_is_playing:
                self.send_text('[SERVER]',
                               self.clients[client['id']]['name'] + 'によって再生')
            else:
                self.send_text('[SERVER]',
                               self.clients[client['id']]['name'] + 'によって一時停止')

        # 時間を取得(遅れて来た人向け)
        # elif message['message_kind'] in 'get_player_time' :
        #     if self.player_is_playing:
        #         diff = time.time() - self.player_start_time
        #         ptime = self.player_time + diff
        #     else:
        #         ptime = self.player_time
        #
        #     obj = { \
        #         'message_kind': 'player_time', \
        #         'time': ptime, \
        #         'is_playing': self.player_is_playing}
        #     self.server.send_message(client,json.dumps(obj))

        # 準備完了
        elif message['message_kind'] in 'set_ready':
            self.clients[client['id']]['is_ready'] = message['is_ready']

            if self.player_is_playing:
                diff = time.time() - self.player_start_time
                ptime = self.player_time + diff
            else:
                ptime = self.player_time

            obj = { \
                'message_kind': 'player_play_pause', \
                'time': ptime, \
                'is_playing': self.player_is_playing}
            self.server.send_message(client, json.dumps(obj))

            # obj = { \
            #     'message_kind': 'set_ready', \
            #     'id' : client['id'],\
            #     'is_ready': self.clients[client['id']]['is_ready']}
            # self.server.send_message_to_all(json.dumps(obj))
            self.send_client_list()

    # クライアント一覧を送信
    def send_client_list(self):
        self.server.send_message_to_all(
            json.dumps({
                'message_kind': 'clients_list',
                'clients': self.clients
            }))

    # テキストメッセージを送信すると同時にログに貯める
    def send_text(self, name, content):
        obj = { \
            'message_kind': 'text', \
            'name': name, \
            'content': content}
        self.server.send_message_to_all(json.dumps(obj))
        self.log.append(obj)

    # あるクライアント以外に送信
    def send_message_exclude_a_client(self, client, message):
        for item in self.server.clients:
            if item == client:
                continue
            self.server.send_message(item, message)

    # run server
    def run(self):
        self.server.set_fn_new_client(self.new_client)
        self.server.set_fn_client_left(self.client_left)
        self.server.set_fn_message_received(self.message_received)
        self.server.run_forever()
class WebSocketServer:
    
    def __init__(self):
        self.server = WebsocketServer(8082, host='0.0.0.0')
        self.server.set_fn_new_client(self.onClient)
        self.server.set_fn_message_received(self.onMessage)
        self.openCvService = OpenCvService()
    
    def onClient(self, client, server):
        print("new client", client)
    
    def onMessage(self, client, server, message):
        print("new message", message)
        messageParsed = json.loads(message)
        command = messageParsed['command']
        args = messageParsed['args']
        if command == "ping":
            print('PONG!')
        if command == "photo":
            print('TAKE PHOTO')
            self.send(client, "PIC#" + self.openCvService.takePicture())
        if command == "begin_calibration":
            # will clean the calib_tmp folder
            self.openCvService.beginCalibration(self, client)
        if command == "calibration_snapshot":
            self.openCvService.calibrationSnapshot(self, client, args['calibrationId'])
        if command == "calibration_process":
            self.openCvService.processCalibrationData(self, client, args['calibrationId'])
        if command == "calibration_fetch_saves":
            self.openCvService.fetchSaves(self, client)
        if command == "calibration_fetch_save":
            self.openCvService.fetchSave(self, client, args['calibrationId'])
        if command == "enable_markers":
            # enable marker for this specific client
            self.openCvService.enableMarkers()
        if command == "disable_markers":
            # enable marker for this specific client
            self.openCvService.disableMarkers()
        if command == "enable_position":
            # enable marker for this specific client
            self.openCvService.enablePosition()
        if command == "disable_position":
            # enable marker for this specific client
            self.openCvService.disablePosition()
        if command == "live":
            # create a new thread
            self.openCvService.startLiveVideo(self, client)
        if command == "stop_live":
            self.stopClientLiveThread(client)
        # if command == "calibration_get_input_data":
        #     with open(args['path'], "rb") as imageFile:
        #         sent = "data:image/jpeg;base64," + base64.b64encode(imageFile.read()).decode("utf-8")
        #         self.send(client, "calibrationData", sent)
        if command == "calibration_delete_input_data":
            frameId = str(int(args['calibrationFrameId']))
            calibrationId = args['calibrationId']
            if not re.compile('^[a-z0-9\-]+$').match(calibrationId):
                print('ERR: Calibration id not match')
                return
            self.openCvService.deleteInputData(calibrationId, frameId)
            

    def send(self, client, responseType, data = None):
        if not client['handler'].keep_alive:
            return False
        toSend = json.dumps({'responseType': responseType, 'data': data})
        # if responseType != 'frame':
        #     print(toSend)
        self.server.send_message(client, toSend)
        return True

    def start(self):
        self.server.run_forever()
Exemple #16
0
class WebSocket:
    def __init__(self):
        self.server = None
        self.rooms = None
        self.clientSelectedRoom = dict()
        self.debugMode = False

    # Called for every client connecting (after handshake)
    def new_client(self,client, server):
        print("New client connected and was given id %d" % client['id'])

        self.clientSelectedRoom[client['id']]=-1
        if self.rooms == None or len(self.rooms) == 0:
            server.send_message(client,"0")
        else:
            messageStr = self.getRoomInfo(self.rooms)
            server.send_message(client,"R:"+messageStr)

    # Called for every client disconnecting
    def client_left(self,client, server):
        # print("Client(%d) disconnected" % client['id'])
        self.clientSelectedRoom.pop(client['id'])
        print("Client disconnected")
        pass

    # Called when a client sends a message
    def message_received(self,client, server, message):
        if len(message) > 200:
            message = message[:200]+'..'
        print("Client(%d) said: %s" % (client['id'], message))
        if message == "debug":
            self.debugMode = True
        elif message == "normal":
            self.debugMode = False
        else:
            roomIndex=int(message)
            self.clientSelectedRoom[client['id']]=roomIndex
            if roomIndex < len(self.rooms):
                room = self.rooms[roomIndex]
                messageStr = self.getUpdateInfo(self.rooms[roomIndex])
                server.send_message(client,messageStr)

    def start(self):
        port=3344
        self.server = WebsocketServer(port,host='0.0.0.0')
        self.server.set_fn_new_client(self.new_client)
        self.server.set_fn_client_left(self.client_left)
        self.server.set_fn_message_received(self.message_received)
        server_thread = threading.Thread(target=self.server.run_forever)
        server_thread.daemon = True
        server_thread.start()

    def stop(self):
        self.server.server_close()

    def findClientFromId(self,clientId):
        for client in self.server.clients:
            if client['id'] == clientId:
                return client
        return None

    def updateRooms(self,Rooms,removeIndex):
        self.rooms=Rooms
        messageStr = ""
        if len(self.rooms) != 0:
            messageStr = self.getRoomInfo(self.rooms)
        self.server.send_message_to_all("R:"+messageStr)
        if removeIndex != -1:
            for key in self.clientSelectedRoom:
                if self.clientSelectedRoom[key] > removeIndex:
                    self.clientSelectedRoom[key]-=1
                elif self.clientSelectedRoom[key] == removeIndex:
                    self.clientSelectedRoom[key]=-1

    def updateContent(self,Rooms,roomIndex):
        self.rooms=Rooms
        for clientId,selectedIndex in self.clientSelectedRoom.iteritems():
            client = self.findClientFromId(clientId)
            if client == None:
                continue
            if selectedIndex == roomIndex:
                messageStr = self.getUpdateInfo(Rooms[roomIndex])
                self.server.send_message(client,messageStr)

    def getRoomInfo(self,rooms):
        content = ""
        for room in rooms:
            names = ""
            for index in range(4):
                name = room.users[index].name
                names += name
                if index != 3:
                    names += "、"
            content += names + "|"
        content = content[:-1]
        return content

    def getUpdateInfo(self,room):
        # trump^{info}^{Name}^{call}^{three}^{play}^{card}
        info = ""
        if room.attackTeam!="":
            info = room.attackTeam + "|" + ("%d / %d")%(room.attackScore,room.attackWinNumber) + "|" + room.defenseTeam + "|" + ("%d / %d")%(room.defenseScore,14-room.attackWinNumber)
        name = ""
        for user in room.users:
            name += user.name + "|"
        name = name[:-1]
        call = ""
        subCalls = [[],[],[],[]]
        for index in range(4):
            subCalls[index] = room.callsRaw[index].split('^')
        count=0;index=0;length=0
        while 1:
            subCall = subCalls[index]
            str = ""
            if length < len(subCall) and subCall[length]!="":
                str = subCall[length]
            elif(subCalls[index]!=""):
                count+=1
                subCalls[index]=""
            if count == 4:
                break
            call += str + ","
            if index+1 == 4:
                index = 0
                length += 1
                call = call[:-1]
                call += "|"
            else:
                index += 1
        call = call[:-1]
        three = ""
        for player in room.threeModeUsers:
            three += player + "|"
        three = three[:-1]
        play = ""
        subPlays = [[],[],[],[]]
        for index in range(4):
            subPlays[index] = room.playsRaw[index].split('^')
        count=0;index=0;length=0
        while 1:
            subPlay = subPlays[index]
            str = ""
            if length < len(subPlay):
                str = subPlay[length]
            if count == 13:
                break
            play += str + ","
            if index+1 == 4:
                index = 0
                length += 1
                count += 1
                play = play[:-1]
                play += "|"
            else:
                index += 1
        play = play[:-1]
        winBount = room.boutsWinRecord[:-1]
        flower = ""
        for index in range(4):
            flower += ("%d|")%room.flowerCountRecord[index]
        flower = flower[:-1]
        card = ""
        if room.users[0].name!="":
            for index in range(4):
                str = ""
                for poker in room.playsPokerHand[index]:
                    str += ("%d,")%poker
                card += str[:-1] + "|"
        card = card[:-1]
        return ("%d")%room.getTrump() + "^" + info + "^" + name + "^" + call + "^" + three + "^" + play + "^" + winBount + "^"+ flower + "^" +card
Exemple #17
0
class FakeGWServer(threading.Thread):
    """
	Creates an FakeGWServer.

	Arguments:
	port -- port of WebSocket connection.
	config -- configuration of behaviour, could contain following parameters:
		'autoRegister' -- automatic registration accepting
		'autoResponse' -- automatic response for requests
		'autoData' -- automatic data messages processing
		'prePaired' -- list of paired devices for device_list requests.
		'autoNewDevice' -- automatic new device reqests handling
	"""
    def __init__(self, port, config, host='127.0.0.1'):
        self.autoRegister = config['autoRegister']
        self.autoResponse = config['autoResponse']
        self.autoData = config['autoData']
        self.prePaired = config['prePaired']
        self.autoNewDevice = config['autoNewDevice']

        self.WSServer = WebsocketServer(port, host, loglevel=logging.DEBUG)
        self.WSServer.set_fn_message_received(self.message_received)
        self.WSServer.set_fn_client_left(self.client_left)
        self.WSServer.set_fn_new_client(self.new_client)

        self.messages = []
        self.dataMessages = []
        self.responseMessages = []
        self.newDevices = []
        self.client = None
        self.clientLock = threading.Lock()
        self.newConnection = threading.Condition(self.clientLock)
        self.disconnect = threading.Condition(self.clientLock)
        self.newMessage = threading.Condition(self.clientLock)
        self.newDataMessage = threading.Condition(self.clientLock)
        self.newResponseMessage = threading.Condition(self.clientLock)
        self.newDeviceMessage = threading.Condition(self.clientLock)
        self.connected = False
        self.resetEnable = False
        super().__init__()

    def run(self):
        self.WSServer.run_forever()
        self.WSServer.socket.close()

    def stop(self):
        self.WSServer.shutdown()

    def enableReset(self):
        with self.clientLock:
            self.resetEnable = True

    def new_client(self, client, server):
        with self.clientLock:
            if self.connected:
                logging.debug("Unknown client refused")
                client['handler'].send_text("",
                                            websocket_server.OPCODE_CLOSE_CONN)
            elif self.client is None or self.resetEnable:
                self.client = client
                if not self.autoRegister:
                    self.connected = True
                    self.newConnection.notify_all()
                self.resetEnable = False
                logging.debug("connection established")
            else:
                logging.debug("dropping completely")
                client['handler'].send_text("",
                                            websocket_server.OPCODE_CLOSE_CONN)

    def client_left(self, client, server):
        with self.clientLock:
            if client == self.client:
                logging.debug("client disconnected")
                self.connected = False
                self.messages = []
                self.disconnect.notify_all()
            else:
                logging.debug("unknown client disconnected")

    def message_received(self, client, server, message):
        logging.debug("received: " + message)
        with self.clientLock:
            if self.client != client:
                logging.debug("dropping message from unknown client")
                return
            try:
                jsonMessage = json.loads(message)
                if self.autoRegister:
                    if jsonMessage['message_type'] == "gateway_register":
                        self.WSServer.send_message(
                            self.client,
                            '{ "message_type" : "gateway_accepted" }')
                        self.connected = True
                        self.newConnection.notify_all()
                        return
                if self.autoData:
                    if jsonMessage['message_type'] == "sensor_data_export":
                        sensorData = SensorData.SensorData()
                        sensorData.fromJSON(jsonMessage['data'][0])
                        self.dataMessages.append(sensorData)
                        self.newDataMessage.notify_all()
                        response = {}
                        response['message_type'] = "sensor_data_confirm"
                        response['id'] = jsonMessage['id']
                        logging.debug("sending message: " +
                                      json.dumps(response))
                        self.WSServer.send_message(self.client,
                                                   json.dumps(response))
                        return
                if self.prePaired is not None:
                    if jsonMessage['message_type'] == "device_list_request":
                        if jsonMessage['device_prefix'] in self.prePaired:
                            response = {}
                            response['message_type'] = "device_list_response"
                            response['id'] = jsonMessage['id']
                            response['status'] = 1
                            response['devices'] = self.prePaired[
                                jsonMessage['device_prefix']]
                            logging.debug("sending message: " +
                                          json.dumps(response))
                            self.WSServer.send_message(self.client,
                                                       json.dumps(response))
                        return
                if self.autoResponse:
                    if jsonMessage['message_type'] == "response_with_ack":
                        self.responseMessages.append(jsonMessage)
                        self.newResponseMessage.notify_all()
                        response = {}
                        response['message_type'] = "generic_ack"
                        response['id'] = jsonMessage['id']
                        response['status'] = jsonMessage['status']
                        logging.debug("sending message: " +
                                      json.dumps(response))
                        self.WSServer.send_message(self.client,
                                                   json.dumps(response))
                        return
                    if jsonMessage['message_type'] == "generic_response":
                        self.responseMessages.append(jsonMessage)
                        self.newResponseMessage.notify_all()
                        return

                if self.autoNewDevice:
                    if jsonMessage['message_type'] == "new_device_request":
                        device = Device.Device(jsonMessage)
                        self.newDevices.append(device)
                        self.newDeviceMessage.notify_all()
                        response = {}
                        response['message_type'] = "generic_ack"
                        response['id'] = jsonMessage['id']
                        response['status'] = 1
                        logging.debug("sending message: " +
                                      json.dumps(response))
                        self.WSServer.send_message(self.client,
                                                   json.dumps(response))
                        return

            except Exception as ex:
                logging.error("Exception: " + str(ex))
                pass

            self.messages.append(message)
            self.newMessage.notify_all()

    def nextNewDevice(self, timeout=10):
        with self.clientLock:
            if not self.newDevices:
                self.newDeviceMessage.wait(timeout)
            if self.newDevices:
                return self.newDevices.pop(0)

    def nextResponse(self, timeout=10):
        with self.clientLock:
            if not self.responseMessages:
                self.newResponseMessage.wait(timeout)
            if self.responseMessages:
                return self.responseMessages.pop(0)

    def nextData(self, timeout=10):
        with self.clientLock:
            if not self.dataMessages:
                self.newDataMessage.wait(timeout)
            if self.dataMessages:
                return self.dataMessages.pop(0)

    def clearData(self):
        with self.clientLock:
            self.dataMessages = []

    def nextMessage(self, timeout=10):
        with self.clientLock:
            if not self.messages:
                self.newMessage.wait(timeout)
            if self.messages:
                return self.messages.pop(0)

    def waitForDisconnect(self, timeout=10):
        with self.clientLock:
            if not self.connected:
                return True
            self.disconnect.wait(timeout)
            return not self.connected

    def waitForConnection(self, timeout=10):
        with self.clientLock:
            if self.connected:
                return True
            self.newConnection.wait(timeout)
            return self.connected

    def sendMessage(self, message):
        with self.clientLock:
            if self.connected:
                logging.debug("sending message: " + message)
                self.WSServer.send_message(self.client, message)
            else:
                raise Exception("client is not connected")
class SwarmNode:
    def __init__(self, host):
        self.logger = logger.get_logger(__name__, 'swarm_node')
        self.assets_paths = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'assets'))
        self.assets = {}
        self.load_assets()
        Thread(target=self.maintain_assets).start()
        self.host = host
        self.api_port = 8721
        self.api = WebsocketServer(self.api_port, host=self.host)
        self.api.set_fn_message_received(self.api_on_message)
        self.api_thread = Thread(target=self.api.run_forever)
        self.api_thread.start()
        self.logger.info('Swarm API server started, listening on {}:{}'.format(self.host, self.api_port))
        self.report_queue = queue.Queue()
        self.reports_thread = Thread(target=self.reports_listener)
        self.reports_thread.start()
        self.cartography = {
            'messages': {},
            'authorized_clients': []
        }

    def load_assets(self):
        start = time.time()
        assets_downloader.update_assets()
        files_packs = {}
        self.logger.info('Mapping static assets')
        for file in os.listdir(self.assets_paths):
            if file.endswith('.json'):
                if file.replace('.json', '').split('_')[-1].isdigit():
                    if '_'.join(file.replace('.json', '').split('_')[:-1]) not in files_packs.keys():
                        files_packs['_'.join(file.replace('.json', '').split('_')[:-1])] = [file]
                    else:
                        files_packs['_'.join(file.replace('.json', '').split('_')[:-1])].append(file)
                else:
                    files_packs[file.replace('.json', '')] = [file]

        self.logger.info('Loading static assets...')
        self.load_assets_list(files_packs)
        self.logger.info('Done loading assets in {}s'.format(round(time.time() - start, 2)))

    def build_files_packs_from_assets_names(self, assets_names):
        files_packs = {}
        for assset_name in assets_names:
            for file in os.listdir(self.assets_paths):
                if file.endswith('.json') and assset_name in file:
                    if file.replace('.json', '').split('_')[-1].isdigit():
                        if '_'.join(file.replace('.json', '').split('_')[:-1]) not in files_packs.keys():
                            files_packs['_'.join(file.replace('.json', '').split('_')[:-1])] = [file]
                        else:
                            files_packs['_'.join(file.replace('.json', '').split('_')[:-1])].append(file)
                    else:
                        files_packs[file.replace('.json', '')] = [file]
        return files_packs

    def load_assets_list(self, files_packs):
        for asset_name, file_pack in files_packs.items():
            self.logger.info('Loading asset: {}'.format(asset_name))
            if len(file_pack) <= 20:
                for file in file_pack:
                    with open(self.assets_paths + '/' + file, 'r', encoding='utf8') as f:
                        data = json.load(f)
                    if asset_name not in self.assets.keys():
                        self.assets[asset_name] = data
                    else:
                        if type(data) is list:
                            self.assets[asset_name] += data
                        elif type(data) is dict:
                            self.assets[asset_name].update(data)
            else:
                with Pool(cpu_count() - 1) as p:
                    results_list = p.map(self.load_asset_chunk, [self.assets_paths + '/' + file_name for file_name in file_pack])
                for asset_chunk in results_list:
                    if asset_name not in self.assets.keys():
                        self.assets[asset_name] = asset_chunk
                    else:
                        if type(asset_chunk) is list:
                            self.assets[asset_name] += asset_chunk
                        elif type(asset_chunk) is dict:
                            self.assets[asset_name].update(asset_chunk)

    def maintain_assets(self):
        self.logger.info('Assets maintainer starting')
        try:
            while 1:
                time.sleep(60)
                updated_files = assets_downloader.update_assets()
                updated_assets = set()
                for file in updated_files:
                    if file.split('_')[-1].isdigit():
                        updated_assets.add('_'.join(file.split('_')[:-1]))
                    else:
                        updated_assets.add(file)

                if len(updated_assets):
                    start = time.time()
                    self.logger.info('Updating assets: '.format(updated_assets))
                    files_packs = self.build_files_packs_from_assets_names(updated_assets)
                    self.load_assets_list(files_packs)
                    self.logger.info('Done updating assets in {}s'.format(round(time.time() - start, 2)))
        except:
            self.logger.error('Assets maintainer crashed')
            self.logger.error(traceback.format_exc())
            send_discord_message("Assets maintainer crashed")
            send_discord_message("`{}`".format(traceback.format_exc()))
            time.sleep(1)

    def load_asset_chunk(self, file_path):
        with open(file_path, 'r', encoding='utf8') as f:
            chunk = json.load(f)
        return chunk

    def api_on_message(self, client, server, message):
        if message == '':
            return
        try:
            self.logger.info('Recieved from {}: {}'.format(client['address'], message))
            message = json.loads(message)
            if 'id' not in message.keys():
                message['id'] = str(uuid.uuid4())

            if 'command' in message.keys() and message['command'] != 'login':
                new_authorized_clients = []
                found = False
                for authorized_client, valid_until in self.cartography['authorized_clients']:
                    if valid_until > time.time():
                        new_authorized_clients.append((authorized_client, valid_until))
                        if authorized_client == client:
                            found = True
                self.cartography['authorized_clients'] = new_authorized_clients
                if not found:
                    self.logger.warning('Unauthorized client tried to connect')
                    message['success'] = False
                    message['details'] = {'reason': 'Unauthorized client'}
                    self.api.send_message(client, json.dumps(message))
                    return

            self.cartography['messages'][message['id']] = client
            intercept_command = False

            if 'command' in message.keys() and message['command'] == 'new_bot':
                self.logger.info('Creating new bot : ' + str(message['parameters']))
                try:
                    strategies.support_functions.create_profile(
                        id=message['parameters']['id'],
                        bot_name=message['bot'],
                        password=message['parameters']['password'],
                        username=message['parameters']['username'],
                        server=message['parameters']['server']
                    )
                    self.logger.info('Created : ' + str(message['bot']))
                    message['success'] = True
                    message['details'] = {}
                    self.api.send_message(client, json.dumps(message))
                    return
                except Exception as e:
                    if e.args[0] == 'Bot already exists. Delete it using the \'delete_bot\' command first.':
                        self.logger.warn('Failed creating : ' + str(message['bot']))
                        message['success'] = False
                        message['details'] = {'reason': e.args[0]}
                        self.api.send_message(client, json.dumps(message))
                    else:
                        raise
                    return

            if 'command' in message.keys() and message['command'] == 'delete_bot':
                strategies.support_functions.delete_profile(message['bot'])
                message['success'] = True
                message['details'] = {}
                if message['bot'] in self.cartography.keys():
                    self.kill_commander(message['bot'])
                self.api.send_message(client, json.dumps(message))
                return

            if 'command' in message.keys() and message['command'] == 'login':
                if 'parameters' in message.keys() and 'token' in message['parameters'].keys():
                    valid_until = support_functions.token_is_authorized(message['parameters']['token'])
                    if valid_until:
                        for authorized_client, _ in self.cartography['authorized_clients']:
                            message['success'] = True
                            if client == authorized_client:
                                self.api.send_message(client, json.dumps(message))
                                return
                        self.cartography['authorized_clients'].append((client, valid_until))
                        message['success'] = True
                        self.api.send_message(client, json.dumps(message))
                        return
                    else:
                        message['success'] = False
                        self.api.send_message(client, json.dumps(message))
                return

            if 'command' in message.keys() and message['command'] == 'test':
                self.api.send_message(client, json.dumps({'success': True}))
                return

            if 'bot' in message.keys() and message['bot'] not in self.cartography.keys():
                self.logger.info('Bot is not running. Starting commander for {}'.format(message['bot']))
                try:
                    self.spawn_commander(json.loads(json.dumps(message['bot'])), client)
                except Exception as e:
                    if e.args[0] == 'Bot does not exist. Create a profile using the \'new_bot\' command first.':
                        message['report'] = {}
                        message['report']['success'] = False
                        message['report']['details'] = {'reason': e.args[0]}
                        self.api.send_message(client, json.dumps(message))
                    else:
                        raise
                    return

            if not intercept_command:
                self.logger.info('Adding strategy to {}: {}'.format(message['bot'], message))
                self.cartography[message['bot']]['strategies_queue'].put(message)

        except Exception:
            self.logger.warning('Received badly formatted strategy')
            self.logger.warning(traceback.format_exc())

    def reports_listener(self):
        while 1:
            try:
                report = self.report_queue.get()
                self.logger.info('New report from {}: {}'.format(report['bot'], report))
                if 'exception_notif' in report.keys():
                    # A component of a bot died, kill the rest of it
                    client = self.cartography[report['bot']]['client']
                    self.kill_commander(report['bot'])
                else:
                    # Business as usual
                    client = self.cartography['messages'].pop(report['id'])

                self.api.send_message(client, json.dumps(report))

            except BrokenPipeError:
                self.logger.warning('Client closed connection')
                self.logger.warning(traceback.format_exc())
            except Exception:
                self.logger.warning('Received badly formatted report')
                self.logger.warning(traceback.format_exc())

    def spawn_commander(self, bot_name, client):
        if bot_name in self.cartography.keys():
            raise Exception('{} is already used elsewhere'.format(bot_name))
        bot_profile = strategies.support_functions.get_profile(bot_name)
        self.cartography[bot_name] = {}
        self.cartography[bot_name].update({'strategies_queue': queue.Queue()})
        self.cartography[bot_name].update({'thread': Thread(target=Commander, args=(bot_profile, self.cartography[bot_name]['strategies_queue'], self.report_queue, self.assets))})
        self.cartography[bot_name]['thread'].start()
        self.cartography[bot_name]['client'] = client

    def kill_commander(self, bot_name):
        self.cartography[bot_name]['strategies_queue'].put({'stop': 'die'})
        del self.cartography[bot_name]
Exemple #19
0
class GUI:
    # Initialization function
    # The actual initialization
    def __init__(self, host, console, hal):
        t = threading.Thread(target=self.run_server)


        self.payload = {'image1': '', 'shape1': [], 'image2': '', 'shape2': [], 'text_buffer': '', 'point': '', 'matching': '', 'paint_matching':''}
        self.server = None
        self.client = None

        self.host = host

        # Image variables
        self.image1_to_be_shown = None
        self.image2_to_be_shown = None
        self.image_to_be_shown_updated = False
        self.image_show_lock = threading.Lock()

        self.acknowledge = False
        self.acknowledge_lock = threading.Lock()

        self.point_to_save = []
        self.point_to_send = []

        self.matching_to_save = []
        self.duplicate_matching = False
        self.matching_to_send = []
        self.paint_matching = False
        # Take the console object to set the same websocket and client
        self.console = console
        self.hal = hal
        t.start()


    # Explicit initialization function
    # Class method, so user can call it without instantiation
    @classmethod
    def initGUI(cls, host, console):
        # self.payload = {'image': '', 'shape': []}
        new_instance = cls(host, console)
        return new_instance

    # Function to prepare image payload
    # Encodes the image as a JSON string and sends through the WS
    def payloadImage(self):
        self.image_show_lock.acquire()
        image_to_be_shown_updated = self.image_to_be_shown_updated
        image1_to_be_shown = self.image1_to_be_shown
        image2_to_be_shown = self.image2_to_be_shown
        self.image_show_lock.release()

        image1 = image1_to_be_shown
        payload1 = {'image1': '', 'shape1': ''}
        image2 = image2_to_be_shown
        payload2 = {'image2': '', 'shape2': ''}

        if(image_to_be_shown_updated == False):
            return payload1,payload2

        shape1 = image1.shape
        image1 = cv2.cvtColor(image1, cv2.COLOR_RGB2BGR)
        frame1 = cv2.imencode('.JPEG', image1)[1]
        encoded_image1 = base64.b64encode(frame1)

        payload1['image1'] = encoded_image1.decode('utf-8')
        payload1['shape1'] = shape1

        shape2 = image2.shape
        image2 = cv2.cvtColor(image2, cv2.COLOR_RGB2BGR)
        frame2 = cv2.imencode('.JPEG', image2)[1]
        encoded_image2 = base64.b64encode(frame2)

        payload2['image2'] = encoded_image2.decode('utf-8')
        payload2['shape2'] = shape2

        self.image_show_lock.acquire()
        self.image_to_be_shown_updated = False
        self.image_show_lock.release()

        return payload1,payload2

    # Function for student to call
    def showImages(self, image1, image2, paint_matching):
        self.paint_matching = paint_matching
        if (np.all(self.image1_to_be_shown == image1) == False or np.all(self.image2_to_be_shown == image2) == False):
            self.image_show_lock.acquire()
            self.image1_to_be_shown = image1
            self.image2_to_be_shown = image2
            self.image_to_be_shown_updated = True
            self.image_show_lock.release()


    # Function to get the client
    # Called when a new client is received
    def get_client(self, client, server):
        self.client = client
        self.console.set_websocket(self.server, self.client)

    # Function to get value of Acknowledge
    def get_acknowledge(self):
        self.acknowledge_lock.acquire()
        acknowledge = self.acknowledge
        self.acknowledge_lock.release()

        return acknowledge

    # Function to get value of Acknowledge
    def get_frequency(self):
        frequency = self.time_frequency

        return frequency


    # Function to get value of Acknowledge
    def set_acknowledge(self, value):
        self.acknowledge_lock.acquire()
        self.acknowledge = value
        self.acknowledge_lock.release()

    # Update the gui
    def update_gui(self):
        # Payload Image Message
        payload1, payload2 = self.payloadImage()

        self.payload["image1"] = json.dumps(payload1)
        self.payload["image2"] = json.dumps(payload2)

        # Payload Point Message
        length_point_send = len(self.point_to_send)

        if (length_point_send != 0):
            if (length_point_send > 20):
                self.payload["point"] = json.dumps(self.point_to_send[0:20])
                del self.point_to_send[0:20]
            else:
                self.payload["point"] = json.dumps(self.point_to_send)
                del self.point_to_send[0:length_point_send]
        else:
            self.payload["point"] = json.dumps([])

        length_matching_send = len(self.matching_to_send)
        self.payload["matching"] = json.dumps(self.matching_to_send)
        del self.matching_to_send[0:length_matching_send]

        self.payload["paint_matching"] = self.paint_matching
        # Payload Console Messages
        message_buffer = self.console.get_text_to_be_displayed()
        self.payload["text_buffer"] = json.dumps(message_buffer)

        message = "#gui" + json.dumps(self.payload)
        self.server.send_message(self.client, message)

    # Function to read the message from websocket
    # Gets called when there is an incoming message from the client
    def get_message(self, client, server, message):
        # Acknowledge Message for GUI Thread
        if(message[:4] == "#ack"):
            self.set_acknowledge(True)

        # Message for Console
        elif(message[:4] == "#con"):
            self.console.prompt(message)

    # Activate the server
    def run_server(self):
        self.server = WebsocketServer(port=2303, host=self.host)
        self.server.set_fn_new_client(self.get_client)
        self.server.set_fn_message_received(self.get_message)
        self.server.run_forever()

    # Show new points
    def ShowNewPoints(self, points):
        duplicate_point = False
        for i in range(0, len(points)):
            for j in range (0, len(self.point_to_save)):
                if (self.point_to_save[j] == points[i]):
                    duplicate_point = True
            if (duplicate_point == False):
                self.point_to_save.append(points[i])
                self.point_to_send.append(points[i])
            else:
                duplicate_point = False

    # Show all points
    def ShowAllPoints(self, points):
        number_equal_points = 0
        for i in range(0, len(points)):
            for j in range (0, len(self.point_to_save)):
                if (self.point_to_save[j] == points[i]):
                    number_equal_points += 1

        if (number_equal_points != len(points)):
            self.ClearAllPoints()
            for i in range(0, len(points)):
                self.point_to_save.append(points[i])
                self.point_to_send.append(points[i])

    # Show image matching
    def showImageMatching(self, x1, y1, x2, y2):
        matching = [x1, y1, x2, y2]

        for i in range(0, len(self.matching_to_save)):
            if ((self.matching_to_save[i] == matching) == True):
                self.duplicate_matching = True


        if (self.duplicate_matching == False):
            self.matching_to_save.append(matching)
            self.matching_to_send.append(matching)
        else:
            self.duplicate_matching = False

    # Function to reset
    def ClearAllPoints(self):
        self.point_to_save =[]
        self.point_to_send = []
        self.matching_to_save = []
        self.matching_to_send = []
        self.server.send_message(self.client, "#res")
Exemple #20
0
class WSServer:
    def __init__(self, port=9007):
        self.port = port
        self.server = WebsocketServer(self.port, host='0.0.0.0')
        self.server.set_fn_new_client(self.on_connect)
        self.server.set_fn_message_received(self.on_msg)
        self.server.set_fn_client_left(self.on_disconnect)
        self.msg_lock = Lock()

    def ping(self):
        self.server.send_message_to_all(json.dumps({'action': 'ping'}))

        # pinging every 50 seconds to avoid disconnection
        t = Timer(50, self.ping)
        t.start()

    def on_connect(self, client, server):
        #server.send_message_to_all("Hey all, a new client has joined us")
        pass

    def on_disconnect(self, client, server):
        #server.send_message_to_all("Hey all, a new client has joined us")
        pass

    def on_msg(self, client, server, message):
        self.msg_lock.acquire()
        try:
            args = message.split(' ')
            command = args[0]
            args = args[1:]
            internal = 'internal_ws_' + command
            if hasattr(self, internal):
                getattr(self, internal)(client, *args)
            else:
                data = {'action': 'cmd', 'msg': 'not found'}
                self.server.send_message(client, json.dumps(data))
        except Exception as e:
            print("Error: ", e)

        connection.close()
        self.msg_lock.release()

    def run(self):
        self.ping()
        self.server.run_forever()

    def drop_seat(self, hold):
        session = hold.session
        layout = hold.layout

        row, col = hold.seat.split('-')
        data = {
            'action': 'drop',
            'session': session.id,
            'layout': layout.id,
            'row': row,
            'col': col,
        }

        hold.delete()

        confirmed = not session.is_seat_available(layout, row, col)
        if confirmed:
            data['action'] = 'confirm'

        self.server.send_message_to_all(json.dumps(data))

    def notify_confirmed(self):
        d = timezone.now()
        d = d - datetime.timedelta(seconds=80)
        holds = TicketSeatHold.objects.filter(date__gt=d, type="R")
        for h in holds:
            row, col = h.seat.split('-')
            data = {
                'action': 'confirm',
                'session': h.session.id,
                'layout': h.layout.id,
                'row': row,
                'col': col,
            }
            self.server.send_message_to_all(json.dumps(data))

    # Protocol definitions

    def internal_ws_autoseats(self, client, session, amount, user):
        session = Session.objects.get(id=session)
        seats = search_seats(session, int(amount))
        data = {
            'action': 'autoseat',
            'session': session.id,
            'seats': seats,
        }

        for s in seats:
            layout = SeatLayout.objects.get(id=s['layout'])
            seat = '{}-{}'.format(s['row'], s['col'])

            d2 = {
                'action': 'hold',
                'session': session.id,
                'layout': layout.id,
                'row': s['row'],
                'col': s['col'],
            }
            sh = TicketSeatHold(client=user,
                                layout=layout,
                                seat=seat,
                                session=session)
            sh.save()
            self.server.send_message_to_all(json.dumps(d2))

        if not seats:
            data['error'] = _('Not found contiguous seats, please, select manually using the green button')

        self.server.send_message(client, json.dumps(data))

    def internal_ws_get_events(self, client):
        events = serializers.serialize("json", Event.objects.all())
        self.server.send_message(client, events)

    def internal_ws_get_spaces(self, client, event):
        event = Event.objects.get(slug=event)
        spaces = serializers.serialize("json", event.spaces.all())
        self.server.send_message(client, spaces)

    def internal_ws_get_sessions(self, client, event, space):
        event = Event.objects.get(slug=event)
        space = event.spaces.get(slug=space)
        sessions = serializers.serialize("json", space.sessions.all())
        self.server.send_message(client, sessions)

    def internal_ws_hold_seat(self, client, session, layout, row, col, user):
        session = Session.objects.get(id=session)
        layout = SeatLayout.objects.get(id=layout)
        data = {
            'action': 'hold',
            'session': session.id,
            'layout': layout.id,
            'row': row,
            'col': col,
        }

        if not session.is_seat_holded(layout, row, col):
            seat = row + '-' + col
            sh = TicketSeatHold(client=user, layout=layout, seat=seat,
                                session=session)
            sh.save()
            self.server.send_message_to_all(json.dumps(data))
        else:
            data['action'] = 'holded'
            self.server.send_message(client, json.dumps(data))

    def internal_ws_drop_seat(self, client, session, layout, row, col, user):
        try:
            seat = row + '-' + col
            sh = TicketSeatHold.objects.get(client=user,
                                            type='H',
                                            layout=layout,
                                            seat=seat,
                                            session=session)
            self.drop_seat(sh)
        except:
            pass

    def internal_ws_add_ac(self, client, control, date, st):
        data = {
            'action': 'add_ac',
            'control': control,
            'date': date,
            'st': st,
        }
        log = LogAccessControl(access_control=AccessControl.objects.get(slug=control), status=st)
        log.save()
        self.server.send_message_to_all(json.dumps(data))

    def internal_ws_add_sale(self, client, window, date, payment, amount, price):
        data = {
            'action': 'add_sale',
            'window': window,
            'date': date,
            'payment': payment,
            'amount': amount,
            'price': price
        }
        self.server.send_message_to_all(json.dumps(data))

    def internal_ws_add_change(self, client, window, date, payment, amount, price):
        data = {
            'action': 'add_change',
            'window': window,
            'date': date,
            'payment': payment,
            'amount': amount,
            'price': price
        }
        self.server.send_message_to_all(json.dumps(data))
Exemple #21
0
class WebTunnel(threading.Thread):
    def __init__(self, controller, port):
        threading.Thread.__init__(self)

        self.port = port

        self.outboundPackets = {
            "SET_VALUE_BOUNDS": "svb",
            "FEEDBACK_VALUE": "fv"  #aka true value
        }

        self.inboundPackets = {"USER_VALUE": "uv"}

        self.positionSuffix = "0"
        self.maxVelocitySuffix = "1"
        self.stiffnessSuffix = "2"

        self.jointNoToWidgetPrefix = ["joint0_", "joint1_"]

        self.controller = controller
        self.queue = []

        self.server = WebsocketServer(self.port)

        self.server.set_fn_new_client(self.new_client)
        self.server.set_fn_client_left(self.client_left)
        self.server.set_fn_message_received(self.message_received)

        self.positionFeedback = {}
        self.stiffnessFeedback = {}

        self.positionBounds = {}
        self.stiffnessBounds = {}
        self.maxVelocityBounds = {}

    def run(self):
        print("Tunnel now running!")
        self.server.run_forever()

    def shutdown(self):
        print("Shutting down")
        try:
            self.server.shutdown()
        except:
            exit(1)

    # Called for every client connecting (after handshake)
    def new_client(self, client, server):
        print("New client connected and was given id %d" % client['id'])
        print("Filling in client with latest data")

        #send latest position bounds
        for k in self.positionBounds:
            self.server.send_message(
                client,
                self.getPositionBoundsPacket(k, str(self.positionBounds[k][0]),
                                             self.positionBounds[k][1]))

        #send latest position feedbacks
        for k in self.positionFeedback:
            self.server.send_message(
                client,
                self.getPositionFeedbackPacket(k, self.positionFeedback[k]))

        #send latest max velocity bounds
        for k in self.maxVelocityBounds:
            self.server.send_message(
                client,
                self.getMaxVelocityBoundsPacket(
                    k, str(self.maxVelocityBounds[k][0]),
                    self.maxVelocityBounds[k][1]))

        #send latest stiffness bounds
        for k in self.stiffnessBounds:
            self.server.send_message(
                client,
                self.getStiffnessBoundsPacket(k,
                                              str(self.stiffnessBounds[k][0]),
                                              self.stiffnessBounds[k][1]))

        #send latest applied force feedbacks
        #for k in self.stiffnessFeedback:
        #    self.server.send_message(client, self.getStiffnessFeedbackPacket(k,
        #    self.stiffnessFeedback[k]))

    def client_left(self, client, server):
        print("Client(%d) disconnected" % client['id'])

    def message_received(self, client, server, message):
        print("Client %d said: %s", client['id'], message)

        if '%' in message:
            tokens = message.split('%')
            if tokens[0] == self.inboundPackets['USER_VALUE']:
                if tokens[1] and tokens[2]:
                    jointType = tokens[1].split("_")
                    jointType = jointType[len(jointType) - 1]

                    jointPrefix = tokens[1].split("_")[0] + "_"
                    #jointNo = jointPrefix.split("joint")
                    #jointNo = jointNo[len(jointNo) - 1]

                    print "jointPrefix: " + jointPrefix + "\n"
                    print "joint type: " + jointType + "\n"

                    if jointPrefix in self.jointNoToWidgetPrefix:
                        index = self.jointNoToWidgetPrefix.index(jointPrefix)

                        if self.controller:
                            if jointType == self.positionSuffix:
                                self.controller.setPosition(index, tokens[2])
                            elif jointType == self.maxVelocitySuffix:
                                self.controller.setMaxVelocity(
                                    index, tokens[2])
                            elif jointType == self.stiffnessSuffix:
                                self.controller.setStiffness(index, tokens[2])
                        else:
                            print(
                                'Undefined controller -- tried calling setPosition('
                                + str(index) + ', ' + str(tokens[2]) + ')')
                    else:
                        print('Could not find target with prefix: ' +
                              jointPrefix)
                else:
                    print('Corrupt USER_VALUE packet')
            else:
                print('Unhandled packet: ' + tokens[0])
        elif message == 'PING':
            self.server.send_message_to_all('PONG')
        else:
            print('Invalid packet')

    def sendPositionBoundsPacket(self, no, lower, upper):
        self.server.send_message_to_all(
            self.getPositionBoundsPacket(no, lower, upper))
        self.positionBounds[no] = [lower, upper]

    def sendPositionFeedbackPacket(self, no, val):
        self.server.send_message_to_all(self.getPositionFeedbackPacket(
            no, val))
        self.positionFeedback[no] = val

    def sendStiffnessBoundsPacket(self, no, lower, upper):
        print "SENDING STIFFNESS BOUNDS: " + str(no) + " " + str(
            lower) + " " + str(upper)
        self.server.send_message_to_all(
            self.getStiffnessBoundsPacket(no, lower, upper))
        self.stiffnessBounds[no] = [lower, upper]

    def sendStiffnessFeedbackPacket(self, no, val):
        self.server.send_message_to_all(
            self.getStiffnessFeedbackPacket(no, val))
        self.stiffnessFeedback[no] = val

    def sendMaxVelocityBoundsPacket(self, no, lower, upper):
        self.server.send_message_to_all(
            self.getMaxVelocityBoundsPacket(no, lower, upper))
        self.maxVelocityBounds[no] = [lower, upper]

    def getPositionBoundsPacket(self, no, lower, upper):
        if self.jointNoToWidgetPrefix[no]:
            return (self.outboundPackets["SET_VALUE_BOUNDS"] + "%" +
                    self.jointNoToWidgetPrefix[no] + self.positionSuffix +
                    "%" + str(lower) + "%" + str(upper))
        else:
            print("Could not find widget prefix for no = " + no)
            return None

    def getStiffnessBoundsPacket(self, no, lower, upper):
        if self.jointNoToWidgetPrefix[no]:
            return (self.outboundPackets["SET_VALUE_BOUNDS"] + "%" +
                    self.jointNoToWidgetPrefix[no] + self.stiffnessSuffix +
                    "%" + str(lower) + "%" + str(upper))
        else:
            print("Could not find widget prefix for no = " + no)
            return None

    def getPositionFeedbackPacket(self, no, val):
        if self.jointNoToWidgetPrefix[no]:
            return (self.outboundPackets["FEEDBACK_VALUE"] + "%" +
                    self.jointNoToWidgetPrefix[no] + str(self.positionSuffix) +
                    "%" + str(val))
        else:
            print("Could not find widget prefix for no = " + no)
            return None

    def getStiffnessFeedbackPacket(self, no, val):
        if self.jointNoToWidgetPrefix[no]:
            return (self.outboundPackets["FEEDBACK_VALUE"] + "%" +
                    self.jointNoToWidgetPrefix[no] +
                    str(self.stiffnessSuffix) + "%" + str(val))
        else:
            print("Could not find widget prefix for no = " + no)
            return None

    def getMaxVelocityBoundsPacket(self, no, lower, upper):
        if self.jointNoToWidgetPrefix[no]:
            return (self.outboundPackets["SET_VALUE_BOUNDS"] + "%" +
                    self.jointNoToWidgetPrefix[no] + self.maxVelocitySuffix +
                    "%" + str(lower) + "%" + str(upper))
        else:
            print("Could not find widget prefix for no = " + no)
            return None
class Million:

    _port = 9001
    _server = None

    def __init__(self):
        self._server = WebsocketServer(self._port, "0.0.0.0")
        self._server.set_fn_new_client(self.new_client)  #用户加入
        self._server.set_fn_client_left(self.client_left)  #用户断开
        self._server.set_fn_message_received(self.message_received)  #接收消息
        self._server.run_forever()

    # 验证发送或接收到的数据包是否合法
    def verifyData(self, data, stype='receive'):
        if (type(data) is not dict):
            data = json.loads(data)
        if 'type' not in data:
            raise Exception('Data type error type:' + data['type'])

        if 'receive' == stype:
            if 'UUID' not in data:
                raise Exception('UUID can not empty {}'.format(data))
        return data

    # 向客户端发送
    def sendTo(self, clientId, data):
        try:
            data = self.verifyData(data, 'send')
        except Exception as e:
            return common.ex(e)

        # 全员发送
        if 'all' == clientId:
            # data['receiver'] = 'all'
            self._server.send_message_to_all(
                json.dumps(data, ensure_ascii=False))
        else:
            self._server.send_message(clientId,
                                      json.dumps(data, ensure_ascii=False))

        print("发送: {} to client {}".format(data, clientId))

    # 发送聊天消息
    def sendChat(self, fromName, toId, msg):
        return self.sendTo(toId, {
            'from': fromName,
            'type': 'chat',
            'msg': msg.strip()
        })

    # 当新的客户端连接时会提示
    # Called for every client connecting (after handshake)
    def new_client(self, client, server):
        print("New client connected and was given id {}".format(client['id']))
        # self.sendTo('all', {'type': 'newplayer', 'msg': '进入了房间'})

    # 当旧的客户端离开
    # Called for every client disconnecting
    def client_left(self, client, server):
        print("Client({}) disconnected".format(client['id']))

    # UUID: clientHandler
    _clients = {}

    # 接收客户端的信息。
    # Called when a client sends a message
    def message_received(self, client, server, data):
        try:
            data = self.verifyData(data)
        except Exception as e:
            return common.ex(e)
        print("Client({}) 接收: {}".format(client['id'], data))

        self._clients[data['UUID']] = client
        # data['_clientId'] = client
        name = data['type']
        try:
            getattr(self, name)(data)
        except AttributeError as e:
            return common.ex('接收消息处理失败', e)

    # 给客户端显示错误
    def errorShow(self, to, msg):
        self.sendTo(to, {'type': 'errorShow', 'msg': msg})
        return False

    # 用户信息
    _userList = {}

    # 新用户加入
    def newplayer(self, data):
        print('do newplayer')

        if not data['name'].strip():
            return self.errorShow(self._clients[data['UUID']], '名字不能为空')

        # 添加人员信息
        self._userList[data['UUID']] = {
            'UUID': data['UUID'],
            'name': data['name'],
            'jointime': int(time.time()),
            # 'joinip': data["ip"],
            # '_clientId': data["_clientId"],
        }

        # 发送消息
        self.sendChat('系统', 'all', '欢迎 {} 加入海岛争夺'.format(data['name']))

        return self.getMyInfo({"UUID": data['UUID']})

    # 获取用户信息
    def getMyInfo(self, data):
        print('do get my info')

        if data['UUID'] not in self._userList:
            print('notlogin')
            return self.sendTo(self._clients[data['UUID']], {
                'type': 'getMyInfo',
                'status': 'notlogin',
            })
        else:
            print('login')
            userInfo = self._userList[data['UUID']]
            return self.sendTo(self._clients[data['UUID']], {
                'type': 'getMyInfo',
                'status': 'success',
                'userInfo': userInfo
            })

    # 聊天
    def chat(self, data):
        print('do chat')
        self.sendChat(data['from'], data['to'], data['msg'])

    # 获取已创建房间列表
    def getRoomList(self, data, refresh=False):
        print('do get room list')
        # 还没有房间
        if len(self._roomList) <= 0:
            return False

        to = self._clients[data['UUID']]
        # 即刷新所有人的列表
        if True == refresh:
            to = 'all'

        self.sendTo(
            to, {
                'type': "getRoomList",
                'status': 'success',
                'roomList': self._roomList,
            })

    # 房间缓存
    _roomList = {}
    # 最后的 room
    _lastRoomId = 5000

    # 创建新房间
    def newRoom(self, data):
        print('do get newRoom')
        self._lastRoomId = self._lastRoomId + 1
        roomId = self._lastRoomId
        self._roomList[roomId] = {
            'roomId': roomId,
            'name': data['name'],
            'min_per': data['min_per'],
            'map_size': data['map_size'],
            'created_at': int(time.time()),
            'userList': [data['UUID']]
        }

        # 通知创建人创建成功
        self.sendTo(self._clients[data['UUID']], {
            'type': 'newRoom',
            'status': 'success',
            'roomId': roomId,
        })

        # 通知大厅 重新加载
        return self.getRoomList(data, True)

    # 加入一个房间
    def join2Room(self, data):
        print('do join to room')
        if data['roomId'] not in self._roomList:
            self.getRoomList(data)  # 刷新他的房间列表
            return common.ex('房间已被解散,请重新进入')

        self.sendTo(
            self._clients[data['UUID']], {
                'type': "getRoomList",
                'status': 'success',
                'roomInfo': self._roomList[data['roomId']],
            })
Exemple #23
0
class Environment:
    """
    Environment class is responsible for passing the actions to the game.
    It is also responsible for retrieving the game status and the reward.
    """
    actions = {Action.UP: 'UP', Action.FORWARD: 'FORTH', Action.DOWN: 'DOWN'}

    def __init__(self, host, port, debug=False):
        self.debug = debug
        self.queue = multiprocessing.Queue()
        self.game_client = None
        self.server = WebsocketServer(port, host=host)
        self.server.set_fn_new_client(self.new_client)
        self.server.set_fn_message_received(self.new_message)
        print("\nGame can be connected (press F5 in Browser)")
        thread = threading.Thread(target=self.server.run_forever)
        thread.daemon = True
        thread.start()

    def new_client(self, client, server):
        if self.debug: print("GameAgent: Game just connected")
        self.game_client = client
        self.server.send_message(self.game_client,
                                 "Connection to Game Agent Established")

    def new_message(self, client, server, message):
        if self.debug: print("GameAgent: Incoming data from game")
        data = json.loads(message)
        image, crashed = data['world'], data['crashed']

        # remove data-info at the beginning of the image
        image = re.sub('data:image/png;base64,', '', image)
        # convert image from base64 decoding to np array
        image = np.array(Image.open(BytesIO(base64.b64decode(image))))

        # cast to bool
        crashed = True if crashed in ['True', 'true'] else False

        self.queue.put((image, crashed))

    def start_game(self):
        """
        Starts the game and lets the TRex run for half a second and then returns the initial state.

        :return: the initial state of the game (np.array, reward, crashed).
        """
        # game can not be started as long as the browser is not ready
        while self.game_client is None:
            time.sleep(1)

        self.server.send_message(self.game_client, "START")
        time.sleep(4)
        return self.get_state(Action.FORWARD)

    def refresh_game(self):
        time.sleep(0.5)
        print("...refreshing game...")
        self.server.send_message(self.game_client, "REFRESH")
        time.sleep(1)

    def do_action(self, action):
        """
        Performs action and returns the updated status

        :param action:  Must come from the class Action.
                        The only allowed actions are Action.UP, Action.Down and Action.FORWARD.
        :return: return the image of the game after performing the action, the reward (after the action) and
                        whether the TRex crashed or not.
        """
        if action != Action.FORWARD:
            # noting needs to be send when the action is going forward
            self.server.send_message(self.game_client, self.actions[action])

        time.sleep(.05)
        return self.get_state(action)

    def get_state(self, action):
        self.server.send_message(self.game_client, "STATE")

        image, crashed = self.queue.get()

        if crashed:
            reward = -100.
        else:
            if action == Action.UP:
                reward = -5.
            elif action == Action.DOWN:
                reward = -3.
            else:
                reward = 1.

        return image, reward, crashed
 def on_get_batches(self, client, server: WebsocketServer):
     batches = self.database.get_batches()
     json_data = self.converter.batches_to_json(batches)
     server.send_message(client, 'res|batches|%s' % json_data)
 def on_get_paths_dta(self, client, server: WebsocketServer):
     paths = self.database.get_paths_dta()
     json_data = self.converter.paths_dta_to_json(paths)
     server.send_message(client, 'res|pathsDta|%s' % json_data)
Exemple #26
0
class DataDriver:
    # 客户端信息
    class ClientInfo:
        def __init__(self, client, address):
            # 客户端对象
            self.client = client
            # 客户端地址
            self.address = address
            # 客户端订阅主题
            self.topic = ''

    def __init__(self):
        # 本地ip地址
        self.__host = ''
        # 本地端口号
        self.__port = 0
        # 数据模式:sensor(传感类数据);event(事件类数据)
        self.__model = ''
        # websocket服务器对象
        self.__web_server = None
        # 客户端字典
        self.__client_dict = {}
        # 组装数据函数字典
        self.__package = {
            'sensor': self.__package_sensor_data,
            'event': self.__package_event_data
        }

    # 获取版本信息
    def get_version(self):
        return json.dumps({
            'code': 0,
            'data': {
                'version': driver_version,
                'name': driver_name,
                'desc': driver_desc
            }
        })

    # 设置基础配置
    def set_basic_config(self, cfg_name, cfg_msg):
        # 解析配置
        try:
            cfg = json.loads(cfg_msg, encoding='utf-8')
            self.__host, self.__port, self.__model = cfg['host'], cfg[
                'port'], cfg['model']
        except Exception as err:
            LOG.error('解析基础配置失败:%s' % (str(err), ))
            return RET_FAIL_PARAM
        # 校验配置
        if self.__model not in ('sensor', 'event'):
            LOG.error('校验基础配置失败:%s' % self.__model)
            return RET_FAIL_PARAM
        LOG.info('设置基础配置成功')
        return RET_OK

    # 设置运行时配置
    def set_run_config(self, cfg_name, cfg_msg):
        # 无运行时配置,直接返回
        return RET_OK

    # 初始化
    def init(self):
        try:
            # 启动WebSocket服务
            self.__web_server = WebsocketServer(self.__port, self.__host)
            # 注册回调函数
            self.__web_server.set_fn_new_client(self.__new_client)
            self.__web_server.set_fn_client_left(self.__client_left)
            self.__web_server.set_fn_message_received(self.__msg_receive)
            # 创建WebSocket服务线程
            t1 = threading.Thread(target=self.__web_server.run_forever)
            t1.start()
        except Exception as err:
            LOG.error('初始化失败:%s' % (str(err), ))
            return RET_FAIL_EXEC
        LOG.info('驱动初始化成功。创建websocket服务端:%s:%d' % (self.__host, self.__port))
        return RET_OK

    # 设置回调函数
    def set_fun(self, fun):
        # 无需回调,直接返回
        return RET_OK

    # 写入数据(对外发布数据)
    def write_data(self, data_info, data_list):
        try:
            # 解析data_info里的topic
            data_info = json.loads(data_info, encoding='utf-8')
            topic = data_info['topic']
            for info in self.__client_dict.values():
                if topic == info.topic:
                    self.__web_server.send_message(
                        info.client, self.__package_data(data_list))
        except Exception as err:
            LOG.error('发布数据失败:%s' % str(err))
            return RET_FAIL_EXEC
        return RET_OK

    # 启动运行
    def run(self):
        # 无需启动,直接返回
        return RET_OK

    # 停止运行
    def stop(self):
        # 无需停止,直接返回
        return RET_OK

    # 获取状态
    def get_state(self):
        state = 0x00000000
        return json.dumps({'code': 0, 'data': state})

    # ---------------------------------------内部实现---------------------------------------------
    # 新客户端连接
    def __new_client(self, client, server):
        if client:
            LOG.info("新的页面客户端连接: %d, %s" %
                     (client['id'], str(client['address'])))
            self.__client_dict[client['id']] = self.ClientInfo(
                client, client['address'])

    # 接收到页面请求
    def __msg_receive(self, client, server, message):
        if client:
            LOG.info("接收到页面%d请求:%s..." % (client['id'], message[:100]))
            try:
                msg_dict = json.loads(message)
                topic = msg_dict['topic']
                self.__client_dict[client['id']].topic = topic
            except Exception:
                server.send_message(client, 'pong')

    # 页面离开
    def __client_left(self, client, server):
        if client:
            LOG.info('页面断开连接:%d, %s' % (client['id'], str(client['address'])))
            if client['id'] in self.__client_dict:
                self.__client_dict.pop(client['id'])

    # 组装数据
    def __package_data(self, data_list):
        return self.__package[self.__model](data_list)

    # 组装传感类数据
    def __package_sensor_data(self, data_list):
        datas = []
        for data in data_list:
            datas.append(sensor2dict(data))
        return json.dumps(datas)

    def __package_event_data(self, data_list):
        datas = []
        for data in data_list:
            datas.append(event2dict(data))
        return json.dumps(datas)
Exemple #27
0
class WBmessenger(object):
    def __init__(self, viewerparent):
        self.parent = viewerparent
        self.ProcessMessage = self.parent.ProcessMessage
        self.websockport = self.parent.websockport
        self.sleeptime = self.parent.sleeptime
        self.mprint = self.parent.mprint
        self.parent.lastviewmtrx
        self.browserisopen = False
        self.msgqueue = []
        self.msgdelim = ":\n"
        self.ishandling = False
        self.websockclient = None
        self.isterminating = False
        self.was_disconnected = None
        self.mywebsock = None
        self.websockeventloop = None

    def Sleep(self, t):
        time.sleep(t)

    def OnWebsocketClientMessage(self, client, server, message):
        self.ProcessMessage(message)

    def StartWebsocket(self):
        self.server = WebsocketServer(self.websockport, host='127.0.0.1')
        if not self.server:
            raise Sorry("Could not connect to web browser")
        self.server.set_fn_new_client(self.OnConnectWebsocketClient)
        self.server.set_fn_client_left(self.OnDisconnectWebsocketClient)
        self.server.set_fn_message_received(self.OnWebsocketClientMessage)
        self.wst = threading.Thread(target=self.server.run_forever)
        self.wst.daemon = True
        self.wst.start()
        self.msgqueuethrd = threading.Thread(target=self.WebBrowserMsgQueue)
        self.msgqueuethrd.daemon = True
        self.msgqueuethrd.start()

    def StopWebsocket(self):
        try:
            if self.websockclient:  # might not have been created if program is closed before a data set is shown
                self.websockclient['handler'].send_text(u"", opcode=0x8)
        except Exception as e:
            self.mprint(to_str(e) + "\n" + traceback.format_exc(limit=10),
                        verbose=0)
        self.mprint("Shutting down Websocket listening thread", verbose=1)
        self.server.shutdown()
        self.parent.javascriptcleaned = True
        self.msgqueuethrd.join()
        self.mprint("Shutting down WebsocketServer", verbose=1)
        self.wst.join()
        self.isterminating = True

    def AddToBrowserMsgQueue(self, msgtype, msg=""):
        self.msgqueue.append((msgtype, msg))

    def WebBrowserMsgQueue(self):
        try:
            while True:
                nwait = 0.0
                time.sleep(self.sleeptime)
                if self.parent.javascriptcleaned:
                    self.mprint("Shutting down WebBrowser message queue",
                                verbose=1)
                    return
                if len(self.msgqueue):
                    pendingmessagetype, pendingmessage = self.msgqueue[0]
                    gotsent = self.send_msg_to_browser(pendingmessagetype,
                                                       pendingmessage)
                    while not self.browserisopen:  #self.websockclient:
                        time.sleep(self.sleeptime)
                        nwait += self.sleeptime
                        if nwait > self.parent.handshakewait or self.parent.javascriptcleaned or not self.viewerparams.scene_id is not None:
                            return
                    if gotsent:
                        self.msgqueue.remove(self.msgqueue[0])
                    #if self.was_disconnected:
                    #  nwait2 = 0.0
                    #  while nwait2 < self.parent.handshakewait:
                    #    nwait2 += self.sleeptime
                    #  self.ReloadNGL()


# if the html content is huge the browser will be unresponsive until it has finished
# reading the html content. This may crash this thread. So try restarting this thread until
# browser is ready
        except Exception as e:
            self.mprint( str(e) + ", Restarting WebBrowserMsgQueue\n" \
                                + traceback.format_exc(limit=10), verbose=2)
            self.websockclient = None
            self.WebBrowserMsgQueue()

    def OnConnectWebsocketClient(self, client, server):
        self.websockclient = client
        self.mprint("Browser connected:" + str(self.websockclient), verbose=1)
        if self.was_disconnected:
            self.was_disconnected = False
        if self.parent.lastviewmtrx and self.parent.viewerparams.scene_id is not None:
            self.parent.set_volatile_params()
            self.mprint("Reorienting client after refresh:" +
                        str(self.websockclient),
                        verbose=2)
            self.AddToBrowserMsgQueue("ReOrient", self.parent.lastviewmtrx)
        else:
            self.parent.SetAutoView()

    def OnDisconnectWebsocketClient(self, client, server):
        self.mprint("Browser disconnected:" + str(client), verbose=1)
        self.was_disconnected = True

    def send_msg_to_browser(self, msgtype, msg=""):
        message = u"" + msgtype + self.msgdelim + str(msg)
        if self.websockclient:
            nwait = 0.0
            while not ("Ready" in self.parent.lastmsg or "tooltip_id" in self.parent.lastmsg \
              or "CurrentViewOrientation" in self.parent.lastmsg or "AutoViewSet" in self.parent.lastmsg \
              or "ReOrient" in self.parent.lastmsg or "JavaScriptCleanUp" in self.parent.lastmsg or self.websockclient is None):
                time.sleep(self.sleeptime)
                nwait += self.sleeptime
                if nwait > 2.0 and self.browserisopen:
                    self.mprint("ERROR: No handshake from browser!", verbose=0)
                    self.mprint("failed sending " + msgtype, verbose=1)
                    self.mprint("Reopening webpage again", verbose=0)
                    break
        if self.browserisopen and self.websockclient is not None:
            try:
                self.server.send_message(self.websockclient, message)
                return True
            except Exception as e:
                self.mprint(str(e) + "\n" + traceback.format_exc(limit=10),
                            verbose=1)
                self.websockclient = None
                return False
        else:
            return self.parent.OpenBrowser()
Exemple #28
0
class hklview_3d:
    def __init__(self, *args, **kwds):
        self.settings = kwds.get("settings")
        self.miller_array = None
        self.d_min = None
        self.scene = None
        self.NGLscriptstr = ""
        self.cameratype = "orthographic"
        self.url = ""
        self.binarray = "Resolution"
        self.icolourcol = None
        self.iradiicol = None
        self.iarray = None
        self.isnewfile = False
        self.binvals = []
        self.workingbinvals = []
        self.proc_arrays = []
        self.otherscenes = []
        self.othermaxdata = []
        self.othermindata = []
        self.othermaxsigmas = []
        self.otherminsigmas = []
        self.sceneisdirty = False
        self.matchingarrayinfo = []
        self.match_valarrays = []
        self.binstrs = []
        self.mapcoef_fom_dict = {}
        self.verbose = True
        if kwds.has_key('verbose'):
            self.verbose = kwds['verbose']
        self.mprint = sys.stdout.write
        if kwds.has_key('mprint'):
            self.mprint = kwds['mprint']
        self.nbin = 0
        self.websockclient = None
        self.lastmsg = ""
        self.StartWebsocket()
        tempdir = tempfile.gettempdir()
        self.hklfname = os.path.join(tempdir, "hkl.htm")
        if os.path.isfile(self.hklfname):
            os.remove(self.hklfname)
        if kwds.has_key('htmlfname'):
            self.hklfname = kwds['htmlfname']
        self.hklfname = os.path.abspath(self.hklfname)
        self.jscriptfname = os.path.join(tempdir, "hkljstr.js")
        if os.path.isfile(self.jscriptfname):
            os.remove(self.jscriptfname)
        if kwds.has_key('jscriptfname'):
            self.jscriptfname = kwds['jscriptfname']
        self.mprint('Output will be written to \"%s\"\n' \
          'including reference to NGL JavaScript \"%s\"' %(self.hklfname, self.jscriptfname))
        self.hklhtml = r"""
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<html>
<head>
<meta charset="utf-8" />
</head>

<body>
<script src="%s" type="text/javascript"></script>

<script src="%s" type="text/javascript"></script>
    """
        self.htmldiv = """
<div id="viewport" style="width:100%; height:100%;"></div>

</body></html>

    """
        self.colourgradientvalues = []
        self.UseOSBrowser = True
        if kwds.has_key('UseOSBrowser'):
            self.UseOSBrowser = kwds['UseOSBrowser']
        self.viewmtrxelms = None
        self.pendingmessage = None

    def __exit__(self, exc_type, exc_value, traceback):
        # not called unless instantiated with a "with hklview_3d ... " statement
        self.server.shutdown()
        if os.path.isfile(self.hklfname):
            os.remove(self.hklfname)

    def set_miller_array(self, col, merge=None, details="", proc_arrays=[]):
        self.iarray = col
        if col:
            self.miller_array = proc_arrays[col]
        self.proc_arrays = proc_arrays
        self.merge = merge
        if (self.miller_array is None):
            return
        self.d_min = self.miller_array.d_min()
        array_info = self.miller_array.info()
        self.binvals = [
            1.0 / self.miller_array.d_max_min()[0],
            1.0 / self.miller_array.d_max_min()[1]
        ]
        #import code, traceback; code.interact(local=locals(), banner="".join( traceback.format_stack(limit=10) ) )
        uc = "a=%g b=%g c=%g angles=%g,%g,%g" % self.miller_array.unit_cell(
        ).parameters()
        self.mprint( "Data: %s %s, %d reflections in space group: %s, unit Cell: %s" \
          % (array_info.label_string(), details, self.miller_array.indices().size(), \
              self.miller_array.space_group_info(), uc) )
        #self.construct_reciprocal_space(merge=merge)

    def ExtendMillerArraysUnionHKLs(self):
        #import code, traceback; code.interact(local=locals(), banner="".join( traceback.format_stack(limit=10) ) )
        self.match_valarrays = []
        # loop over all miller arrays to find the subsets of hkls common between currently selected
        # miler array and the other arrays. hkls found in the currently selected miller array but
        # missing in the subsets are populated populated with NaN values
        # create miller indices being a superset of available indices in all arrays
        self.mprint("Gathering superset of miller indices")
        superset_array = self.proc_arrays[0]
        for i, validarray in enumerate(self.proc_arrays):
            if i == 0:
                continue
            # first match indices in currently selected miller array with indices in the other miller arrays
            matchindices = miller.match_indices(superset_array.indices(),
                                                validarray.indices())
            #print validarray.info().label_string()
            valarray = validarray.select(matchindices.pairs().column(1))
            #import code, traceback; code.interact(local=locals(), banner="".join( traceback.format_stack(limit=10) ) )
            if valarray.anomalous_flag(
            ) and not superset_array.anomalous_flag():
                # valarray gets its anomalous_flag from validarray. But it cannot have more HKLs than self.miller_array
                # so set its anomalous_flag to False if self.miller_array is not anomalous data
                valarray._anomalous_flag = False
            if not valarray.anomalous_flag() and superset_array.anomalous_flag(
            ):
                # temporarily expand other arrays to anomalous if self.miller_array is anomalous
                valarray = valarray.generate_bijvoet_mates()
            missing = superset_array.lone_set(valarray)
            # insert NAN values for reflections in self.miller_array not found in validarray
            valarray = display.ExtendMillerArray(valarray, missing.size(),
                                                 missing.indices())
            match_valindices = miller.match_indices(superset_array.indices(),
                                                    valarray.indices())
            #import code, traceback; code.interact(local=locals(), banner="".join( traceback.format_stack(limit=10) ) )
            match_valarray = valarray.select(
                match_valindices.pairs().column(1))
            match_valarray.sort(by_value="packed_indices")
            #match_valarray.set_info(validarray.info() )
            superset_array = match_valarray
            #print "supersetsize:", superset_array.size()
        # now extend each miller array to contain any missing indices from the superset miller array
        for i, validarray in enumerate(self.proc_arrays):
            # first match indices in currently selected miller array with indices in the other miller arrays
            matchindices = miller.match_indices(superset_array.indices(),
                                                validarray.indices())
            #print validarray.info().label_string()
            valarray = validarray.select(matchindices.pairs().column(1))
            #import code, traceback; code.interact(local=locals(), banner="".join( traceback.format_stack(limit=10) ) )
            if valarray.anomalous_flag(
            ) and not superset_array.anomalous_flag():
                # valarray gets its anomalous_flag from validarray. But it cannot have more HKLs than self.miller_array
                # so set its anomalous_flag to False if self.miller_array is not anomalous data
                valarray._anomalous_flag = False
            if not valarray.anomalous_flag() and superset_array.anomalous_flag(
            ):
                # temporarily expand other arrays to anomalous if self.miller_array is anomalous
                valarray = valarray.generate_bijvoet_mates()
            missing = superset_array.lone_set(valarray)
            # insert NAN values for reflections in self.miller_array not found in validarray
            valarray = display.ExtendMillerArray(valarray, missing.size(),
                                                 missing.indices())
            match_valindices = miller.match_indices(superset_array.indices(),
                                                    valarray.indices())
            #import code, traceback; code.interact(local=locals(), banner="".join( traceback.format_stack(limit=10) ) )
            match_valarray = valarray.select(
                match_valindices.pairs().column(1))
            match_valarray.sort(by_value="packed_indices")
            match_valarray.set_info(validarray.info())
            self.match_valarrays.append(match_valarray)

    def construct_reciprocal_space(self, merge=None):
        self.mprint("Constructing HKL scenes")
        #if len(self.match_valarrays)==0:
        #  self.ExtendMillerArraysUnionHKLs()
        self.miller_array = self.match_valarrays[self.iarray]
        if not self.sceneisdirty:
            return
        self.otherscenes = []
        self.othermaxdata = []
        self.othermindata = []
        self.othermaxsigmas = []
        self.otherminsigmas = []
        self.matchingarrayinfo = []
        #import code, traceback; code.interact(local=locals(), banner="".join( traceback.format_stack(limit=10) ) )
        foms_array = None
        if self.miller_array.is_complex_array():
            fomcolm = self.mapcoef_fom_dict.get(
                self.miller_array.info().label_string())
            if fomcolm:
                foms_array = self.proc_arrays[fomcolm].deep_copy()
        #self.scene = display.scene(miller_array=self.miller_array, merge=merge,
        # settings=self.settings, foms_array=foms_array)
        # compute scenes for each of the miller arrays
        for i, match_valarray in enumerate(self.match_valarrays):
            foms = None
            if match_valarray.is_complex_array():
                fomcolm = self.mapcoef_fom_dict.get(
                    match_valarray.info().label_string())
                #import code, traceback; code.interact(local=locals(), banner="".join( traceback.format_stack(limit=10) ) )
                if fomcolm:
                    foms = self.match_valarrays[fomcolm]
            #commonarray = match_valarray
            commonarray = match_valarray.common_set(
                self.proc_arrays[self.iarray])
            commonarray.set_info(match_valarray.info())
            if i == self.iradiicol or i == self.icolourcol or i == self.iarray:
                bfullprocess = True
            else:
                bfullprocess = False
            otherscene = display.scene(miller_array=commonarray,
                                       merge=merge,
                                       settings=self.settings,
                                       foms_array=foms,
                                       fullprocessarray=True)
            #import code, traceback; code.interact(local=locals(), banner="".join( traceback.format_stack(limit=10) ) )
            if not otherscene.SceneCreated:
                self.mprint("The " + commonarray.info().label_string() +
                            " array was not processed")
                continue
            #import code, traceback; code.interact(local=locals(), banner="".join( traceback.format_stack(limit=10) ) )
            # cast any NAN values to 1 of the colours and radii to 0.2 before writing javascript
            b = flex.bool([
                bool(math.isnan(e[0]) + math.isnan(e[1]) + math.isnan(e[2]))
                for e in otherscene.colors
            ])
            otherscene.colors = otherscene.colors.set_selected(
                b, (1.0, 1.0, 1.0))
            b = flex.bool([bool(math.isnan(e)) for e in otherscene.radii])
            otherscene.radii = otherscene.radii.set_selected(b, 0.2)
            self.otherscenes.append(otherscene)
            ainf = ArrayInfo(otherscene.work_array, self.mprint)
            self.othermaxdata.append(ainf.maxdata)
            self.othermindata.append(ainf.mindata)
            self.othermaxsigmas.append(ainf.maxsigmas)
            self.otherminsigmas.append(ainf.minsigmas)
            infostr = ainf.infostr
            self.mprint("%d, %s" % (i, infostr))
            self.matchingarrayinfo.append(infostr)
        #import code, traceback; code.interact(local=locals(), banner="".join( traceback.format_stack(limit=10) ) )
        self.sceneisdirty = False

    def update_settings(self, diffphil):
        if hasattr(diffphil, "filename"):
            self.ExtendMillerArraysUnionHKLs()
            self.sceneisdirty = True

        if hasattr(diffphil, "spacegroupchoice") or \
          hasattr(diffphil, "mergedata") or \
          hasattr(diffphil, "column") or \
          hasattr(diffphil, "fomcolumn") or \
          hasattr(diffphil, "viewer") and ( hasattr(diffphil.viewer, "show_anomalous_pairs") \
          or hasattr(diffphil.viewer, "show_data_over_sigma") \
          or hasattr(diffphil.viewer, "show_missing") \
          or hasattr(diffphil.viewer, "show_only_missing") \
          or hasattr(diffphil.viewer, "show_systematic_absences") \
          or hasattr(diffphil.viewer, "slice_axis") \
          or hasattr(diffphil.viewer, "slice_mode") \
          or hasattr(diffphil.viewer, "scale") \
          or hasattr(diffphil.viewer, "nth_power_scale_radii") \
          or hasattr(diffphil.viewer, "expand_anomalous") \
          or hasattr(diffphil.viewer, "expand_to_p1")
          ):
            self.sceneisdirty = True
        self.construct_reciprocal_space(merge=self.merge)
        if self.miller_array is None or self.iarray < 0:
            return
        self.scene = self.otherscenes[self.iarray]
        self.DrawNGLJavaScript()
        msg = "Rendered %d reflections\n" % self.scene.points.size()
        return msg

    def UpdateBinValues(self, binvals=[]):
        if binvals:
            self.binvals = binvals
        else:
            self.binvals = [
                1.0 / self.miller_array.d_max_min()[0],
                1.0 / self.miller_array.d_max_min()[1]
            ]

    def DrawNGLJavaScript(self):
        if self.miller_array is None:
            self.mprint("A miller array must be selected for drawing")
            return
        self.mprint("Composing NGL JavaScript...")
        h_axis = self.scene.axes[0]
        k_axis = self.scene.axes[1]
        l_axis = self.scene.axes[2]
        nrefls = self.scene.points.size()

        Hstararrowstart = roundoff(
            [-h_axis[0] * 100, -h_axis[1] * 100, -h_axis[2] * 100])
        Hstararrowend = roundoff(
            [h_axis[0] * 100, h_axis[1] * 100, h_axis[2] * 100])
        Hstararrowtxt = roundoff(
            [h_axis[0] * 102, h_axis[1] * 102, h_axis[2] * 102])
        Kstararrowstart = roundoff(
            [-k_axis[0] * 100, -k_axis[1] * 100, -k_axis[2] * 100])
        Kstararrowend = roundoff(
            [k_axis[0] * 100, k_axis[1] * 100, k_axis[2] * 100])
        Kstararrowtxt = roundoff(
            [k_axis[0] * 102, k_axis[1] * 102, k_axis[2] * 102])
        Lstararrowstart = roundoff(
            [-l_axis[0] * 100, -l_axis[1] * 100, -l_axis[2] * 100])
        Lstararrowend = roundoff(
            [l_axis[0] * 100, l_axis[1] * 100, l_axis[2] * 100])
        Lstararrowtxt = roundoff(
            [l_axis[0] * 102, l_axis[1] * 102, l_axis[2] * 102])
        # make arrow font size roughly proportional to radius of highest resolution shell
        fontsize = str(1.0 + roundoff(
            math.pow(max(self.miller_array.index_span().max()), 1.0 / 3.0)))

        arrowstr = """
    // xyz arrows
    shape.addSphere( [0,0,0] , [ 1, 1, 1 ], 0.3, 'Origo');
    //blue-x
    shape.addArrow( %s, %s , [ 0, 0, 1 ], 0.1);
    //green-y
    shape.addArrow( %s, %s , [ 0, 1, 0 ], 0.1);
    //red-z
    shape.addArrow( %s, %s , [ 1, 0, 0 ], 0.1);

    shape.addText( %s, [ 0, 0, 1 ], %s, 'h');
    shape.addText( %s, [ 0, 1, 0 ], %s, 'k');
    shape.addText( %s, [ 1, 0, 0 ], %s, 'l');
    """ % (str(Hstararrowstart), str(Hstararrowend), str(Kstararrowstart),
           str(Kstararrowend), str(Lstararrowstart), str(Lstararrowend),
           Hstararrowtxt, fontsize, Kstararrowtxt, fontsize, Lstararrowtxt,
           fontsize)

        # Make colour gradient array used for drawing a bar of colours next to associated values on the rendered html
        mincolourscalar = self.othermindata[self.icolourcol]
        maxcolourscalar = self.othermaxdata[self.icolourcol]
        if self.settings.sigma_color:
            mincolourscalar = self.otherminsigmas[self.icolourcol]
            maxcolourscalar = self.othermaxsigmas[self.icolourcol]
        span = maxcolourscalar - mincolourscalar
        ln = 60
        incr = span / ln
        colourgradarrays = []
        val = mincolourscalar
        colourscalararray = flex.double()
        colourscalararray.append(val)
        for j, sc in enumerate(range(ln)):
            val += incr
            colourscalararray.append(val)
        if self.otherscenes[self.icolourcol].miller_array.is_complex_array():
            # When displaying phases from map coefficients together with fom values
            # compute colour map chart as a function of fom and phase values (x,y axis)
            incr = 360.0 / ln
            val = 0.0
            colourscalararray = flex.double()
            colourscalararray.append(val)
            for j in enumerate(range(ln)):
                val += incr
                colourscalararray.append(val)

            fomarrays = []
            if self.otherscenes[self.icolourcol].isUsingFOMs():
                fomln = 50
                fom = 1.0
                fomdecr = 1.0 / (fomln - 1.0)
                # make fomln fom arrays of size len(colourscalararray) when calling colour_by_phi_FOM
                for j in range(fomln):
                    fomarrays.append(flex.double(len(colourscalararray), fom))
                    fom -= fomdecr
                for j in range(fomln):
                    colourgradarrays.append(
                        graphics_utils.colour_by_phi_FOM(
                            colourscalararray *
                            (math.pi / 180.0), fomarrays[j]) * 255.0)
            else:
                fomln = 1
                fomarrays = [1.0]
                colourgradarrays.append(
                    graphics_utils.colour_by_phi_FOM(colourscalararray *
                                                     (math.pi / 180.0)) *
                    255.0)
        else:
            fomln = 1
            fomarrays = [1.0]
            colourgradarrays.append(
                graphics_utils.color_by_property(
                    properties=flex.double(colourscalararray),
                    selection=flex.bool(len(colourscalararray), True),
                    color_all=False,
                    gradient_type=self.settings.color_scheme) * 255.0)

        colors = self.otherscenes[self.icolourcol].colors
        radii = self.otherscenes[self.iradiicol].radii
        points = self.scene.points
        hkls = self.scene.indices
        dres = self.scene.dres
        colstr = self.scene.miller_array.info().label_string()
        data = self.scene.data
        colourlabel = self.otherscenes[self.icolourcol].colourlabel
        fomlabel = self.otherscenes[self.icolourcol].fomlabel
        #import code, traceback; code.interact(local=locals(), banner="".join( traceback.format_stack(limit=10) ) )
        assert (colors.size() == radii.size() == nrefls)
        colours = []
        positions = []
        radii2 = []
        spbufttips = []

        self.workingbinvals = []
        if not self.binarray == "Resolution":
            ibinarray = int(self.binarray)
            self.workingbinvals = [
                self.othermindata[ibinarray] - 0.1,
                self.othermaxdata[ibinarray] + 0.1
            ]
            self.workingbinvals.extend(self.binvals)
            self.workingbinvals.sort()
            if self.workingbinvals[0] < 0.0:
                self.workingbinvals.append(0.0)
                self.workingbinvals.sort()
            bindata = self.otherscenes[ibinarray].data
            if self.otherscenes[ibinarray].work_array.is_complex_array():
                bindata = self.otherscenes[ibinarray].ampl
        else:
            self.workingbinvals = self.binvals
            colstr = "dres"
            bindata = 1.0 / dres
        self.nbin = len(self.workingbinvals)

        for ibin in range(self.nbin):
            colours.append([])  # colours and positions are 3 x size of data()
            positions.append([])
            radii2.append([])
            spbufttips.append([])

        def data2bin(d):
            for ibin, binval in enumerate(self.workingbinvals):
                if (ibin + 1) == self.nbin:
                    return ibin
                if d > binval and d <= self.workingbinvals[ibin + 1]:
                    return ibin
            #import code, traceback; code.interact(local=locals(), banner="".join( traceback.format_stack(limit=10) ) )
            raise Sorry("Should never get here")

        #import code, traceback; code.interact(local=locals(), banner="".join( traceback.format_stack(limit=10) ) )
        for i, hklstars in enumerate(points):
            # bin currently displayed data according to the values of another miller array
            ibin = data2bin(bindata[i])
            spbufttip = 'H,K,L: %s, %s, %s' % (hkls[i][0], hkls[i][1],
                                               hkls[i][2])
            spbufttip += '\ndres: %s ' % str(roundoff(dres[i]))
            spbufttip += '\' + AA + \''
            for j, otherscene in enumerate(self.otherscenes):
                ocolstr = self.proc_arrays[j].info().label_string()
                odata = otherscene.data
                od = ""
                if self.proc_arrays[j].is_complex_array():
                    if not math.isnan(otherscene.foms[i]):
                        od = str(roundoff(otherscene.ampl[i])) + ", " + str(roundoff(otherscene.phases[i])  ) + \
                          "\' + DGR + \'" +  ", " + str(roundoff(otherscene.foms[i])  )
                    else:
                        od = str(roundoff(otherscene.ampl[i])) + ", " + str(roundoff(otherscene.phases[i])  ) + \
                          "\' + DGR + \'"
                elif self.proc_arrays[j].sigmas() is not None:
                    od = str(roundoff(odata[i])) + ", " + str(
                        roundoff(otherscene.sigmas[i]))
                else:
                    od = str(roundoff(odata[i]))
                if not (math.isnan(abs(odata[i]))
                        or odata[i] == display.inanval):
                    spbufttip += "\n%s: %s" % (ocolstr, od)
            positions[ibin].extend(roundoff(list(hklstars)))
            colours[ibin].extend(roundoff(list(colors[i]), 2))
            radii2[ibin].append(roundoff(radii[i], 2))
            spbufttips[ibin].append(spbufttip)

        spherebufferstr = """
  ttips = new Array(%d)
  positions = new Array(%d)
  colours = new Array(%d)
  radii = new Array(%d)
  spherebufs = new Array(%d)
    """ % (self.nbin, self.nbin, self.nbin, self.nbin, self.nbin)

        negativeradiistr = ""
        cntbin = 0
        self.binstrs = []
        for ibin in range(self.nbin):
            mstr = ""
            nreflsinbin = len(radii2[ibin])
            if (ibin + 1) < self.nbin and nreflsinbin > 0:
                bin1 = self.workingbinvals[ibin]
                bin2 = self.workingbinvals[ibin + 1]
                if colstr == "dres":
                    bin1 = 1.0 / self.workingbinvals[ibin]
                    bin2 = 1.0 / self.workingbinvals[ibin + 1]
                mstr= "bin:%d, %d reflections with %s in ]%2.2f; %2.2f]" %(cntbin, nreflsinbin, \
                        colstr, bin1, bin2)
                self.binstrs.append(mstr)
                self.mprint(mstr, verbose=True)
                spherebufferstr += """
  // %s
  ttips[%d] = %s
  positions[%d] = new Float32Array( %s )
  colours[%d] = new Float32Array( %s )
  radii[%d] = new Float32Array( %s )
  spherebufs[%d] = new NGL.SphereBuffer({
    position: positions[%d],
    color: colours[%d],
    radius: radii[%d],
    picking: ttips[%d],
  })
  //}, { disableImpostor: true }) // if true allows wireframe spheres but does not allow resizing spheres

  shape.addBuffer(spherebufs[%d])
      """ %(mstr, cntbin, str(spbufttips[ibin]).replace('\"', '\''), \
                 cntbin, str(positions[ibin]), cntbin, str(colours[ibin]), \
                 cntbin, str(radii2[ibin]), cntbin, cntbin, cntbin, cntbin, cntbin, cntbin )

                if self.workingbinvals[ibin] < 0.0:
                    negativeradiistr += "spherebufs[%d].setParameters({metalness: 1})\n" % cntbin
                cntbin += 1

        spherebufferstr += """
// create tooltip element and add to the viewer canvas
  tooltip = document.createElement("div");
  Object.assign(tooltip.style, {
    display: "none",
    position: "absolute",
    zIndex: 10,
    pointerEvents: "none",
    backgroundColor: "rgba(255, 255, 255, 0.75)",
    color: "black",
    padding: "0.1em",
    fontFamily: "sans-serif"
  });

  stage.viewer.container.appendChild(tooltip);
  // listen to `hovered` signal to move tooltip around and change its text
  stage.signals.hovered.add(function (pickingProxy) {
    if (pickingProxy && (Object.prototype.toString.call(pickingProxy.picker) === '[object Array]'  )){
      var sphere = pickingProxy.sphere;
      var cp = pickingProxy.canvasPosition;
      tooltip.innerText = pickingProxy.picker[pickingProxy.pid];
      tooltip.style.bottom = cp.y + 7 + "px";
      tooltip.style.left = cp.x + 8 + "px";
      tooltip.style.fontSize = "smaller";
      tooltip.style.display = "block";
    }else{
      tooltip.style.display = "none";
    }
  });

  stage.signals.clicked.add(function (pickingProxy) {
  if (pickingProxy && (Object.prototype.toString.call(pickingProxy.picker) === '[object Array]'  )){
    var innerText = pickingProxy.picker[pickingProxy.pid];
    mysocket.send( innerText);
  }
  });

    """
        colourgradstrs = "colourgradvalarray = new Array(%s)\n" % fomln
        # if displaying phases from map coefficients together with fom values then
        for g, colourgradarray in enumerate(colourgradarrays):
            self.colourgradientvalues = []
            for j, e in enumerate(colourgradarray):
                self.colourgradientvalues.append([colourscalararray[j], e])
            self.colourgradientvalues = roundoff(self.colourgradientvalues)

            fom = fomarrays[g]
            colourgradstr = []
            for j, val in enumerate(self.colourgradientvalues):
                vstr = ""
                alpha = 1.0
                gradval = "rgba(%s, %s, %s, %s)" % (val[1][0], val[1][1],
                                                    val[1][2], alpha)
                if j % 10 == 0 or j == len(self.colourgradientvalues) - 1:
                    vstr = str(roundoff(val[0], 2))
                colourgradstr.append([vstr, gradval])

            colourgradstrs += "  colourgradvalarray[%s] = %s\n" % (
                g, str(colourgradstr))

        #negativeradiistr = ""
        #for ibin in range(self.nbin):
        #  if self.workingbinvals[ibin] < 0.0:
        #    negativeradiistr += "spherebufs[%d].setParameters({metalness: 1})\n" %ibin



        self.NGLscriptstr = """
// Microsoft Edge users follow instructions on
// https://stackoverflow.com/questions/31772564/websocket-to-localhost-not-working-on-microsoft-edge
// to enable websocket connection

var pagename = location.pathname.substring(1);
var mysocket = new WebSocket('ws://127.0.0.1:7894/');

mysocket.onopen = function (e) {
  mysocket.send('%s now connected via websocket to ' + pagename + '\\n');
};

mysocket.onclose = function (e) {
  mysocket.send('%s now disconnecting from websocket ' + pagename + '\\n');
};

// Log errors to debugger of your browser
mysocket.onerror = function (error) {
  console.log('WebSocket Error ' + error);
};


window.addEventListener( 'resize', function( event ){
    stage.handleResize();
}, false );




var stage;
var shape;
var shapeComp;
var repr;
var AA = String.fromCharCode(197); // short for angstrom
var DGR = String.fromCharCode(176); // short for degree symbol

function createElement (name, properties, style) {
// utility function used in for loop over colourgradvalarray
  var el = document.createElement(name)
  Object.assign(el, properties)
  Object.assign(el.style, style)
  Object.assign(el.style, {
      display: "block",
      position: "absolute",
      color: "black",
      fontFamily: "sans-serif",
      fontSize: "smaller",
    }
  )
  return el
}


function addElement (el) {
// utility function used in for loop over colourgradvalarray
  Object.assign(el.style, {
    position: "absolute",
    zIndex: 10
  })
  stage.viewer.container.appendChild(el)
}


function addDivBox(txt, t, l, w, h, bgcolour='rgba(255.0, 255.0, 255.0, 0.0)') {
  divbox = createElement("div",
  {
    innerText: txt
  },
  {
    backgroundColor: bgcolour,
    color:  'rgba(0.0, 0.0, 0.0, 1.0)',
    top: t.toString() + "px",
    left: l.toString() + "px",
    width: w.toString() + "px",
    height: h.toString() + "px",
  }
  );
  addElement(divbox)
}


var hklscene = function () {
  shape = new NGL.Shape('shape');
  stage = new NGL.Stage('viewport', { backgroundColor: "grey", tooltip:false,
                                      fogNear: 100, fogFar: 100 });
  stage.setParameters( { cameraType: "%s" } );

  %s

  %s

  shapeComp = stage.addComponentFromObject(shape);
  repr = shapeComp.addRepresentation('buffer');
  shapeComp.autoView();
  repr.update()

  // if some radii are negative draw them with wireframe
  %s

  //colourgradvalarrays
  %s

  var ih = 3;
  var topr = 35
  var topr2 = 10
  var lp = 10
  var wp = 40
  var lp2 = lp + wp
  var gl = 3
  var wp2 = gl
  var fomlabelheight = 25
  if (colourgradvalarray.length === 1) {
    wp2 = 15
    fomlabelheight = 0
  }

  var wp3 = wp + colourgradvalarray.length * wp2 + 2

  totalheight = ih*colourgradvalarray[0].length + 35 + fomlabelheight
  // make a white box on top of which boxes with transparent background are placed
  // containing the colour values at regular intervals as well as label legend of
  // the displayed miller array
  addDivBox("", topr2, lp, wp3, totalheight, 'rgba(255.0, 255.0, 255.0, 1.0)');

  // print label of the miller array used for colouring
  addDivBox("%s", topr2, lp, wp, 20);

  if (colourgradvalarray.length > 1) {
    // print FOM label, 1, 0.5 and 0.0 values below colour chart
    fomtop = topr2 + totalheight - 18
    fomlp = lp + wp
    fomwp = wp3
    fomtop2 = fomtop - 13
    // print the 1 number
    addDivBox("1", fomtop2, fomlp, fomwp, 20)
    // print the 0.5 number
    leftp = fomlp + 0.48 * gl * colourgradvalarray.length
    addDivBox("0.5", fomtop2, leftp, fomwp, 20)
    // print the FOM label
    addDivBox("%s", fomtop, leftp, fomwp, 20);
    // print the 0 number
    leftp = fomlp + 0.96 * gl * colourgradvalarray.length
    addDivBox("0", fomtop2, leftp, fomwp, 20)
  }

  for (j = 0; j < colourgradvalarray[0].length; j++) {
    rgbcol = colourgradvalarray[0][j][1];
    val = colourgradvalarray[0][j][0]
    topv = j*ih + topr
    toptxt = topv - 5
    // print value of miller array if present in colourgradvalarray[0][j][0]
    addDivBox(val, toptxt, lp, wp, ih);
  }

  // draw the colour gradient
  for (g = 0; g < colourgradvalarray.length; g++) {
    leftp = g*gl + lp + wp

    // if FOM values are supplied draw colour gradients with decreasing
    // saturation values as stored in the colourgradvalarray[g] arrays
    for (j = 0; j < colourgradvalarray[g].length; j++) {
      rgbcol = colourgradvalarray[g][j][1];
      val = colourgradvalarray[g][j][0]
      topv = j*ih + topr
      addDivBox("", topv, leftp, wp2, ih, rgbcol);
    }
  }

}

document.addEventListener('DOMContentLoaded', function() { hklscene() }, false );


mysocket.onmessage = function (e) {
  //alert('Server: ' + e.data);
  var c
  var alpha
  var si
  mysocket.send('got ' + e.data ); // tell server what it sent us
  try {
    val = e.data.split(",")

    if (val[0] === "alpha") {
      ibin = parseInt(val[1])
      alpha = parseFloat(val[2])
      spherebufs[ibin].setParameters({opacity: alpha})
      stage.viewer.requestRender()
    }

    if (val[0] === "colour") {
      ibin = parseInt(val[1])
      si =  parseInt(val[2])
      colours[ibin][3*si] = parseFloat(val[3])
      colours[ibin][3*si+1] = parseFloat(val[4])
      colours[ibin][3*si+2] = parseFloat(val[5])
      spherebufs[ibin].setAttributes({ color: colours[ibin] })
      stage.viewer.requestRender()
    }

    if (val[0] === "Redraw") {
      stage.viewer.requestRender()
    }

    if (val[0] === "ReOrient") {
      mysocket.send( 'Reorienting ' + pagename );
      sm = new Float32Array(16);
      for (j=0; j<16; j++)
        sm[j] = parseFloat(val[j + 2]) // first 2 are "ReOrient", "NGL\\n"

      var m = new NGL.Matrix4();
      m.fromArray(sm);
      stage.viewerControls.orient(m);
      stage.viewer.requestRender();
    }

    if (val[0] === "Reload") {
    // refresh browser with the javascript file
      cvorient = stage.viewerControls.getOrientation().elements
      msg = String(cvorient)
      mysocket.send('Current vieworientation:\\n, ' + msg );

      mysocket.send( 'Refreshing ' + pagename );
      window.location.reload(true);
    }

    if (val[0] === "Testing") {
      // test something new
      mysocket.send( 'Testing something new ' + pagename );
      var newradii = radii[0].map(function(element) {
        return element*1.5;
      });

      spherebufs[0].setAttributes({
          radius: newradii
        })
      stage.viewer.requestRender()
    }

  }
  catch(err) {
    mysocket.send('error: ' + err );
  }
};




    """ % (self.__module__, self.__module__, self.cameratype, arrowstr, spherebufferstr, \
                negativeradiistr, colourgradstrs, colourlabel, fomlabel)
        if self.jscriptfname:
            with open(self.jscriptfname, "w") as f:
                f.write(self.NGLscriptstr)
        self.ReloadNGL()

    def OnConnectWebsocketClient(self, client, server):
        #if not self.websockclient:
        self.websockclient = client
        self.mprint("Browser connected:" + str(self.websockclient),
                    self.verbose)
        #else:
        #  self.mprint( "Unexpected browser connection was rejected" )

    def OnWebsocketClientMessage(self, client, server, message):
        if message != "":
            self.mprint(message, verbose=False)
        self.lastmsg = message
        if "Current vieworientation:" in message:
            # The NGL.Matrix4 with the orientation is a list of floats.
            self.viewmtrxelms = message[message.find("\n"):]
            sleep(0.2)
            self.mprint("Reorienting client after refresh:" +
                        str(self.websockclient))
            if not self.isnewfile:
                self.pendingmessage = u"ReOrient, NGL" + self.viewmtrxelms
            self.isnewfile = False

    def WebBrowserMsgQueue(self):
        while True:
            sleep(1)
            if hasattr(self, "pendingmessage") and self.pendingmessage:
                self.SendWebSockMsg(self.pendingmessage)
                self.pendingmessage = None

    def StartWebsocket(self):
        self.server = WebsocketServer(7894, host='127.0.0.1')
        if not self.server:
            raise Sorry("Could not connect socket to web browser")
        self.server.set_fn_new_client(self.OnConnectWebsocketClient)
        self.server.set_fn_message_received(self.OnWebsocketClientMessage)
        self.wst = threading.Thread(target=self.server.run_forever)
        self.wst.daemon = True
        self.wst.start()
        self.msgqueuethrd = threading.Thread(target=self.WebBrowserMsgQueue)
        self.msgqueuethrd.daemon = True
        self.msgqueuethrd.start()

    def SendWebSockMsg(self, msg):
        #import code, traceback; code.interact(local=locals(), banner="".join( traceback.format_stack(limit=10) ) )
        #print "self.server.clients: ", self.server.clients
        #print "self.websockclient: ",
        if self.websockclient:
            while "Refreshing" in self.lastmsg:
                sleep(0.5)
                self.lastmsg = ""
            self.server.send_message(self.websockclient, msg)
        else:
            self.OpenBrowser()

    def SetOpacity(self, bin, alpha):
        if bin > self.nbin:
            self.mprint("There are only %d bins of data present" % self.nbin)
            return
        msg = u"alpha, %d, %f" % (bin, alpha)
        self.SendWebSockMsg(msg)

    def RedrawNGL(self):
        self.SendWebSockMsg(u"Redraw, NGL\n")

    def ReloadNGL(self):  # expensive as javascript may be several Mbytes large
        self.mprint("Rendering NGL JavaScript...")
        self.SendWebSockMsg(u"Reload, NGL\n")

    def OpenBrowser(self):
        NGLlibpath = libtbx.env.under_root(
            os.path.join("modules", "cctbx_project", "crys3d", "hklview",
                         "ngl.js"))
        htmlstr = self.hklhtml % (NGLlibpath, os.path.abspath(
            self.jscriptfname))
        htmlstr += self.htmldiv
        with open(self.hklfname, "w") as f:
            f.write(htmlstr)
        self.url = "file://" + os.path.abspath(self.hklfname)
        self.mprint(
            "Writing %s and connecting to its websocket client" %
            self.hklfname, self.verbose)
        if self.UseOSBrowser:
            webbrowser.open(self.url, new=1)
        self.isnewfile = False

    def TestNewFunction(self):
        self.SendWebSockMsg(u"Testing, NGL\n")
Exemple #29
0
class websocketserver:

    cameras = {}
    tags = {}
    users = {}
    calibration = {}

    port = 8001

    # Called for every client connecting (after handshake)
    def new_client_connection(self, client, server):
        print("New client connected and was given id %d" % client['id'] +
              " and  address " + str(client['address']))
        server.send_message(client, "Client connected succesfully")

    # Called for every client disconnecting
    def client_left(self, client, server):
        print("Client(%d) disconnected" % client['id'])
        # Remove client from its list
        # TODO better delete (remove points etc...)

        if (str(client['address']) in self.cameras):
            print "Camera disconnected : " + str(client['address'])
            del self.cameras[str(client['address'])]

        elif (str(client['address']) in self.users):
            # Remove Tag assignement because User left
            print "User disconnected : " + str(client['address'])
            self.users[str(client['address'])].removeTag()
            del self.users[str(client['address'])]

        elif (str(client['address']) in self.calibration):
            print "Calibration disconnected : " + str(client['address'])
            del self.calibration[str(client['address'])]

        elif (str(client['address']) in self.tags):
            print "Tag disconnected : " + str(client['address'])
            # Remove Tag assignement to User because Tag left AND kill 3D point
            for key in self.users:
                if self.users[key].tag == self.tags[str(client['address'])]:
                    self.users[key].removeTag()
            del self.tags[str(client['address'])]

    # Called when a client sends a message
    def message_received(self, client, server, message):
        self.parseMessage(client, message)

    def __init__(self, host='127.0.0.1'):
        self.server = WebsocketServer(self.port, host)
        self.server.set_fn_new_client(self.new_client_connection)
        self.server.set_fn_client_left(self.client_left)
        self.server.set_fn_message_received(self.message_received)
        self.server.run_forever()

    def parseMessage(self, client, message):
        """
        Check who is the message from to redirect it to User / Tag / Camera / Calibration
        or create a new instance of User / Tag / Camera / Calibration
        :param client:
        :param message:
        :return:
        """
        if self.cameras.has_key(str(client['address'])):
            #print "Message from Camera"
            self.cameras[str(client['address'])].push(message)
            # Update all cameras counters
            #Todo: Change this method for checking all cameras for lost point (auto check inside point2D ?)
            for key in self.cameras.keys():
                self.cameras[key].update()

        elif self.users.has_key(str(client['address'])):
            print "Message from User"

        elif self.tags.has_key(str(client['address'])):
            print "Message from Tag"

        elif self.calibration.has_key(str(client['address'])):
            self.calibration[str(client['address'])].push(message)
            print "Message from Calibration"

        # This message is coming from an unknown client
        else:
            if message.split("-")[0] == "camera":
                self.cameras[str(client['address'])] = Camera(
                    client,
                    message.split("-")[1])
                # Add Observers linking every user to every camera's update
                for key in self.users:
                    if isinstance(self.users[key], User):
                        self.cameras[str(
                            client['address'])].new2DPointNotifier.addObserver(
                                self.users[key].position.newPoint2DObserver)
                        self.cameras[str(
                            client['address']
                        )].point2DdeletedNotifier.addObserver(
                            self.users[key].position.point2DDeletedObserver)

            elif message.split("-")[0] == "tag":
                self.tags[str(client['address'])] = Tag(
                    self.server, client,
                    message.split("-")[1])
                for key in self.users:
                    if isinstance(self.users[key], User):
                        # Assign a Tag to User with no Tag
                        if self.users[key].tag == None:
                            self.users[key].setTag(self.tags[str(
                                client['address'])])

            elif message.split("-")[0] == "user":
                user = User(self.server, client, message.split("-")[1])
                self.users[str(client['address'])] = user
                # Add Observers linking every user to every camera's update
                for key in self.cameras:
                    if isinstance(self.cameras[key], Camera):
                        self.cameras[key].new2DPointNotifier.addObserver(
                            user.position.newPoint2DObserver)
                        self.cameras[key].point2DdeletedNotifier.addObserver(
                            user.position.point2DDeletedObserver)

                for key in self.tags:
                    if isinstance(self.tags[key], Tag):
                        # Assign a Tag to new User
                        if self.tags[key].isAssigned() == False:
                            user.setTag(self.tags[key])

            elif message == "calibration":
                if (len(self.tags) > 0):
                    self.calibration[str(client['address'])] = Calibration(
                        self.server, client, self.cameras,
                        self.tags.values()[0])
                else:
                    self.server.send_message(
                        client,
                        "Please connect a Tag first, and start Calibration again."
                    )
Exemple #30
0
class WUI():
    def __init__(self,
                 theme_path,
                 browser_path,
                 log_lv=logging.DEBUG,
                 exit_time=10,
                 host='0.0.0.0',
                 port=6688):

        logging.basicConfig(level=log_lv)
        self.port = port
        self.CREATE_NO_WINDOW = 0x08000000
        self.exit_time = exit_time
        self.theme_path = theme_path
        self.browser_path = browser_path

        self.User_List = []

        self.host = host

        self.init_stat = 0

        self.Recv_Message_Hook = list()
        self.Join_Hook = list()
        self.Leave_Hook = list()

        self.init_ws()

    def init_ws(self):
        self.ws = WebsocketServer(self.port, host=self.host)
        self.ws.set_fn_message_received(self.message_received)
        self.ws.set_fn_client_left(self.user_leave)
        self.ws.set_fn_new_client(self.user_join)

        t = Thread(target=self.Exit_Check)
        t.start()

    def Send_Order(self, client, order, detail):
        temp = dict()
        temp['order'] = order
        temp['detail'] = detail
        temp = json.dumps(temp)
        self.ws.send_message(client, temp)

    def Broadcast(self, order, detail):
        temp = dict()
        temp['order'] = order
        temp['detail'] = detail
        temp = json.dumps(temp)
        self.ws.send_message_to_all(temp)

    def Add_Recv_Msg_Hook(self, msg_txt, callback, send_msg_to_fn=1):
        self.Add_WS_Hook('rec', msg_txt, callback, send_msg_to_fn)

    def Add_Join_Hook(self, callback='', msg_txt='', send_msg_to_fn=1):
        self.Add_WS_Hook('join', msg_txt, callback, send_msg_to_fn)

    def Add_Leave_Hook(self, msg_txt, callback, send_msg_to_fn=1):
        self.Add_WS_Hook('leave', msg_txt, callback, send_msg_to_fn)

    def Add_WS_Hook(self, hook_type, msg_txt, callback, send_msg_to_fn=1):
        try:
            mb = dict()
            mb['txt'] = msg_txt
            mb['callback'] = callback
            mb['send_msg_to_fn'] = send_msg_to_fn

            if hook_type == 'rec':
                self.Recv_Message_Hook.append(mb)
            if hook_type == 'join':
                self.Join_Hook.append(mb)
            if hook_type == 'leave':
                self.Leave_Hook.append(mb)
        except:
            print("Add_Hook_Error:" + format(msg_txt))

    def Run_Hook(self, hook_type, client, message):
        hook_list = list()
        if hook_type == 'rec':
            hook_list = self.Recv_Message_Hook
        if hook_type == 'join':
            hook_list = self.Join_Hook
        if hook_type == 'leave':
            hook_list = self.Leave_Hook
        for mb in hook_list:
            try:
                if hook_type == 'rec':
                    if mb['send_msg_to_fn'] == 1:
                        try:
                            msg_o = json.loads(message)
                            order = msg_o['order']
                            detail = msg_o['detail']
                            if order == mb['txt']:
                                mb['callback'](client, detail)
                        except Exception as e:
                            print(e)
                            logging.info("Message:" + format(message) +
                                         "JSON_Decode_Error")
                    else:
                        if message == mb['txt']:
                            mb['callback']()
                else:

                    if mb['send_msg_to_fn'] == 1:
                        mb['callback'](client)
                    else:
                        mb['callback']()
            except:
                print('Hook_Error:' + mb)

    def message_received(self, client, server, message):
        logging.debug("WS_Rec_Msg:" + format(message))
        self.Run_Hook(hook_type='rec', client=client, message=message)

    def user_leave(self, client, server):
        uid = client['id']
        del self.User_List[self.User_List.index(uid)]

        self.Run_Hook(hook_type='leave', client=client, message='')

    def user_join(self, client, server):
        logging.debug("User_Join:" + format(client))
        uid = client['id']
        self.User_List.append(uid)
        self.Run_Hook(hook_type='join', client=client, message=client)

    def Start_WS(self, start_browser=1):
        logging.info("Start_WS_Server:" + self.host + ":" + format(self.port))
        t = Thread(target=self.ws.run_forever)
        t.start()
        if start_browser == 1:
            self.Start_Chrome()

    def Start_Chrome(self):
        chrome_path = 'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe'
        Self_chrome_path = self.browser_path

        if os.path.isfile(chrome_path) == True:
            order = [chrome_path, '%s', self.theme_path]
            subprocess.Popen(order)
        else:
            order = [Self_chrome_path, '%s', self.theme_path]
            subprocess.Popen(order)

    def Quit(self):
        pid = os.getpid()
        subprocess.Popen(args=['taskkill', '/f', '/PID',
                               str(pid)],
                         creationflags=self.CREATE_NO_WINDOW)

    def Exit_Check(self):
        zero_time = time.time()
        while 1:
            if len(self.User_List) != 0:
                zero_time = time.time()

            if zero_time != 0:
                af_time = time.time() - zero_time

                if af_time > self.exit_time:
                    self.Quit()

            time.sleep(0.3)
Exemple #31
0
class RosConsumer:
    # Initialization function
    # The actual initialization
    def __init__(self, host):
        t = threading.Thread(target=self.run_server)
        self.reload = False
        self.server = None
        self.client = None
        self.host = host
        t.start()

    # Explicit initialization functions
    # Class method, so user can call it without instantiation
    @classmethod
    def initWeb(cls, host):
        new_instance = cls(host)
        return new_instance

    # Gets called when there is an incoming message from the client
    def handle(self, client, server, message):

        if (message == "#pong"):
            self.server.send_message(self.client, "#ping")
            return

        try:
            # Once received turn the reload flag up and send it to execute_thread function
            message_array = np.fromstring(message, dtype=int, sep=',')
            message_array.resize(240, 320, 3)
            frame_int64 = message_array
            frame_bgr = np.uint8(frame_int64)
            self.frame_rgb = cv2.cvtColor(frame_bgr, cv2.COLOR_BGR2RGB)
            self.server.send_message(self.client, "#ack")
            self.reload = True
        except:
            pass

    # Function that gets called when the connected closes
    def getImage(self):
        return self.frame_rgb

    def connected(self, client, server):
        self.client = client

        # Initialize the ping message
        self.server.send_message(self.client, "#ping")

        print(client, 'connected')

    # Function that gets called when the connected closes
    def handle_close(self, client, server):
        print(client, 'closed')

    def run_server(self):
        self.server = WebsocketServer(port=60002, host=self.host)
        self.server.set_fn_new_client(self.connected)
        self.server.set_fn_client_left(self.handle_close)
        self.server.set_fn_message_received(self.handle)
        self.server.run_forever()

    def callback(self, data):

        # Used to convert between ROS and OpenCV images
        br = CvBridge()

        # Output debugging information to the terminal
        rospy.loginfo("receiving video frame")

        # Convert ROS Image message to OpenCV image
        current_frame = br.imgmsg_to_cv2(data)

        _, im_arr = cv2.imencode(
            '.jpg',
            current_frame)  # im_arr: image in Numpy one-dim array format.
        im_bytes = im_arr.tobytes()
        im_b64 = base64.b64encode(im_bytes)

        try:
            self.server.send_message(self.client, im_b64)
        except:
            pass

    def receive_message(self):

        # Tells rospy the name of the node.
        # Anonymous = True makes sure the node has a unique name. Random
        # numbers are added to the end of the name.
        rospy.init_node('video_sub_py', anonymous=True)

        # Node is subscribing to the video_frames topic
        rospy.Subscriber('video_frames', Image, self.callback)

        # spin() simply keeps python from exiting until this node is stopped
        rospy.spin()
Exemple #32
0
class IgorServer:
    def __init__(self, api=None, config=CONFIG):
        """
        :param api: api dictionary containing handler functions
        :param config: config object
        """
        if not isinstance(api, dict):
            raise Exception("API config object must be dictionary object")
        else:
            self.paths = api

        self.config = config
        self.file_server_threat = None
        self.streams = {}
        self.clients = {}
        self.timeouts = {}
        self.sessions = {}
        self.processes = {}
        self.scope = {}
        self.loop = asyncio.get_event_loop()

        self.server = WebsocketServer(config['port'],
                                      host=config['host'],
                                      loglevel=config['logging']['level'])
        self.server.set_fn_new_client(self.__register_new_client)
        self.server.set_fn_client_left(self.__unregister_client)
        self.server.set_fn_message_received(self.__main_handler)

        self.session_delete_timeout = 10.0

        self.logger = None
        self.__configure(config)

    def __configure(self, config):
        if config['file_server_config']['enable']:
            self.file_server_threat = run_file_server(
                config['file_server_config']['port'],
                config['file_server_config']['root_directory'])
        logger = logging.getLogger(__name__)
        log_handler = None
        if config['logging']['file_name']:
            log_handler = logging.FileHandler(config['logging']['file_name'])
        else:
            log_handler = logging.StreamHandler()
        log_handler.setFormatter(
            logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
        logger.addHandler(log_handler)
        logger.setLevel(level=config['logging']['level'])
        self.logger = logger

    def run_forever(self):
        self.logger.debug("Starting server")
        for process_id, process in self.processes.items():
            thread = process['thread']
            thread.daemon = True
            print('Starting thread')
            thread.start()
        self.server.run_forever()

    def __register_new_client(self, client, server):
        if client.get('id', None) is None:
            raise Exception('Trying to register client without id')
        if self.clients.get(client['id'], None) is not None:
            raise Exception('Client with id: "' + client['id'] +
                            '" already connected')
        self.logger.debug('New client: "' + str(client['id']) + '" registered')
        self.clients[client['id']] = client
        self.sessions[client['id']] = {}

    def __unregister_client(self, client, server):
        self.logger.debug('Client: "' + str(client['id']) + '" unregistered')
        del self.clients[client['id']]

        def delete_session(client_id, igor_server):
            _client = igor_server.clients.get(client_id, None)
            if _client is None:
                del self.sessions[client_id]

        timeout = Timer(self.session_delete_timeout, delete_session,
                        [client['id'], self])
        self.timeouts[client['id']] = timeout
        timeout.start()

    def __add_new_stream(self, stream_id, client):
        self.logger.debug('Stream added')
        stream = Stream(self, client, stream_id, self.__remove_stream)
        self.streams[stream_id] = stream
        return stream

    def __remove_stream(self, real_self, stream_id):
        self.logger.debug('Stream removed')
        del real_self.streams[stream_id]

    def add_process(self, process_id, thread):
        """
        Adds new process to server - it won't be started immediately, to start it run: run_forever method

        :process_id: id of the process
        :thread: thread object of the process
        """
        output = ProcessOutput(process_id, self,
                               self._IgorServer__remove_process)
        thread.process_id = process_id
        thread.output = output
        thread.scope = self.scope
        thread.sessions = self.sessions
        self.processes[process_id] = {'thread': thread, 'output': output}

    def __remove_process(self, real_self, process_id):
        self.logger.debug('Process with id: "' + process_id +
                          '" finished and is removed')
        real_self.processes[process_id]['thread'].kill()
        del real_self.processes[process_id]

    def __send_erorr(self, client, message, code=500):
        self.logger.error(message)
        self.server.send_message(client,
                                 json.dumps({
                                     'error': message,
                                     'code': code
                                 }))

    def __introduce_self(self, client, stream_data):
        client_id = stream_data.get('client_id', None)
        if client_id is None:
            self.__send_erorr(client,
                              'No client_id for introduce_self action',
                              code=400)
            return
        else:
            client_session = self.sessions.get(client_id, None)
            if client_session is not None:
                timeout = self.timeouts.get(client['id'], None)
                if timeout is not None:
                    timeout.cancel()
            else:
                client_session = self.sessions[client['id']]
            del self.sessions[client['id']]
            del self.clients[client['id']]
            self.clients[stream_data['client_id']] = client
            self.sessions[stream_data['client_id']] = client_session
            client['id'] = stream_data['client_id']

    def __main_handler(self, client, server, message):
        try:
            message = json.loads(message)
            stream_id = message.get('streamId', None)

            if stream_id is None:
                self.__send_erorr(client, 'No streamId specified', code=400)
            else:
                stream_data = message.get('data', None)
                action = message.get('action', None)
                if action is None:
                    self.__send_erorr(client, 'No action specified', code=400)
                    return
                if action == 'introduce_self':
                    self.__introduce_self(client, stream_data)
                    return
                handler_function = self.paths.get(action, None)
                if handler_function is None:
                    self.__send_erorr(client,
                                      'No handler for action: "' + action +
                                      '"',
                                      code=400)
                    return
                stream = self.streams.get(stream_id, None)
                if stream is None:
                    stream = self.__add_new_stream(stream_id, client)
                session = self.sessions.get(client['id'], None)

                self.loop.run_until_complete(
                    handler_wrapper(handler_function, stream, stream_data,
                                    session, self.scope))
        except SystemExit:
            loggself.loggering.debug('System exit exception shutting down')
            if self.file_server_threat is not None:
                self.file_server_threat.kill()
            _thread.interrupt_main()

        except Exception as error:
            self.logger.error(str(error))
            self.__send_erorr(client,
                              'Undefined error occured while handling message',
                              code=503)
            raise error
Exemple #33
0
class websocket_server_impl(server_parent):
    def __init__(self, port, name):
        super().__init__(name)

        self.server = WebsocketServer(port)
        self.server.set_fn_client_left(self.client_left)
        self.server.set_fn_message_received(self.get_message)
        self.server.run_forever()

    def get_message(self, client, server, message):
        """
        get message in some way,child need implement it
        """
        # client = args[0]
        # server = args[1]
        # message = args[2]
        self.filter(json.loads(message), client)

    def login(self, data: dict, *args, **kwargs):
        """
        when a client send login to server,check client and name
        :param data : {
            CODE: LOGIN,
            LOGIN_ID: id,
            INFO :{
                LOGIN_NAME: name
            }
            TIMESTAMP: int(time.time() / 1000)
        }
        :return:
        """
        # load data from info
        client = args[0][0]
        id = data[LOGIN_ID]
        name = data[INFO][LOGIN_NAME]

        # if id exist,it means client want to login again and get its data before.
        # TODO password is nessary
        if id != None and id in self.user_dict:
            # switch to login
            self.user_dict[id].switch_type_login()
            # set client
            self.user_dict[id].set_client(client)
            # send response to client
            self.send_to_client(
                id,
                generate_json.generate_login_response(
                    self.user_dict[id].get_user_id(),
                    self.user_dict[id].get_name()))
        # if not exist,give it a new one
        else:
            # new websocket user
            user = websocket_user_impl(id, name)
            # set client
            user.set_client(client)
            # input to user
            id, name = self.input_user(user)
            # send to client
            self.send_to_client(
                id, generate_json.generate_login_response(id, name))

    def client_left(self, client, server):
        """
        when clinet left there are two situation
        1.left natural, server need delete its data
        2.left by unknown problem, server need keep its data
        :param client: the client which left
        :param server: self.server
        :return:
        """
        # TODO  rewrite
        # close connection
        # id = self.get_number_by_client(client)
        if id != -1:
            self.close_client(id)
            print(f"client:{id} close")

        # charge if it is left natural
        room_number = self.get_room_by_number(id)
        if room_number == -1 and id != -1:
            self.delete_client(id)
            print(f"client:{id} delete")

    def send_to_client(self, user_id: str, msg: str):
        """
        :param user_id: user's id
        :param msg: message
        :return:
        """
        self.server.send_message(self.user_dict[user_id].get_client(), msg)
class websocketserver:

    cameras = {}
    tags = {}
    users = {}
    calibration = {}

    port=8001

    # Called for every client connecting (after handshake)
    def new_client_connection(self, client, server):
        print("New client connected and was given id %d" %  client['id'] +" and  address " + str(client['address']))
        server.send_message(client, "Client connected succesfully")


    # Called for every client disconnecting
    def client_left(self, client, server):
        print("Client(%d) disconnected" % client['id'])
        # Remove client from its list
        # TODO better delete (remove points etc...)

        if(str(client['address']) in self.cameras):
            print "Camera disconnected : " + str(client['address'])
            del self.cameras[str(client['address'])]

        elif(str(client['address']) in self.users):
            # Remove Tag assignement because User left
            print "User disconnected : " + str(client['address'])
            self.users[str(client['address'])].removeTag()
            del self.users[str(client['address'])]

        elif(str(client['address']) in self.calibration):
            print "Calibration disconnected : " + str(client['address'])
            del self.calibration[str(client['address'])]

        elif(str(client['address']) in self.tags):
            print "Tag disconnected : " + str(client['address'])
            # Remove Tag assignement to User because Tag left AND kill 3D point
            for key in self.users:
                if self.users[key].tag == self.tags[str(client['address'])]:
                    self.users[key].removeTag()
            del self.tags[str(client['address'])]


    # Called when a client sends a message
    def message_received(self, client, server, message):
        self.parseMessage(client, message)

    def __init__(self, host='127.0.0.1'):
        self.server = WebsocketServer(self.port, host)
        self.server.set_fn_new_client(self.new_client_connection)
        self.server.set_fn_client_left(self.client_left)
        self.server.set_fn_message_received(self.message_received)
        self.server.run_forever()


    def parseMessage(self, client, message):
        """
        Check who is the message from to redirect it to User / Tag / Camera / Calibration
        or create a new instance of User / Tag / Camera / Calibration
        :param client:
        :param message:
        :return:
        """
        if self.cameras.has_key(str(client['address'])):
            #print "Message from Camera"
            self.cameras[str(client['address'])].push(message)
            # Update all cameras counters
            #Todo: Change this method for checking all cameras for lost point (auto check inside point2D ?)
            for key in self.cameras.keys():
                self.cameras[key].update()

        elif self.users.has_key(str(client['address'])):
            print "Message from User"

        elif self.tags.has_key(str(client['address'])):
            print "Message from Tag"

        elif self.calibration.has_key(str(client['address'])):
            self.calibration[str(client['address'])].push(message)
            print "Message from Calibration"

        # This message is coming from an unknown client
        else:
            if message.split("-")[0] == "camera":
                self.cameras[str(client['address'])] = Camera(client, message.split("-")[1])
                # Add Observers linking every user to every camera's update
                for key in self.users:
                    if isinstance(self.users[key], User):
                        self.cameras[str(client['address'])].new2DPointNotifier.addObserver(self.users[key].position.newPoint2DObserver)
                        self.cameras[str(client['address'])].point2DdeletedNotifier.addObserver(self.users[key].position.point2DDeletedObserver)

            elif message.split("-")[0] == "tag":
                self.tags[str(client['address'])] = Tag(self.server, client, message.split("-")[1])
                for key in self.users:
                    if isinstance(self.users[key], User):
                        # Assign a Tag to User with no Tag
                        if self.users[key].tag == None:
                            self.users[key].setTag(self.tags[str(client['address'])])

            elif message.split("-")[0] == "user":
                user = User(self.server, client, message.split("-")[1])
                self.users[str(client['address'])] = user
                # Add Observers linking every user to every camera's update
                for key in self.cameras:
                    if isinstance(self.cameras[key], Camera):
                        self.cameras[key].new2DPointNotifier.addObserver(user.position.newPoint2DObserver)
                        self.cameras[key].point2DdeletedNotifier.addObserver(user.position.point2DDeletedObserver)

                for key in self.tags:
                    if isinstance(self.tags[key], Tag):
                        # Assign a Tag to new User
                        if self.tags[key].isAssigned() == False:
                            user.setTag(self.tags[key])

            elif message == "calibration":
                if(len(self.tags)>0):
                    self.calibration[str(client['address'])] = Calibration(self.server, client, self.cameras, self.tags.values()[0])
                else:
                    self.server.send_message(client, "Please connect a Tag first, and start Calibration again.")