Гибкое, надежное и переносимое обнаружение сервисов

StackOverflow https://stackoverflow.com/questions/568028

Вопрос

Я ищу способ для клиентов в локальной сети найти все экземпляры моего серверного приложения без какой-либо настройки.Вместо того чтобы взламывать что-то самому, я бы хотел использовать существующее решение.Лично мне нужно, чтобы это было сделано на Python, но я был бы рад услышать о решениях на любом другом языке.

Так почему же я не использую авахи или OpenSLP ( Открытый SLP ) или какой - то другой Нулевой Конф/SLP решение?Ну, есть пара дополнительных критериев, и у меня сложилось впечатление, что ни одна из вышеупомянутых систем им не соответствует.

Я ищу решение, которое является:

  • Гибкий.Для этого не должны требоваться права суперпользователя, т.е.используйте только порты>1024.
  • Твердый.Он должен разрешать несколько служб одного и того же и разных типов служб на одном компьютере и продолжать рекламировать службы, даже когда экземпляр, запустивший сервер рекламы, останавливается или выходит из строя.
  • Портативный.Он должен выполняться почти везде или, по крайней мере, на * BSD, Debian / gentoo / RedHat / SuSe Linux, Mac OS X, Solaris и Windows NT.
  • Свет.В идеале, один скрипт на Python был бы целым решением.Меня ни в малейшей степени не интересует автоконфигурация адреса или что-то в этом роде, хотя я бы неохотно согласился с решением, которое имеет множество функций, которые мне не нужны.Более того, любая одноразовая настройка строго запрещена.

Я ожидал чего-то подобного:

def registerService(service): # (type, port)
    if listen(multicast, someport):
        if fork() == child:
            services = [service]
            for q in queriesToMe():
                if q == DISCOVERY:
                    answer(filter(q.criteria, services))
                elif q == ADVERTISE and q.sender == "localhost":
                    services.append(q.service)
    else:
        advertiseAt("localhost", service)
Это было полезно?

Решение

Я написал приложение / библиотеку (в настоящее время интерфейс Python и CLI), которая соответствует всем этим критериям.Это называется минусконф.Оказывается, в разветвлении даже нет необходимости.

Другие советы

Для обнаружения узла в локальной сети я использовал многоадресную рассылку Twisted и UDP.Надеюсь, вам это тоже поможет.

Ссылка на документацию twisted, которая объясняет, как это сделать:https://twistedmatrix.com/documents/current/core/howto/udp.html#auto3

Вот базовая реализация сервера / клиента, основанная на коде twisted.Он отвечает сам, если вы запустите его один раз, но весь проверочный код и дополнительные функции были удалены, чтобы упростить чтение.

from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor

class MulticastPingPong(DatagramProtocol):
    MULTICAST_ADDR = ('228.0.0.5', 8005)
    CMD_PING = "PING"
    CMD_PONG = "PONG"

    def startProtocol(self):
        """
        Called after protocol has started listening.
        """
        # Set the TTL>1 so multicast will cross router hops:
        self.transport.setTTL(5)
        # Join a specific multicast group:
        self.transport.joinGroup(self.MULTICAST_ADDR[0])

        self.send_alive()

    def send_alive(self):
        """
        Sends a multicast signal asking for clients.
        The receivers will reply if they want to be found.
        """
        self.transport.write(self.CMD_PING, self.MULTICAST_ADDR)

    def datagramReceived(self, datagram, address):
        print "Datagram %s received from %s" % (repr(datagram), repr(address))

        if datagram.startswith(self.CMD_PING):
            # someone publishes itself, we reply that we are here
            self.transport.write(self.CMD_PONG, address)
        elif datagram.startswith(self.CMD_PONG):
            # someone reply to our publish message
            print "Got client: ", address[0], address[1]


if __name__ == '__main__':
    reactor.listenMulticast(8005, MulticastPingPong(), listenMultiple=True)
    reactor.run()

Я предполагаю, что у вас есть контроль над клиентскими приложениями, а не только над серверным приложением, и в этом случае Поджигатель может хорошо сработать для вас.

Гибкий: использует непривилегированные порты.

Твердый: Он был в хорошем состоянии в течение многих лет.

Портативный: чистый Python и хорошо протестирован на нескольких платформах.

Свет: Я думаю, что Поджигатель - это свет для того, что вы получаете.Может быть, запросить один скрипт на Python нереально для службы сетевых именований?

Даже если вы на самом деле не хотите использовать парадигму "удаленного объекта" Pyro, вы все равно могли бы просто воспользоваться его службой именования.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top