Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Receive all priorities in callback, not just the highest #50

Open
andrewyager opened this issue Jun 6, 2024 · 2 comments
Open

Receive all priorities in callback, not just the highest #50

andrewyager opened this issue Jun 6, 2024 · 2 comments

Comments

@andrewyager
Copy link
Contributor

I have an application where it would be helpful to receive all priorities, rather than just the highest priority packets in the callback; because I want to be able to make some alternate decisions about what to do with packets based on the incoming priority and/or source name.

Would it be possible to add a flag to the handler that impacts the code at

if not self.is_legal_priority(tmp_packet):
to allow all priorities to be passed on?

Perhaps a more elegant solution might be also to define a handler that could pass for every packet, and a different handler that only passes on the highest priority packets (as is the behaviour now)?

@Hundemeier
Copy link
Owner

It would be possible to add a trigger (like universe_all_priorities) that could accept a callback. However, the whole purpose of this library is that the library users do not need to implement all the complicated sequence number and priority handling themselves. Therefore I'm hesitant to add this feature, even though it would not be too complicated to add.

If you really want to have low level access, you could take advantage of the internal components of this library, by implementing your own ReceiverSocketListener:

from sacn.messages.data_packet import DataPacket, calculate_multicast_addr
from sacn.receiving.receiver_socket_base import ReceiverSocketBase, ReceiverSocketListener
from sacn.receiving.receiver_socket_udp import ReceiverSocketUDP

class MyReceiverHandler(ReceiverSocketListener):
    def __init__(self, bind_address: str = '0.0.0.0', bind_port: int = 5568):
        self.socket: ReceiverSocketBase = ReceiverSocketUDP(self, bind_address, bind_port)

    def on_data(self, data: bytes, current_time: float) -> None:
        try:
            packet = DataPacket.make_data_packet(data)
        except TypeError:  # try to make a DataPacket. If it fails just ignore it
            return
        # Do something with the DataPacket 'packet'.
        # The "on_data" method is called for each received UDP packet, so this equals "raw" data.
        print(packet)

    def on_periodic_callback(self, current_time: float) -> None:
        # ignore for now
        pass

    def join_multicast(self, universe: int) -> None:
        self.socket.join_multicast(calculate_multicast_addr(universe))

    def leave_multicast(self, universe: int) -> None:
        self.socket.leave_multicast(calculate_multicast_addr(universe))

    def start(self) -> None:
        self.stop()  # stop an existing thread
        self.socket.start()

    def stop(self) -> None:
        self.socket.stop()

and use it like this:

receiver = MyReceiverHandler()
receiver.start()  # start the receiving thread
receiver.join_multicast(1)

time.sleep(15)  # receive for 15 seconds

receiver.leave_multicast(1)
receiver.stop()

@andrewyager
Copy link
Contributor Author

I'm happy with this approach. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants