通过Zeroconf/Bonjour发布的最简单方法是什么?

18 投票
5 回答
12964 浏览
提问于 2025-04-15 17:06

我有一些应用程序想要通过zeroconf让它们变得可见。

  1. 有没有简单的脚本方法可以做到这一点?
  2. 我的网络管理员需要做些什么来启用这个功能吗?

我比较喜欢用Python或者sh脚本。如果有针对Linux和OS X的建议也欢迎提供。

5 个回答

10

或者你可以直接使用bash:

dns-sd -R <Name> <Type> <Domain> <Port> [<TXT>...]

在OS X上,这个默认是可以工作的。对于其他的*类Unix系统,可以查看avahi-publish的手册页(你可能需要通过你喜欢的包管理工具来安装它)。

11

pybonjour 这个库好像没有人在维护了。我现在使用的是 python-zeroconf

pip install zeroconf

下面是我用来向 iOS 设备宣布一个 Twisted-Autobahn WebSocket 的脚本片段:

from zeroconf import ServiceInfo, Zeroconf

class WebSocketManager(service.Service, object):
    ws_service_name = 'Verasonics WebSocket'
    wsPort = None
    wsInfo = None

    def __init__(self, factory, portCallback):
        factory.protocol = BroadcastServerProtocol
        self.factory = factory
        self.portCallback = portCallback
        self.zeroconf = Zeroconf()

    def privilegedStartService(self):
        self.wsPort = reactor.listenTCP(0, self.factory)
        port = self.wsPort.getHost().port

        fqdn = socket.gethostname()
        ip_addr = socket.gethostbyname(fqdn)
        hostname = fqdn.split('.')[0]

        wsDesc = {'service': 'Verasonics Frame', 'version': '1.0.0'}
        self.wsInfo = ServiceInfo('_verasonics-ws._tcp.local.',
                                  hostname + ' ' + self.ws_service_name + '._verasonics-ws._tcp.local.',
                                  socket.inet_aton(ip_addr), port, 0, 0,
                                  wsDesc, hostname + '.local.')
        self.zeroconf.register_service(self.wsInfo)
        self.portCallback(port)

        return super(WebSocketManager, self).privilegedStartService()

    def stopService(self):
        self.zeroconf.unregister_service(self.wsInfo)

        self.wsPort.stopListening()
        return super(WebSocketManager , self).stopService()
3

编辑于2022-02-27:我现在不太确定我之前写的内容是否真的正确。我最近试了一下,虽然程序能跑,但我通过mdns查询却拿不到信息,这说明mDNS可能比我想的要复杂……后续会继续更新……如果你试过这个方法,请留言告诉我是否有效。


虽然这个回答给了你一个正确的方向,但似乎python-zeroconf(版本0.39.4)做了一些改动,导致上面的例子对我来说不再有效。

我觉得一个更简单、独立的答案会更好,所以我来分享一下:

from zeroconf import ServiceInfo, Zeroconf

PORT=8080

zeroconf = Zeroconf()
wsInfo = ServiceInfo('_http._tcp.local.',
                     "myhost._http._tcp.local.",
                     PORT, 0, 0, {"random_key": "1234", "answer": "42"})
zeroconf.register_service(wsInfo)

import time
time.sleep(1000);

请注意,ServiceInfo()中除了PORT以外的内容都是可选的。

你可以同时运行多个这样的程序,它们都会绑定到同一个UDP端口,完全没有问题。

撰写回答