• Login
  • Register
  • Login Register
    Login
    Username/Email:
    Password:
    Or login with a social network below
  • Forum
  • Website
  • GitHub
  • Status
  • Translation
  • Features
  • Team
  • Rules
  • Help
  • Feeds
User Links
  • Login
  • Register
  • Login Register
    Login
    Username/Email:
    Password:
    Or login with a social network below

    Useful Links Forum Website GitHub Status Translation Features Team Rules Help Feeds
    Jellyfin Forum Development Client Development Help needed for local server discovery (UDP Broadcast response)

     
    • 0 Vote(s) - 0 Average

    Help needed for local server discovery (UDP Broadcast response)

    Writing a Python/GTK client, working on local server discovery
    GeoffreyCoulaud
    Offline

    Junior Member

    Posts: 2
    Threads: 1
    Joined: 2023 Oct
    Reputation: 0
    #1
    2023-10-02, 08:26 PM (This post was last modified: 2023-10-02, 09:59 PM by GeoffreyCoulaud. Edited 2 times in total. Edit Reason: Added wireshark screenshot )
    Hello!

    I've been working for a few days on a Python/GTK/LibAdwaita client for Jellyfin, for fun mainly.
    Here is the repo if anyone is curious (very early stage)

    I need a little bit of help with local server discovery.
    The general networking docs specify that servers can be discovered by broadcasting "Who is JellyfinServer?" on 7359 UDP.
    This does work, by analyzing the network with wireshark I can see the expected response.
    However, I can't get a response message in python with the socket opened to broadcast.
    But if I hardcode the local Jellyfin server address instead of the interface multicast address, then I can get a response fine.

    I've read online that multicast could be more appropriate here, but I don't understand which parameters to use for it. (which multicast group, and why?)

    Can anyone give me a little bit of advice here?

    (UPDATE) I've attached a Wireshark capture of UDP on the Jellyfin server IP.
    On it, we can see that the response does arrive to my machine. The destination port changes everytime tho, that is intriguing.

    Extract of the Python code (github permalink) :
    Code:
    def detect_servers_thread_func(self) -> None:
        for name, address_info_list in psutil.net_if_addrs().items():
            for address_info in address_info_list:
                if (
                    address_info.family not in (AF_INET, AF_INET6)
                    or address_info.broadcast is None
                ):
                    continue
                # TODO Run async
                self.detect_servers_on_interface(
                    name, address_info.family, address_info.broadcast
                )

    def detect_servers_on_interface(
        self,
        interface_name: str,
        address_family: socket.AddressFamily,
        broadcast_address: str,
    ) -> None:
        MSG_ENCODING = "utf-8"
        RECV_BUFFER_SIZE = 4096
        JELLYFIN_DISCOVER_PORT = 7359
        DISCOVER_SEND_TIMEOUT_SECONDS = 5
        # TODO use 30 seconds when not testing
        DISCOVER_RECV_TIMEOUT_SECONDS = 5

        with socket.socket(
            family=address_family, type=SOCK_DGRAM, proto=IPPROTO_UDP
        ) as sock:
            logging.debug(
                "Discovering servers on %s (%s) %s",
                interface_name,
                address_family,
                broadcast_address,
            )

            # Prepare sockets
            interface_name_buffer = bytearray(interface_name, encoding="utf-8")
            sock.setsockopt(SOL_SOCKET, SO_BINDTODEVICE, interface_name_buffer)
            sock.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
            sock.settimeout(DISCOVER_SEND_TIMEOUT_SECONDS)

            # Broadcast discovery message
            msg = bytearray("Who is JellyfinServer?", encoding=MSG_ENCODING)
            try:
                sock.sendto(msg, (broadcast_address, JELLYFIN_DISCOVER_PORT))
            except TimeoutError:
                logging.error("Server discovery broadcast send timed out")
                return

            # Listen for responses
            start = time.time()
            elapsed = 0
            logging.debug("Listening for server responses")
            while elapsed < DISCOVER_RECV_TIMEOUT_SECONDS:
                sock.settimeout(DISCOVER_RECV_TIMEOUT_SECONDS - elapsed)
                try:
                    (data, address_info) = sock.recvfrom(RECV_BUFFER_SIZE)
                except TimeoutError:
                    logging.info("Server discovery receive timed out")
                    break
                msg = data.decode(encoding=MSG_ENCODING)
                # TODO handle response properly
                logging.debug("Response from %s: %s", address_info, msg)
                elapsed = time.time() - start


    Attached Files Thumbnail(s)
       
    GeoffreyCoulaud
    Offline

    Junior Member

    Posts: 2
    Threads: 1
    Joined: 2023 Oct
    Reputation: 0
    #2
    2023-10-03, 02:55 PM
    Update: I tried spinning up a test Jellyfin server with docker on my local machine, and it does get picked up. This makes me think that it may be a network configuration issue? I'd love a hint to what could be misconfigured.
    « Next Oldest | Next Newest »

    Users browsing this thread: 1 Guest(s)


    • View a Printable Version
    • Subscribe to this thread
    Forum Jump:

    Home · Team · Help · Contact
    © Designed by D&D - Powered by MyBB
    L


    Jellyfin

    The Free Software Media System

    Linear Mode
    Threaded Mode