示例#1
0
class Network():
    def __init__(self):
        self.node = Pyre("GAME_NODE")
        self.node.set_header("HELLO", "ABC")
        self.node.start()
        self.node.join("world:position")
        self.node.join("world:combat")

        self.poller = zmq.Poller()
        self.poller.register(self.node.socket(), zmq.POLLIN)

    def poll(self):
        return dict(self.poller.poll(0))

    def peers(self):
        return self.node.peers()

    def stop(self):
        self.node.stop()

    def get_events(self):
        changes = self.poll()
        if self.node.socket() in changes and changes[
                self.node.socket()] == zmq.POLLIN:
            events = self.node.recent_events()
            return events
示例#2
0
class Network():
    def __init__(self):
        self.node = Pyre("GAME_NODE")
        self.node.set_header("AUTHORITY", "FALSE")
        self.node.set_header("NAME", "")
        self.node.start()
        self.node.join("world:position")
        self.node.join("world:combat")
        self.node.join("ctf:teams")
        self.node.join("ctf:dropflag")
        self.node.join("ctf:gotflag")
        self.node.join("players:whois")
        self.node.join("player:name")
        self.node.join("ctf:scores")
        self.node.join("ctf:status")

        self.poller = zmq.Poller()
        self.poller.register(self.node.socket(), zmq.POLLIN)

    def poll(self):
        return dict(self.poller.poll(0))

    def peers(self):
        return self.node.peers()

    def stop(self):
        self.node.stop()

    def get_events(self):
        changes = self.poll()
        if self.node.socket() in changes and changes[self.node.socket()] == zmq.POLLIN:
            events = self.node.recent_events()
            return events
示例#3
0
def peer(rolename, partnum):
    peername = "%s-%02d" % (rolename, partnum)
    portnum = 5670 + partnum  # fixme: risking collission!
    print(peername)
    ret = Pyre(peername)
    ret.set_port(bytes(str(portnum).encode("ascii")))
    ret.set_header("role", rolename)
    return ret
示例#4
0
        def setup_group_member():
            group_member = Pyre(self.name)
            # set headers
            for header in self.default_headers:
                group_member.set_header(*header)
            # join active group
            group_member.join(self.active_group)

            # start group_member
            group_member.start()
            return group_member
示例#5
0
        def setup_group_member():
            group_member = Pyre(self.name)
            # set headers
            for header in self.default_headers:
                group_member.set_header(*header)
            # join active group
            group_member.join(self.active_group)

            # start group_member
            group_member.start()
            return group_member
示例#6
0
    def discovery_task(self, ctx, pipe):
        self.log.debug("Pyre on iface : {}".format(self.iface))

        n = Pyre(self.groupName, sel_iface=self.iface)
        n.set_header("DISCOVERY_Header1", "DISCOVERY_HEADER")
        n.join(self.groupName)
        n.start()

        poller = zmq.Poller()
        poller.register(pipe, zmq.POLLIN)
        poller.register(n.inbox, zmq.POLLIN)

        while (True):
            items = dict(poller.poll())

            if pipe in items and items[pipe] == zmq.POLLIN:
                message = pipe.recv()
                # message to quit
                if message.decode('utf-8') == "$$STOP":
                    break

            if n.inbox in items and items[n.inbox] == zmq.POLLIN:
                cmds = n.recv()
                self.log.debug("NODE_MSG CONT:{}".format(cmds))

                msg_type = cmds.pop(0)
                peer_uuid_bytes = cmds.pop(0)
                peer_uuid = uuid.UUID(bytes=peer_uuid_bytes)

                self.log.debug("NODE_MSG TYPE: {}".format(msg_type))
                self.log.debug("NODE_MSG PEER: {}".format(peer_uuid))

                if msg_type.decode('utf-8') == "SHOUT":
                    group_name = cmds.pop(0)
                    self.log.debug("NODE_MSG GROUP: {}".format(group_name))

                    group_name_2 = cmds.pop(0)
                    self.log.debug("NODE_MSG GROUP_2: {}".format(group_name_2))

                    discoveryMsg = cmds.pop(0)
                    self.log.debug("Discovery Msg : {}".format(discoveryMsg))

                    controller = json.loads(discoveryMsg.decode('utf-8'))
                    self.controller_dl = str(controller["downlink"])
                    self.controller_ul = str(controller["uplink"])
                    self.log.debug("Discovered Controller DL-{}, UL-{}".format(
                        self.controller_dl, self.controller_ul))
                    self.send_event(
                        events.BrokerDiscoveredEvent(self.controller_dl,
                                                     self.controller_ul))

        n.stop()
    def discovery_task(self, ctx, pipe):
        self.log.debug("Pyre on iface : {}".format(self.iface))

        n = Pyre(self.groupName, sel_iface=self.iface)
        n.set_header("DISCOVERY_Header1","DISCOVERY_HEADER")
        n.join(self.groupName)
        n.start()

        poller = zmq.Poller()
        poller.register(pipe, zmq.POLLIN)
        poller.register(n.inbox, zmq.POLLIN)

        while(True):
            items = dict(poller.poll())

            if pipe in items and items[pipe] == zmq.POLLIN:
                message = pipe.recv()
                # message to quit
                if message.decode('utf-8') == "$$STOP":
                    break

            if n.inbox in items and items[n.inbox] == zmq.POLLIN:
                cmds = n.recv()
                #self.log.error("NODE_MSG CONT:{}".format(cmds))

                msg_type = cmds.pop(0)
                peer_uuid_bytes = cmds.pop(0)
                peer_uuid = uuid.UUID(bytes=peer_uuid_bytes)

                #self.log.debug("NODE_MSG TYPE: {}".format(msg_type))
                #self.log.debug("NODE_MSG PEER: {}".format(peer_uuid))

                if msg_type.decode('utf-8') == "SHOUT":
                    group_name = cmds.pop(0)
                    #self.log.debug("NODE_MSG GROUP: {}".format(group_name))

                    group_name_2 = cmds.pop(0)
                    #self.log.debug("NODE_MSG GROUP_2: {}".format(group_name_2))

                    discoveryMsg = cmds.pop(0)
                    #self.log.debug("Discovery Msg : {}".format(discoveryMsg))

                    controller = json.loads(discoveryMsg.decode('utf-8'))
                    self.controller_dl = str(controller["downlink"])
                    self.controller_ul = str(controller["uplink"])
                    self.log.info("Discovered Controller DL-{}, UL-{}".format(self.controller_dl, self.controller_ul))

        n.stop()
    def discovery_task(self, ctx, pipe):
        self.log.debug("Pyre on iface : {}".format(self.iface))
        n = Pyre(self.groupName, sel_iface=self.iface)
        n.set_header("DISCOVERY_Header1", "DISCOVERY_HEADER")
        n.join(self.groupName)
        n.start()

        poller = zmq.Poller()
        poller.register(pipe, zmq.POLLIN)

        while (True):
            items = dict(poller.poll())

            if pipe in items and items[pipe] == zmq.POLLIN:
                message = pipe.recv()
                # message to quit
                if message.decode('utf-8') == "$$STOP":
                    break

                n.shout(self.groupName, message)

        n.stop()
    def discovery_task(self, ctx, pipe):
        self.log.debug("Pyre on iface : {}".format(self.iface))
        n = Pyre(self.groupName, sel_iface=self.iface)
        n.set_header("DISCOVERY_Header1","DISCOVERY_HEADER")
        n.join(self.groupName)
        n.start()

        poller = zmq.Poller()
        poller.register(pipe, zmq.POLLIN)

        while(True):
            items = dict(poller.poll())

            if pipe in items and items[pipe] == zmq.POLLIN:
                message = pipe.recv()
                # message to quit
                if message.decode('utf-8') == "$$STOP":
                    break

                n.shout(self.groupName, message)

        n.stop()
示例#10
0
def chat_task(ctx, pipe):
    print("Game started")
    print("Name: %s" % NAME)
    connected_players = 1
    network_players = 1
    leave_counter = 0

    #Set up node for the game
    n = Pyre("")
    n.set_header("header_name", NAME)

    #Join the group
    n.join(GROUPNAME)

    #Start broadcasting node
    n.start()

    # Set up poller
    poller = zmq.Poller()
    poller.register(
        pipe, zmq.POLLIN
    )  #Local pipe (contains commands/messages we send through terminal)
    poller.register(n.socket(), zmq.POLLIN)

    # A while loop constantly polls for new items = PULL system
    while True:

        #Wait for new message to be polled. This function blocks until there is a new message
        items = dict(poller.poll())

        #This are messages from ourselves
        if pipe in items:
            message_pipe = pipe.recv()
            if message_pipe.decode('utf-8') == STOP_COMMAND:
                break
            #check if the message is a number
            elif message_pipe.decode(
                    'utf-8').isdigit() == True and yourturn == True:
                #variable to keep the loop going until a correct number is given
                status = True
                #check which symbol you got assigned
                if playerX == True:
                    while status == True:
                        number = int(message_pipe.decode('utf-8'))
                        #check if the spot is free
                        if board[number] != "X" and board[number] != "O":
                            status = False
                            yourturn = False
                            print("New status board:")
                            board[number] = "X"
                            showboard()
                            #check for a winning combination
                            if checkall("X") == True:
                                print("You win!")
                                n.whisper(OPPONENT,
                                          str(number).encode('utf-8'))
                                break
                            #when there's no winning combination, it's the other player's turn
                            else:
                                print("Waiting for opponent's move...")
                            #let your opponent know which number you chose
                            n.whisper(OPPONENT, str(number).encode('utf-8'))
                        else:
                            print("Spot taken, try again")
                            message_pipe = pipe.recv()
                else:
                    while status == True:
                        number = int(message_pipe.decode('utf-8'))
                        if board[number] != "X" and board[number] != "O":
                            status = False
                            yourturn = False
                            print("New status board:")
                            board[number] = "O"
                            showboard()
                            if checkall("O") == True:
                                print("You win!")
                                n.whisper(OPPONENT,
                                          str(number).encode('utf-8'))
                                break
                            else:
                                print("Waiting for opponent's move...")
                            n.whisper(OPPONENT, str(number).encode('utf-8'))
                        else:
                            print("Spot taken, try again")
                            message_pipe = pipe.recv()
            elif message_pipe.decode(
                    'utf-8').isdigit() == True and yourturn == False:
                print("It's not your turn, wait for your opponent's move")
            #if the message isn't a number, it is send as a message to your opponent
            else:
                print("Sending message to opponent: %s" %
                      message_pipe.decode('utf-8'))
                n.whisper(OPPONENT, message_pipe)

        # Received messages from system or messages from other peers
        else:
            cmds = n.recv()
            #print(">>>>>>>RECEIVED MESSAGE: ", cmds)
            msg_type = cmds.pop(0)
            player_uuid = uuid.UUID(bytes=cmds.pop(0))
            #OPPONENT = player_uuid
            #print("player uuid: ", player_uuid)
            msg_name = cmds.pop(0)

            if msg_type.decode('utf-8') == "ENTER":
                headers = json.loads(cmds.pop(0).decode('utf-8'))
                network_players += 1
                if network_players == 2:
                    print(
                        "--------------------------------------------------------------------------------"
                    )
                    print("New player discovered in network")
                    print("Name:", headers.get("header_name"))
                    print(
                        "--------------------------------------------------------------------------------"
                    )
            elif msg_type.decode('utf-8') == "JOIN":
                connected_players += 1
                #check if there's stil room for a player
                if connected_players > 2:
                    leave = "No free spot left"
                    n.whisper(player_uuid, leave.encode('utf-8'))
                elif connected_players == 2:
                    print(
                        "--------------------------------------------------------------------------------"
                    )
                    print("%s joined group" % headers.get("header_name"),
                          cmds.pop(0).decode('utf-8'))
                    print(
                        "--------------------------------------------------------------------------------"
                    )
                    #if there are 2 players, you know your opponent:
                    OPPONENT = player_uuid
                    showboard()
                    #randomly choose if you want to start
                    assign = random.randint(0, 1)
                    if assign == 1:
                        player_start = True
                        n.whisper(OPPONENT, "$$Istart".encode('utf-8'))
                    else:
                        player_start = False
                        n.whisper(OPPONENT, "$$Ustart".encode('utf-8'))
            elif msg_type.decode('utf-8') == "WHISPER":
                message_opponent = cmds.pop(0).decode('utf-8')
                if message_opponent == "No free spot left":
                    leave_counter += 1
                    #if you get the message that you must leave from 2 other players, you are the third player
                    if leave_counter == 2:
                        print(message_opponent)
                        break
                #if the random generators both got a compatible result, the game can start
                elif message_opponent == "$$Istart" and player_start == False:
                    playerX = False
                    yourturn = False
                    print("You are symbol O")
                    print("You opponent may start, please wait...")
                elif message_opponent == "$$Ustart" and player_start == True:
                    playerX = True
                    yourturn = True
                    print("You are symbol X")
                    print("You may start")
                    print("Where do you want to place your X?")
                #when the results are incompatible: try again
                elif message_opponent == "$$Istart" and player_start == True:
                    assign = random.randint(0, 1)
                    if assign == 1:
                        player_start = True
                        n.whisper(OPPONENT, "$$Istart".encode('utf-8'))
                    else:
                        player_start = False
                        n.whisper(OPPONENT, "$$Ustart".encode('utf-8'))
                elif message_opponent == "$$Ustart" and player_start == False:
                    assign = random.randint(0, 1)
                    if assign == 1:
                        player_start = True
                        n.whisper(OPPONENT, "$$Istart".encode('utf-8'))
                    else:
                        player_start = False
                        n.whisper(OPPONENT, "$$Ustart".encode('utf-8'))
                #if you receive a number, this is your opponent's move
                elif message_opponent.isdigit() == True:
                    yourturn = True
                    print(
                        "--------------------------------------------------------------------------------"
                    )
                    print("Number opponent: ", message_opponent)
                    print("New status board:")
                    #check for a winning combination based on which player you are
                    if playerX == True:
                        board[int(message_opponent)] = "O"
                        showboard()
                        if checkall('O') == True:
                            print("You loose!")
                            break
                        #if your opponent didn't make a winning combination, it's your turn
                        else:
                            print("Your turn")
                            print("Where do you want to place your X?")
                    else:
                        board[int(message_opponent)] = "X"
                        showboard()
                        if checkall('X') == True:
                            print("You loose!")
                            break
                        else:
                            print("Your turn")
                            print("Where do you want to place your O?")
                #if you just received a message, print it
                else:
                    print("Opponent says: ", message_opponent)

            elif msg_type.decode('utf-8') == "EXIT":
                if connected_players == 2:
                    print("%s left network" % headers.get("header_name"))
                    connected_players -= 1
                    print("Total connected players: ", connected_players)
                leave_counter -= 1
    print("Game stopped")
    n.stop()
def chat_task(ctx, pipe):
	print("Game started")
	print("Name: %s" %NAME)
	connected_players = 1
	network_players = 1
	leave_counter = 0

	#Set up node for the game
	n = Pyre("")
	n.set_header("header_name", NAME)

	#Join the group
	n.join(GROUPNAME)
	
	#Start broadcasting node
	n.start()

	# Set up poller
	poller = zmq.Poller()
	poller.register(pipe, zmq.POLLIN)  #Local pipe (contains commands/messages we send through terminal)
	poller.register(n.socket(), zmq.POLLIN)

	# A while loop constantly polls for new items = PULL system
	while True:

		#Wait for new message to be polled. This function blocks until there is a new message
		items = dict(poller.poll())

        	#This are messages from ourselves
		if pipe in items:
			message_pipe = pipe.recv()
			if message_pipe.decode('utf-8') == STOP_COMMAND:
				break
			#check if the message is a number
			elif message_pipe.decode('utf-8').isdigit() == True and yourturn == True:
				#variable to keep the loop going until a correct number is given
				status = True
				#check which symbol you got assigned
				if playerX == True:
					while status == True:
						number = int(message_pipe.decode('utf-8'))
						#check if the spot is free
						if board[number] != "X" and board[number] != "O":
							status = False
							yourturn = False
							print("New status board:")
							board[number] = "X"
							showboard()
							#check for a winning combination
							if checkall("X") == True:
								print("You win!")
								n.whisper(OPPONENT,str(number).encode('utf-8'))
								break
							#when there's no winning combination, it's the other player's turn
							else:
								print("Waiting for opponent's move...")
							#let your opponent know which number you chose
							n.whisper(OPPONENT,str(number).encode('utf-8'))
						else:
							print("Spot taken, try again")
							message_pipe = pipe.recv()
				else:
					while status == True:
						number = int(message_pipe.decode('utf-8'))
						if board[number] != "X" and board[number] != "O":
							status = False
							yourturn = False
							print("New status board:")
							board[number] = "O"
							showboard()
							if checkall("O") == True:
								print("You win!")
								n.whisper(OPPONENT,str(number).encode('utf-8'))
								break
							else:
								print("Waiting for opponent's move...")
							n.whisper(OPPONENT,str(number).encode('utf-8'))
						else:
							print("Spot taken, try again")
							message_pipe = pipe.recv()
			elif message_pipe.decode('utf-8').isdigit() == True and yourturn == False:
				print("It's not your turn, wait for your opponent's move")
			#if the message isn't a number, it is send as a message to your opponent
			else:
				print("Sending message to opponent: %s" %message_pipe.decode('utf-8'))
				n.whisper(OPPONENT,message_pipe)

		# Received messages from system or messages from other peers
		else:
			cmds = n.recv()
			#print(">>>>>>>RECEIVED MESSAGE: ", cmds)
			msg_type = cmds.pop(0)
			player_uuid = uuid.UUID(bytes=cmds.pop(0))
			#OPPONENT = player_uuid
			#print("player uuid: ", player_uuid)
			msg_name = cmds.pop(0)
			
			if msg_type.decode('utf-8') == "ENTER":
				headers = json.loads(cmds.pop(0).decode('utf-8'))
				network_players += 1
				if network_players == 2:
					print("--------------------------------------------------------------------------------")
					print("New player discovered in network")
					print("Name:", headers.get("header_name"))
					print("--------------------------------------------------------------------------------")
			elif msg_type.decode('utf-8') == "JOIN":
				connected_players += 1
				#check if there's stil room for a player
				if connected_players > 2:
					leave = "No free spot left"
					n.whisper(player_uuid, leave.encode('utf-8'))
				elif connected_players == 2:
					print("--------------------------------------------------------------------------------")
					print("%s joined group" %headers.get("header_name"), cmds.pop(0).decode('utf-8'))
					print("--------------------------------------------------------------------------------")
					#if there are 2 players, you know your opponent:
					OPPONENT = player_uuid
					showboard()
					#randomly choose if you want to start
					assign = random.randint(0,1)
					if assign == 1:
						player_start = True
						n.whisper(OPPONENT, "$$Istart".encode('utf-8'))
					else:
						player_start = False
						n.whisper(OPPONENT, "$$Ustart".encode('utf-8'))						
			elif msg_type.decode('utf-8') == "WHISPER":
				message_opponent = cmds.pop(0).decode('utf-8')
				if message_opponent == "No free spot left":
					leave_counter += 1
					#if you get the message that you must leave from 2 other players, you are the third player
					if leave_counter == 2:
						print(message_opponent)
						break
				#if the random generators both got a compatible result, the game can start
				elif message_opponent == "$$Istart" and player_start == False:
					playerX = False
					yourturn = False
					print("You are symbol O")
					print("You opponent may start, please wait...")
				elif message_opponent == "$$Ustart" and player_start == True:
					playerX = True
					yourturn = True
					print("You are symbol X")
					print("You may start")
					print("Where do you want to place your X?")
				#when the results are incompatible: try again
				elif message_opponent == "$$Istart" and player_start == True:
					assign = random.randint(0,1)
					if assign == 1:
						player_start = True
						n.whisper(OPPONENT, "$$Istart".encode('utf-8'))
					else:
						player_start = False
						n.whisper(OPPONENT, "$$Ustart".encode('utf-8'))
				elif message_opponent == "$$Ustart" and player_start == False:
					assign = random.randint(0,1)
					if assign == 1:
						player_start = True
						n.whisper(OPPONENT, "$$Istart".encode('utf-8'))
					else:
						player_start = False
						n.whisper(OPPONENT, "$$Ustart".encode('utf-8'))
				#if you receive a number, this is your opponent's move
				elif message_opponent.isdigit() == True:
					yourturn = True
					print("--------------------------------------------------------------------------------")
					print("Number opponent: ",message_opponent)
					print("New status board:")
					#check for a winning combination based on which player you are
					if playerX == True:
						board[int(message_opponent)] = "O"
						showboard()
						if checkall('O') == True:
							print("You loose!")
							break
						#if your opponent didn't make a winning combination, it's your turn
						else:
							print("Your turn")
							print("Where do you want to place your X?")
					else:
						board[int(message_opponent)] = "X"
						showboard()
						if checkall('X') == True:
							print("You loose!")
							break
						else:
							print("Your turn")
							print("Where do you want to place your O?")					
				#if you just received a message, print it
				else:
					print("Opponent says: ",message_opponent)


			elif msg_type.decode('utf-8') == "EXIT":
				if connected_players == 2:
					print("%s left network" %headers.get("header_name"))
					connected_players -= 1
					print("Total connected players: ", connected_players)
				leave_counter -= 1
	print("Game stopped")
	n.stop()
示例#12
0
文件: network.py 项目: vedb/pyndsi
class _NetworkNode(NetworkInterface):
    """
    Communication node

    Creates Pyre node and handles all communication.
    """
    def __init__(self,
                 format: DataFormat,
                 context=None,
                 name=None,
                 headers=(),
                 callbacks=()):
        self._name = name
        self._format = format
        self._headers = headers
        self._pyre_node = None
        self._context = context or zmq.Context()
        self._sensors_by_host = {}
        self._callbacks = [self._on_event] + list(callbacks)

    # Public NetworkInterface API

    @property
    def has_events(self) -> bool:
        return self.running and self._pyre_node.socket().get(
            zmq.EVENTS) & zmq.POLLIN

    @property
    def running(self) -> bool:
        return bool(self._pyre_node)

    @property
    def sensors(self) -> typing.Mapping[str, NetworkSensor]:
        sensors = {}
        for sensor in self._sensors_by_host.values():
            sensors.update(sensor)
        return sensors

    @property
    def callbacks(self) -> typing.Iterable[NetworkEventCallback]:
        return self._callbacks

    @callbacks.setter
    def callbacks(self, value: typing.Iterable[NetworkEventCallback]):
        self._callbacks = value

    def start(self):
        # Setup node
        logger.debug("Starting network...")
        self._pyre_node = Pyre(self._name)
        self._name = self._pyre_node.name()
        for header in self._headers:
            self._pyre_node.set_header(*header)
        self._pyre_node.join(self._group)
        self._pyre_node.start()

    def whisper(self, peer, msg_p):
        if self._format == DataFormat.V3:
            return  # no-op
        elif self._format == DataFormat.V4:
            self._pyre_node.whisper(peer, msg_p)
        else:
            raise NotImplementedError()

    def rejoin(self):
        for sensor_uuid, sensor in list(self.sensors.items()):
            self._execute_callbacks({
                "subject": "detach",
                "sensor_uuid": sensor_uuid,
                "sensor_name": sensor["sensor_name"],
                "host_uuid": sensor["host_uuid"],
                "host_name": sensor["host_name"],
            })
        self._pyre_node.leave(self._group)
        self._pyre_node.join(self._group)

    def stop(self):
        logger.debug("Stopping network...")
        self._pyre_node.leave(self._group)
        self._pyre_node.stop()
        self._pyre_node = None

    def handle_event(self):
        if not self.has_events:
            return
        event = PyreEvent(self._pyre_node)
        uuid = event.peer_uuid
        if event.type == "SHOUT" or event.type == "WHISPER":
            try:
                payload = event.msg.pop(0).decode()
                msg = serial.loads(payload)
                msg["subject"]
                msg["sensor_uuid"]
                msg["host_uuid"] = event.peer_uuid.hex
                msg["host_name"] = event.peer_name
            except serial.decoder.JSONDecodeError:
                logger.warning('Malformatted message: "{}"'.format(payload))
            except (ValueError, KeyError):
                logger.warning("Malformatted message: {}".format(msg))
            except Exception:
                logger.debug(tb.format_exc())
            else:
                if msg["subject"] == "attach":
                    if self.sensors.get(msg["sensor_uuid"]):
                        # Sensor already attached. Drop event
                        return
                    sensor_type = SensorType.supported_sensor_type_from_str(
                        msg["sensor_type"])
                    if sensor_type is None:
                        logger.debug("Unsupported sensor type: {}".format(
                            msg["sensor_type"]))
                        return
                elif msg["subject"] == "detach":
                    sensor_entry = self.sensors.get(msg["sensor_uuid"])
                    # Check if sensor has been detached already
                    if not sensor_entry:
                        return
                    msg.update(sensor_entry)
                else:
                    logger.debug("Unknown host message: {}".format(msg))
                    return
                self._execute_callbacks(msg)
        elif event.type == "JOIN":
            # possible values for `group_version`
            # - [<unrelated group>]
            # - [<unrelated group>, <unrelated version>]
            # - ['pupil-mobile']
            # - ['pupil-mobile', <version>]
            group_version = event.group.split("-v")
            group = group_version[0]
            version = group_version[1] if len(group_version) > 1 else "0"

        elif event.type == "EXIT":
            gone_peer = event.peer_uuid.hex
            for host_uuid, sensors in list(self._sensors_by_host.items()):
                if host_uuid != gone_peer:
                    continue
                for sensor_uuid, sensor in list(sensors.items()):
                    self._execute_callbacks({
                        "subject":
                        "detach",
                        "sensor_uuid":
                        sensor_uuid,
                        "sensor_name":
                        sensor["sensor_name"],
                        "host_uuid":
                        host_uuid,
                        "host_name":
                        sensor["host_name"],
                    })
        else:
            logger.debug("Dropping {}".format(event))

    def sensor(
        self,
        sensor_uuid: str,
        callbacks: typing.Iterable[NetworkEventCallback] = ()
    ) -> Sensor:
        try:
            sensor_settings = self.sensors[sensor_uuid].copy()
        except KeyError:
            raise ValueError(
                '"{}" is not an available sensor id.'.format(sensor_uuid))

        sensor_type_str = sensor_settings.pop("sensor_type", "unknown")
        sensor_type = SensorType.supported_sensor_type_from_str(
            sensor_type_str)

        if sensor_type is None:
            raise ValueError('Sensor of type "{}" is not supported.'.format(
                sensor_type_str))

        return Sensor.create_sensor(
            sensor_type=sensor_type,
            format=self._format,
            context=self._context,
            callbacks=callbacks,
            **sensor_settings,
        )

    # Public

    def __str__(self):
        return "<{} {} [{}]>".format(__name__, self._name,
                                     self._pyre_node.uuid().hex)

    # Private

    @property
    def _group(self) -> str:
        return group_name_from_format(self._format)

    def _execute_callbacks(self, event):
        for callback in self.callbacks:
            callback(self, event)

    def _on_event(self, caller, event):
        if event["subject"] == "attach":
            subject_less = event.copy()
            del subject_less["subject"]
            host_uuid = event["host_uuid"]
            host_sensor = {event["sensor_uuid"]: subject_less}
            try:
                self._sensors_by_host[host_uuid].update(host_sensor)
            except KeyError:
                self._sensors_by_host[host_uuid] = host_sensor
            logger.debug(f'Attached {host_uuid}.{event["sensor_uuid"]}')
        elif event["subject"] == "detach":
            for host_uuid, sensors in self._sensors_by_host.items():
                try:
                    del sensors[event["sensor_uuid"]]
                    logger.debug(
                        f'Detached {host_uuid}.{event["sensor_uuid"]}')
                except KeyError:
                    pass
            hosts_to_remove = [
                host_uuid
                for host_uuid, sensors in self._sensors_by_host.items()
                if len(sensors) == 0
            ]
            for host_uuid in hosts_to_remove:
                del self._sensors_by_host[host_uuid]
示例#13
0
def chat_task(ctx,pipe):
	print("communication started")

	GROUPNAME = "Quizzzzz"
	StopCmnd = "$$quit"
	OPPONENT = "opponent"
	
	print("name: %s" %NAME)
	
	connected_players = 1
	
	# set up node for the user
	n = Pyre(GROUPNAME)
	n.set_header('Name', NAME)
	
	# join the groupchat
	n.join(GROUPNAME)
	#print("UUID %s" %n.uuid())
	 
				
	# start broadcasting signal 
	n.start()

	# set up poller
	poller = zmq.Poller()
	poller.register(pipe,zmq.POLLIN)
	poller.register(n.socket(),zmq.POLLIN)

	# looping constantly to recieve messages
	while True:
		items = dict(poller.poll())
		
		if pipe in items:
			message = pipe.recv()
			if message.decode('utf-8') == StopCmnd:
				break
			# uppercase letters for question to whole group
			elif message.decode('utf-8').isupper() == True: 
				print("Question is: %s" %message)
				n.shouts(GROUPNAME,"Question to group is: %s" %message.decode('utf-8'))
				answer = 0
			# lowercase to last person who asked question in the group
			elif message.decode('utf-8').islower()  == True:
				message = NAME + "'s answer is=" + message
				n.whisper(PEER,message)
			else:
				print("please don't mix up or lowercase or use not only numbers")
	
		else:
			msgrecv = n.recv()
			#print(msgrecv)
			msg_type = msgrecv.pop(0)
			msg_sender = uuid.UUID(bytes=msgrecv.pop(0))
			PEER = msg_sender
			msg_name = msgrecv.pop(0)

			if msg_type.decode('utf-8') == "ENTER":
				headers = json.loads(msgrecv.pop(0).decode('utf-8'))
				print("New player discovered in network")
				print("New player = %s " %headers.get("Name"))
			elif msg_type.decode('utf-8') == "JOIN":
				print("New player has joined the group")
				print("New player = %s" %headers.get("Name"))
				connected_players += 1
				print("#players = %s" %connected_players)
			elif msg_type.decode('utf-8') == "SHOUT":
				print(msgrecv.pop(1))
			elif msg_type.decode('utf-8') == "WHISPER":
				if msgrecv[0] == "You have to ask next question":
					print("You have to ask next question")
					n.shout(GROUPNAME, "%s is new quizmaster" %NAME)
					answer = 0
				else:
					print(msgrecv.pop(0))
					answer +=1
					if answer == connected_players -1: #choosing new quizmaster randomly
						players = n.peers()
						next_master = players.pop(random.randint(0,connected_players-2))
						n.whisper(next_master,"You have to ask next question")
			
	
	print("Left current game")	
	n.stop()
示例#14
0
def chat_task(ctx, pipe):
    print("-----CAR PEER COMMUNICATION STARTED-----")
    print("Manufacturer: ", MANUFACTURER, " - Model: ", MODEL)

    connected_cars = 0

    #Set up node for the car
    n = Pyre("")
    n.set_header("manufacturer", MANUFACTURER)
    n.set_header("model", MODEL)

    #Join the group 'chat'
    n.join(GROUPNAME)

    #Start broadcasting node
    n.start()

    # Set up poller
    poller = zmq.Poller()
    poller.register(pipe, zmq.POLLIN)  #Local pipe (contains commands/messages we send through terminal)
    poller.register(n.socket(), zmq.POLLIN)


    # A while loop constantly polls for new items = PULL system
    while True:

        #Wait for new message to be polled. This function blocks until there is a new message
        items = dict(poller.poll())

        #This are messages from ourselves, that we want to shout on the network
        if pipe in items:
            message = pipe.recv()

            # User stopped car
            if message.decode('utf-8') == STOP_COMMAND:
                break

            print(">>>>>> Sending out shout: %s" % message)
            n.shouts(GROUPNAME, message.decode('utf-8'))

        # Received messages from system or messages from other peers
        else:
            cmds = n.recv()
            print("--------------------------------------------------------------------------------")
            #print(">>>>>>>RECEIVED MESSAGE: ", cmds)

            msg_type = cmds.pop(0)
            car_uuid = uuid.UUID(bytes=cmds.pop(0))
            msg_name = cmds.pop(0)

            if msg_type.decode('utf-8') == "ENTER":
                headers = json.loads(cmds.pop(0).decode('utf-8'))
                print(">>>> NEW CAR DISCOVERED IN NETWORK")
                print("---Manufacturer:", headers.get("manufacturer"), "--- Model:", headers.get("model"))

            elif msg_type.decode('utf-8') == "JOIN":
                print(">>>> NEW CAR JOINED GROUP <<", cmds.pop(0).decode('utf-8'),">>")
                connected_cars += 1

            elif msg_type.decode('utf-8') == "SHOUT":
                print(">>>> RECEIVED SHOUT IN %s" % cmds.pop(0))
                print("---Msg: %s" % cmds.pop(0))

            elif msg_type.decode('utf-8') == "EXIT":
                print(">>>> CAR LEFT NETWORK")
                connected_cars -= 1


            print("---Total connected cars: ", connected_cars)
            print("---Car_UUID: ", car_uuid)
            #print("---NODE_MSG REMAINING: %s" % cmds)


    print("-----CAR COMMUNICATION STOPPED-----")
    n.stop()
示例#15
0
class Discovery:

    def __init__(self, my_name, my_ip, group_name):

        self.name = my_name
        self.ip = my_ip
        self.group = group_name

        # node dict is of the format ip: name
        # This is because a user (name) may move to a new ip.
        # Duplicate ip's are not allowed, but more than 1 ip may share the 
        # same name. This is because a user may log in to multiple devices.
        # 
 
        self.node_dict = {}

        self.node = Pyre(self.group)
        self.node.set_header(self.name, self.ip)
        self.node.join(self.group)
        self.node.start()

        # this runs forever for testing, but should be run as a thread
        self._node_update_task()

    """ This task will keep the node dictionary updated.

        The node will periodically send an update (heartbeat) control message
        which has the name and ip as in the header.

        Periodically recieve the incomming messages and update the ip name dictionary
    """
    def _node_update_task(self):
        while True:
            cmds = self.node.recv()
            msg_type = cmds.pop(0)

            # debug prints
            print("NODE_MSG TYPE: %s" % msg_type)
            print("NODE_MSG PEER: %s" % uuid.UUID(bytes=cmds.pop(0)))
            print("NODE_MSG NAME: %s" % cmds.pop(0))

            # headers are packed json
            if msg_type.decode('utf-8') == "SHOUT":
                print("NODE_MSG GROUP: %s" % cmds.pop(0))
            elif msg_type.decode('utf-8') == "ENTER":
                headers = json.loads(cmds.pop(0).decode('utf-8'))
                print("NODE_MSG HEADERS: %s" % headers)
                for key in headers:
                    print("key = {0}, value = {1}".format(key, headers[key]))
            print("NODE_MSG CONT: %s" % cmds)


    """
     Get the currwnt nodes dict
     ip, name, group
    """
    def get_active_nodes(self):

        # return the active nodes dictionary
        return self.node_dict

    def get_idle_nodes(self):
        return self.node_dict
示例#16
0
class Authority():
    def __init__(self):
        self.node = Pyre("GAME_AUTH")
        self.node.set_header("AUTHORITY", "TRUE")
        self.node.start()
        self.node.join("world:position")
        self.node.join("ctf:teams")
        self.node.join("ctf:dropflag")
        self.node.join("ctf:gotflag")

        self.poller = zmq.Poller()
        self.poller.register(self.node.socket(), zmq.POLLIN)

        self.players = AuthorityPlayerManager()

        self.teams = {"blue": [], "red": []}

        self.level = SaveLevel('./assets/maps/CAPFLAG MAP NAT')
        red_spawn_pos = self.level.get_place(Place.RED_SPAWN)
        blue_spawn_pos = self.level.get_place(Place.BLUE_SPAWN)

        self.flags = {
            "blue": {
                "x": blue_spawn_pos[0],
                "y": blue_spawn_pos[1],
                "owner": '',
                "timer": 0
            },
            "red": {
                "x": red_spawn_pos[0],
                "y": red_spawn_pos[1],
                "owner": '',
                "timer": 0
            }
        }

        self.serve()

    def set_teams(self):
        blue_players = self.teams["blue"]
        red_players = self.teams["red"]

        # Check for removed players in RED
        for i, playerUUID in enumerate(red_players):
            if playerUUID not in self.players.players.keys():
                red_players.pop(i)
        # Check for removed players in BLUE
        for i, playerUUID in enumerate(blue_players):
            if playerUUID not in self.players.players.keys():
                blue_players.pop(i)

        # Add new players
        for playerUUID, player in self.players.players.items():
            if not (playerUUID in blue_players or playerUUID in red_players):
                if len(blue_players) > len(red_players):
                    red_players.append(playerUUID)
                else:
                    blue_players.append(playerUUID)

        print("Teams: " + "RED: " + ','.join(red_players) + " | BLUE: " +
              ','.join(blue_players))
        self.node.shout("ctf:teams", bson.dumps(self.teams))

    def set_flags(self, flag_info):
        return

    def update_flags(self):
        self.node.shout("ctf:flags", bson.dumps(self.flags))

    def get_team_from_uuid(self, uuid):
        place = None

        if str(uuid) in self.teams['red']:
            place = Place.RED_SPAWN
        elif str(uuid) in self.teams['blue']:
            place = Place.BLUE_SPAWN

        return place

    def serve(self):
        clock = Clock()
        while True:
            clock.tick(60)

            # check network
            events = self.get_events()
            if events:
                try:
                    for event in events:
                        # Update the teams on JOIN and EXIT
                        if event.type == 'JOIN':
                            if event.group == 'ctf:dropflag':
                                for team, flag in self.flags.items():
                                    if flag['owner'] == '':
                                        self.node.shout(
                                            'ctf:dropflag',
                                            bson.dumps({
                                                'x': flag['x'],
                                                'y': flag['y'],
                                                'team': team
                                            }))
                            elif event.group == 'ctf:gotflag':
                                for team, flag in self.flags.items():
                                    if flag['owner'] != '':
                                        self.node.shout(
                                            'ctf:gotflag',
                                            bson.dumps({
                                                'uuid': flag['owner'],
                                                'team': team
                                            }))
                            elif event.group == 'ctf:teams':
                                self.players.set(self.node.peers())
                                self.set_teams()
                                place = self.get_team_from_uuid(
                                    event.peer_uuid)
                                pos = self.level.get_place(place)
                                self.node.whisper(
                                    event.peer_uuid,
                                    bson.dumps({
                                        'type': 'teleport',
                                        'x': pos[0],
                                        'y': pos[1]
                                    }))
                        elif event.type == 'EXIT':
                            for team, flag in self.flags.items():
                                if flag['owner'] == str(event.peer_uuid):
                                    # flag owner is leaving, drop
                                    player = self.players.get(event.peer_uuid)
                                    flag['x'] = player.x
                                    flag['y'] = player.y
                                    flag['owner'] = ''
                                    self.node.shout(
                                        'ctf:dropflag',
                                        bson.dumps({
                                            'x': flag['x'],
                                            'y': flag['y'],
                                            'team': team
                                        }))
                            self.players.set(self.node.peers())
                            self.set_teams()
                        elif event.type == 'SHOUT':
                            if event.group == "world:position":
                                new_position = bson.loads(event.msg[0])
                                network_player = self.players.get(
                                    event.peer_uuid)
                                network_player.set_position(new_position)

                                # check if flag has been captured
                                for team, flag in self.flags.items():
                                    if flag['owner'] != str(event.peer_uuid):
                                        continue
                                    tile = self.level.get_tile(
                                        new_position['x'], new_position['y'])
                                    if tile == TileType.RED_BLOCK and team == 'blue':
                                        # TODO: blue's flag has been captured
                                        spawn = Place.BLUE_SPAWN
                                    elif tile == TileType.BLUE_BLOCK and team == 'red':
                                        # TODO: red's flag has been captured
                                        spawn = Place.RED_SPAWN
                                    else:
                                        continue
                                    position = self.level.get_place(spawn)
                                    flag['x'] = position[0]
                                    flag['y'] = position[1]
                                    flag['owner'] = ''
                                    self.node.shout(
                                        'ctf:dropflag',
                                        bson.dumps({
                                            'x': flag['x'],
                                            'y': flag['y'],
                                            'team': team
                                        }))
                            if event.group == 'ctf:gotflags':
                                flag_info = bson.loads(event.msg[0])
                                self.set_flags(flag_info)
                        elif event.type == 'WHISPER':
                            msg = bson.loads(event.msg[0])
                            network_player = self.players.get(event.peer_uuid)
                            if msg['type'] == 'death_report':
                                player = self.players.get(event.peer_uuid)
                                previously_owned_flag = None
                                if self.flags['blue']['owner'] == str(
                                        event.peer_uuid):
                                    previously_owned_flag = 'blue'
                                elif self.flags['red']['owner'] == str(
                                        event.peer_uuid):
                                    previously_owned_flag = 'red'

                                if previously_owned_flag:
                                    flag = self.flags[previously_owned_flag]
                                    flag['owner'] = ''
                                    self.node.shout(
                                        'ctf:dropflag',
                                        bson.dumps({
                                            'x':
                                            player.x,
                                            'y':
                                            player.y,
                                            'team':
                                            previously_owned_flag
                                        }))

                                place = self.get_team_from_uuid(
                                    event.peer_uuid)
                                pos = self.level.get_place(place)
                                self.node.whisper(
                                    event.peer_uuid,
                                    bson.dumps({
                                        'type': 'teleport',
                                        'x': pos[0],
                                        'y': pos[1]
                                    }))
                                player.x = pos[0]
                                player.y = pos[1]

                except Exception as e:
                    print(e)
                    import traceback
                    print(traceback.format_exc())
                    pass

            for team, flag in self.flags.items():
                if flag["owner"] != '': continue
                for uuid, player in self.players.players.items():
                    if flag['x'] == player.x and flag['y'] == player.y:
                        team_place = self.get_team_from_uuid(uuid)
                        pos = self.level.get_place(team_place)
                        if team == 'red' and team_place == Place.RED_SPAWN or team == 'blue' and team_place == Place.BLUE_SPAWN:
                            if player.x == pos[0] and player.y == pos[1]:
                                continue

                            self.node.shout(
                                'ctf:dropflag',
                                bson.dumps({
                                    'x': pos[0],
                                    'y': pos[1],
                                    'team': team
                                }))
                        else:
                            flag["owner"] = uuid
                            self.node.shout(
                                'ctf:gotflag',
                                bson.dumps({
                                    'uuid': uuid,
                                    'team': team
                                }))
                            break

    def poll(self):
        return dict(self.poller.poll(0))

    def peers(self):
        return self.node.peers()

    def stop(self):
        self.node.stop()

    def get_events(self):
        changes = self.poll()
        if self.node.socket() in changes and changes[
                self.node.socket()] == zmq.POLLIN:
            events = self.node.recent_events()
            return events
class ZyreToZMQModule:
    """ The ZyreToZMQModule Base Class """
   
    
    def __init__(self,ctx = None,name = "Default",headers=None,groups=None,config_file=None,polling_timeout = 1,sim_time=2):

        self.logger = logging.getLogger(name)
        self.logger.setLevel(logging.DEBUG)
        # create the console output logging
        sh = logging.StreamHandler()
        sh.setLevel(logging.INFO)
        # create a logger writing into a log file
        fh = logging.FileHandler(name + ".log")
        fh.setLevel(logging.DEBUG)
        # create formatter and add it to the handlers
        # see https://docs.python.org/2/library/logging.html#logrecord-attributes for what can be logged
        fh.setFormatter(logging.Formatter('Name: %(name)s, ProcessName: %(processName)s, ThreadName: %(threadName)s, Module: %(module)s, FunctionName: %(funcName)s, LineNo: %(lineno)d, Level: %(levelname)s, Msg: %(message)s'))
        #sh.setFormatter(logging.Formatter('Module: %(module)s, FunctionName: %(funcName)s, LineNo: %(lineno)d, Level: %(levelname)s, Msg: %(message)s'))
        sh.setFormatter(logging.Formatter('Name: %(name)s, %(module)s/%(funcName)s[%(levelname)s]: %(message)s (lineno:%(lineno)d)'))
        # add the handlers to logger
        self.logger.addHandler(sh)
        self.logger.addHandler(fh)
        self.logger.propagate = False # don't pass messages to parent loggers

        if not type(ctx) ==  zmq.sugar.context.Context:
            self.logger.warn("Created ZMQ context. Please supply a ZMQ context next time.")
            ctx = zmq.Context()
        self.ctx = ctx
        if not type(name) == str:
            name = "Default"
            self.logger.warn("Please provide a the name as a string. Setting name to default: %s." % name)
        self.name = name
        if not headers:
            self.logger.warn("Please provide a model and other header information.")
            headers = {}
        self.headers = headers
        if not groups:
            groups = ["SHERPA"]
            self.logger.warn("Please provide a list with group names to which it will listen. Will set it to default: %s" %groups)
        self.groups = groups
        if not config_file:
            # will be opened during configuration
            self.logger.error("No config file provided for initial configuration")
            exit()
      
        self.config_file = config_file
        self.config = None
        self.alive = True # used for exiting once the node is stopped
        self.line_controller = None # stores uid of line controller this module is listening to (to avoid several line controllers)
        self.com_timeout = polling_timeout # time_out in msec after which poller returns
        self.sim_time = sim_time # time in msec
        self.inbox = []
        self.outbox = []
             
        # Node setup
        self.node = Pyre(self.name)
        for key in self.headers:
            self.node.set_header(key,self.headers[key])
        for group in self.groups:
            self.node.join(group)
        #self.node.set_verbose()
        self.node.start()
        
        # Socket setup
        self.poller = zmq.Poller()
        self.poller.register(self.node.socket(), zmq.POLLIN)

        port = "12911" 
        self.zmq_socket = self.ctx.socket(zmq.PUB)
        self.zmq_socket.bind("tcp://*:%s" % port)
   

        self.run()


    def run(self):
        """ Running loop of this process:
        [COMMUNICATION]     Check communication channels and parse all messages.
        """
        while self.alive:
            try:
                #[COMMUNICATION]
                self.communication()
                #[LOGGING]
                #self.logging()
                time.sleep(1)
            except (KeyboardInterrupt, SystemExit):
                break
        self.node.stop()


    def communication(self):
        """ This function handles the communication """

        # Check if communication is ready
        if not self.poller:
            self.logger.warn("No communication channels yet.")
        # Process input
        items = dict(self.poller.poll(self.com_timeout))
        # Get input from Pyre socket and put it in inbox which is processed in the following steps
        #logger.debug("Start processing incoming messages")
        if self.node.socket() in items and items[self.node.socket()] == zmq.POLLIN: 
            self.logger.info("Received %d msgs." % len(items))
            #print "msg arrived. inbox len %d" % len(self.inbox)
            msg_frame = self.node.recv()
            msg_type = msg_frame.pop(0)
            peer_uid = uuid.UUID(bytes=msg_frame.pop(0))
            peer_name = msg_frame.pop(0)   
            self.logger.info("Msg type: %s" % msg_type)         
            self.logger.info("Sender: %s" % peer_name)   
            # For shout and whisper take message payload and put it into inbox assuming it is correct
            # For the other zyre msgs create a JSON obj and put that into inbox
            # TODO: add validation
            if msg_type == "SHOUT":
                group = msg_frame.pop(0)
                msg = json.loads(msg_frame.pop(0))
                msg["sender_UUID"] = peer_uid
                msg["sender_name"] = peer_name
#                self.inbox.append(msg)
                self.outbox.append(msg)
            elif msg_type == "WHISPER":
                msg = json.loads(msg_frame.pop(0))
                msg["sender_UUID"] = peer_uid
                msg["sender_name"] = peer_name
                self.inbox.append(msg)        
            # don't care about join and leave messages; if necessary, split to have separate events               
#             elif msg_type == "LEAVE" or msg_type == "JOIN":
#                 group = msg_frame.pop(0)
#                 event = json.dumps({"metamodel": "http://www.sherpa-project.eu/examples/sherpa_msgs",
#                                     "model": "http://www.sherpa-project.eu/examples/sherpa_msgs/zyre_events",
#                                     "type": "leave/join",
#                                     "sender_UUID": peer_uid,
#                                     "sender_name": peer_name,
#                                     "payload": {}
#                                     })
#                 self.inbox.append(event)
            elif msg_type == "ENTER":
                headers = json.loads(msg_frame.pop(0))
                event = {"metamodel": "http://www.sherpa-project.eu/examples/sherpa_msgs",
                         "model": "http://www.sherpa-project.eu/examples/sherpa_msgs/zyre_events",
                         "type": "enter",
                         "sender_UUID": peer_uid,
                         "sender_name": peer_name,
                         "payload": {"header": headers}
                         }
                self.inbox.append(event)
            elif msg_type == "EXIT":
                event = {"metamodel": "http://www.sherpa-project.eu/examples/sherpa_msgs",
                         "model": "http://www.sherpa-project.eu/examples/sherpa_msgs/zyre_events",
                         "type": "exit",
                         "sender_UUID": peer_uid,
                         "sender_name": peer_name,
                         "payload": {}
                         }
                self.inbox.append(event)
        # Process output and send all msgs there until it is empty, but only if a line controller is connected.
        if self.outbox: #only do if there really is something in the outbox
            #if self.lcsm.sm.curr_state._name == "Idle" or self.lcsm.sm.curr_state._name == "Busy":
            if true:
                self.logger.info("Start processing messages in outbox. Number of msgs in outbox: %d" % len(self.outbox))
                while self.outbox:
                    # since we assume all msgs conform to the sherpa_msgs JSON model, simply shout them out
                    # TODO: add validation
                    msg = self.outbox.pop()
                    if type(msg) == dict:
                        self.logger.info("outbox msg type: " + msg["type"])
                        self.node.shout("SHERPA", json.dumps(msg))
                        
                        #WM message
                        
                        msg_wm_update = {
                          "@worldmodeltype": "RSGUpdate",
                          "operation": "CREATE",
                          "node": {
                            "@graphtype": "Group",
                            "id": "ff483c43-4a36-4197-be49-de829cdd66c8", 
                            "attributes": [
                                  {"key": "name", "value": "Task Specification Tree"},
                                  {"key": "tst:envtst", "value": msg },
                            ],
                          },
                          "parentId": "e379121f-06c6-4e21-ae9d-ae78ec1986a1",
                        }
                  
                        print ("===")
                        print (json.dumps(msg_wm_update))
                        self.zmq_socket.send_string(json.dumps(msg_wm_update)) 

                    else:
                        self.logger.warn("Message is not a dict! Serialization is done here! Msg: \n" + str(msg))
            else:
                self.logger.info("Can't send messages in outbox. Module not ready.")
示例#18
0
def rethinkdb_writer(ctx, pipe):

    # Database setup
    with open('../configuration.json') as data_file:
        configuration = json.load(data_file)

    group_name = configuration['zyreMediator']['group']

    n = Pyre(configuration['zyreMediator']['name'])
    n.set_interface('usb0')
    n.set_header('TYPE', configuration['zyreMediator']['type'])
    n.join(group_name)
    n.start()

    # Zyre setup
    poller = zmq.Poller()
    poller.register(pipe, zmq.POLLIN)
    poller.register(n.inbox, zmq.POLLIN)

    database_configuration = configuration['database']['mongoDB']
    mongo_connection = MongoClient(database_configuration['host'], database_configuration['port'])

    meteor = mongo_connection['meteor']

    # Add this module to the database
    meteor['modules'].insert([{
        '_id': str(n.uuid()),
        'name': n.name(),
        'type': configuration['zyreMediator']['type'],
        'parent': None
    }])

    ready_message = {
        'type': 'state',
        'senderId': str(n.uuid()),
        'payload': 2
    }

    def logMessage(message_to_log):
        message_to_log['timestamp'] = datetime.datetime.utcnow()
        meteor['events'].insert_one(message_to_log)
        del message_to_log['timestamp']
        del message_to_log['_id']

    n.shout(group_name, json.dumps(ready_message))
    logMessage(ready_message)

    module_name_to_uid_map = {}

    while True:
        items = dict(poller.poll(10))

        if pipe in items and items[pipe] == zmq.POLLIN:
            message = pipe.recv()
            # message to quit
            if message.decode('utf-8') == '$$STOP':
                break

        if n.inbox in items and items[n.inbox] == zmq.POLLIN:

            msg_frame = n.recv()
            msg_type = msg_frame.pop(0)
            peer_uid = uuid.UUID(bytes=msg_frame.pop(0))
            peer_name = msg_frame.pop(0)
            print('NODE_MSG TYPE: %s' % msg_type)
            print('NODE_MSG PEER: %s' % str(peer_uid))
            print('NODE_MSG NAME: %s' % peer_name)

            if msg_type.decode('utf-8') == 'ENTER':

                headers = json.loads(msg_frame.pop(0))

                try:
                    module_type = headers['type']
                except KeyError:
                    print("Your header doesn't contain your type of module")
                    module_type = 'unknown'

                try:
                    parent_module_id = headers['parentId']
                except KeyError:
                    print("The header doesn't contain the module's parent id")
                    parent_module_id = None

                # creates an entry with all known information about the robot
                # in the database if the robot is not in the database
                meteor['modules'].insert_one({
                    '_id': str(peer_uid),
                    'name': peer_name,
                    'type': module_type,
                    'parent': parent_module_id
                })

                module_name_to_uid_map[peer_name] = str(peer_uid)

            elif msg_type.decode('utf-8') == 'EXIT':
                meteor['modules'].remove({'_id': str(peer_uid)})

            elif msg_type.decode('utf-8') == 'SHOUT':

                # write message to database
                group = msg_frame.pop(0)
                try:
                    data = json.loads(msg_frame[0])
                except:
                    data = {}
                    print 'Invalid JSON string'

                # print data

                data['senderId'] = str(peer_uid)
                logMessage(data)

            elif msg_type.decode('utf-8') == 'WHISPER':
                # write message to database
                try:
                    data = json.loads(msg_frame[0])
                except:
                    print 'Invalid JSON string'

                logMessage(data)

    meteor['modules'].remove({'_id': str(n.uuid())})
    n.stop()
示例#19
0
class ZyreToZMQModule:
    """ The ZyreToZMQModule Base Class """
    def __init__(self,
                 ctx=None,
                 name="Default",
                 headers=None,
                 groups=None,
                 config_file=None,
                 polling_timeout=1,
                 sim_time=2):

        self.logger = logging.getLogger(name)
        self.logger.setLevel(logging.DEBUG)
        # create the console output logging
        sh = logging.StreamHandler()
        sh.setLevel(logging.INFO)
        # create a logger writing into a log file
        fh = logging.FileHandler(name + ".log")
        fh.setLevel(logging.DEBUG)
        # create formatter and add it to the handlers
        # see https://docs.python.org/2/library/logging.html#logrecord-attributes for what can be logged
        fh.setFormatter(
            logging.Formatter(
                'Name: %(name)s, ProcessName: %(processName)s, ThreadName: %(threadName)s, Module: %(module)s, FunctionName: %(funcName)s, LineNo: %(lineno)d, Level: %(levelname)s, Msg: %(message)s'
            ))
        #sh.setFormatter(logging.Formatter('Module: %(module)s, FunctionName: %(funcName)s, LineNo: %(lineno)d, Level: %(levelname)s, Msg: %(message)s'))
        sh.setFormatter(
            logging.Formatter(
                'Name: %(name)s, %(module)s/%(funcName)s[%(levelname)s]: %(message)s (lineno:%(lineno)d)'
            ))
        # add the handlers to logger
        self.logger.addHandler(sh)
        self.logger.addHandler(fh)
        self.logger.propagate = False  # don't pass messages to parent loggers

        if not type(ctx) == zmq.sugar.context.Context:
            self.logger.warn(
                "Created ZMQ context. Please supply a ZMQ context next time.")
            ctx = zmq.Context()
        self.ctx = ctx
        if not type(name) == str:
            name = "Default"
            self.logger.warn(
                "Please provide a the name as a string. Setting name to default: %s."
                % name)
        self.name = name
        if not headers:
            self.logger.warn(
                "Please provide a model and other header information.")
            headers = {}
        self.headers = headers
        if not groups:
            groups = ["SHERPA"]
            self.logger.warn(
                "Please provide a list with group names to which it will listen. Will set it to default: %s"
                % groups)
        self.groups = groups
        if not config_file:
            # will be opened during configuration
            self.logger.error(
                "No config file provided for initial configuration")
            exit()

        self.config_file = config_file
        self.config = None
        self.alive = True  # used for exiting once the node is stopped
        self.line_controller = None  # stores uid of line controller this module is listening to (to avoid several line controllers)
        self.com_timeout = polling_timeout  # time_out in msec after which poller returns
        self.sim_time = sim_time  # time in msec
        self.inbox = []
        self.outbox = []

        # Node setup
        self.node = Pyre(self.name)
        for key in self.headers:
            self.node.set_header(key, self.headers[key])
        for group in self.groups:
            self.node.join(group)
        #self.node.set_verbose()
        self.node.start()

        # Socket setup
        self.poller = zmq.Poller()
        self.poller.register(self.node.socket(), zmq.POLLIN)

        port = "12911"
        self.zmq_socket = self.ctx.socket(zmq.PUB)
        self.zmq_socket.bind("tcp://*:%s" % port)

        self.run()

    def run(self):
        """ Running loop of this process:
        [COMMUNICATION]     Check communication channels and parse all messages.
        """
        while self.alive:
            try:
                #[COMMUNICATION]
                self.communication()
                #[LOGGING]
                #self.logging()
                time.sleep(1)
            except (KeyboardInterrupt, SystemExit):
                break
        self.node.stop()

    def communication(self):
        """ This function handles the communication """

        # Check if communication is ready
        if not self.poller:
            self.logger.warn("No communication channels yet.")
        # Process input
        items = dict(self.poller.poll(self.com_timeout))
        # Get input from Pyre socket and put it in inbox which is processed in the following steps
        #logger.debug("Start processing incoming messages")
        if self.node.socket() in items and items[
                self.node.socket()] == zmq.POLLIN:
            self.logger.info("Received %d msgs." % len(items))
            #print "msg arrived. inbox len %d" % len(self.inbox)
            msg_frame = self.node.recv()
            msg_type = msg_frame.pop(0)
            peer_uid = uuid.UUID(bytes=msg_frame.pop(0))
            peer_name = msg_frame.pop(0)
            self.logger.info("Msg type: %s" % msg_type)
            self.logger.info("Sender: %s" % peer_name)
            # For shout and whisper take message payload and put it into inbox assuming it is correct
            # For the other zyre msgs create a JSON obj and put that into inbox
            # TODO: add validation
            if msg_type == "SHOUT":
                group = msg_frame.pop(0)
                msg = json.loads(msg_frame.pop(0))
                msg["sender_UUID"] = peer_uid
                msg["sender_name"] = peer_name
                #                self.inbox.append(msg)
                self.outbox.append(msg)
            elif msg_type == "WHISPER":
                msg = json.loads(msg_frame.pop(0))
                msg["sender_UUID"] = peer_uid
                msg["sender_name"] = peer_name
                self.inbox.append(msg)
            # don't care about join and leave messages; if necessary, split to have separate events


#             elif msg_type == "LEAVE" or msg_type == "JOIN":
#                 group = msg_frame.pop(0)
#                 event = json.dumps({"metamodel": "http://www.sherpa-project.eu/examples/sherpa_msgs",
#                                     "model": "http://www.sherpa-project.eu/examples/sherpa_msgs/zyre_events",
#                                     "type": "leave/join",
#                                     "sender_UUID": peer_uid,
#                                     "sender_name": peer_name,
#                                     "payload": {}
#                                     })
#                 self.inbox.append(event)
            elif msg_type == "ENTER":
                headers = json.loads(msg_frame.pop(0))
                event = {
                    "metamodel":
                    "http://www.sherpa-project.eu/examples/sherpa_msgs",
                    "model":
                    "http://www.sherpa-project.eu/examples/sherpa_msgs/zyre_events",
                    "type": "enter",
                    "sender_UUID": peer_uid,
                    "sender_name": peer_name,
                    "payload": {
                        "header": headers
                    }
                }
                self.inbox.append(event)
            elif msg_type == "EXIT":
                event = {
                    "metamodel":
                    "http://www.sherpa-project.eu/examples/sherpa_msgs",
                    "model":
                    "http://www.sherpa-project.eu/examples/sherpa_msgs/zyre_events",
                    "type": "exit",
                    "sender_UUID": peer_uid,
                    "sender_name": peer_name,
                    "payload": {}
                }
                self.inbox.append(event)
        # Process output and send all msgs there until it is empty, but only if a line controller is connected.
        if self.outbox:  #only do if there really is something in the outbox
            #if self.lcsm.sm.curr_state._name == "Idle" or self.lcsm.sm.curr_state._name == "Busy":
            if true:
                self.logger.info(
                    "Start processing messages in outbox. Number of msgs in outbox: %d"
                    % len(self.outbox))
                while self.outbox:
                    # since we assume all msgs conform to the sherpa_msgs JSON model, simply shout them out
                    # TODO: add validation
                    msg = self.outbox.pop()
                    if type(msg) == dict:
                        self.logger.info("outbox msg type: " + msg["type"])
                        self.node.shout("SHERPA", json.dumps(msg))

                        #WM message

                        msg_wm_update = {
                            "@worldmodeltype": "RSGUpdate",
                            "operation": "CREATE",
                            "node": {
                                "@graphtype":
                                "Group",
                                "id":
                                "ff483c43-4a36-4197-be49-de829cdd66c8",
                                "attributes": [
                                    {
                                        "key": "name",
                                        "value": "Task Specification Tree"
                                    },
                                    {
                                        "key": "tst:envtst",
                                        "value": msg
                                    },
                                ],
                            },
                            "parentId": "e379121f-06c6-4e21-ae9d-ae78ec1986a1",
                        }

                        print("===")
                        print(json.dumps(msg_wm_update))
                        self.zmq_socket.send_string(json.dumps(msg_wm_update))

                    else:
                        self.logger.warn(
                            "Message is not a dict! Serialization is done here! Msg: \n"
                            + str(msg))
            else:
                self.logger.info(
                    "Can't send messages in outbox. Module not ready.")