Skip to content

Instantly share code, notes, and snippets.

@jpmens
Created November 13, 2013 07:48
Show Gist options
  • Save jpmens/7445275 to your computer and use it in GitHub Desktop.
Save jpmens/7445275 to your computer and use it in GitHub Desktop.
Add support for DNS SRV records to Mosquitto's mosquitto.py Code placed in the public domain, by Jan-Piet Mens, November 2013
--- mosquitto.py.orig 2013-11-12 11:41:17.000000000 +0100
+++ mosquitto.py 2013-11-13 08:44:31.000000000 +0100
@@ -45,6 +45,11 @@
import sys
import threading
import time
+HAVE_DNS = True
+try:
+ import dns.resolver
+except ImportError:
+ HAVE_DNS = False
MOSQUITTO_MAJOR=1
MOSQUITTO_MINOR=2
@@ -568,6 +573,45 @@
self.connect_async(host, port, keepalive, bind_address)
return self.reconnect()
+ def connect_srv(self, domain=None, keepalive=60, bind_address=""):
+ """Connect to a remote broker.
+
+ domain is the DNS domain to search for SRV records; if None,
+ try to determine local domain name.
+ keepalive and bind_address are as for connect()
+ """
+
+ if HAVE_DNS == False:
+ raise ValueError('No DNS resolver library found.')
+
+ if domain is None:
+ domain = socket.getfqdn()
+ domain = domain[domain.find('.') + 1:]
+
+ try:
+ rr = '_mqtt._tcp.%s' % domain
+ if self._ssl is not None:
+ rr = '_mqtts._tcp.%s' % domain
+ answers = []
+ for answer in dns.resolver.query(rr, dns.rdatatype.SRV):
+ address = (answer.target.to_text()[:-1], answer.port)
+ answers.append((address, answer.priority, answer.weight))
+ except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer, dns.resolver.NoNameservers):
+ raise ValueError("No answer/NXDOMAIN for SRV in %s" % (domain))
+
+ # FIXME: doesn't account for weight
+ for answer in answers:
+ address, prio, weight = answer
+ host, port = address
+
+ try:
+ # print "trying: ", host, port
+ return self.connect(host, port, keepalive, bind_address)
+ except:
+ pass
+
+ raise ValueError("No SRV hosts responded")
+
def connect_async(self, host, port=1883, keepalive=60, bind_address=""):
"""Connect to a remote broker asynchronously. This is a non-blocking
connect call that can be used with loop_start() to provide very quick
#!/usr/bin/python
import mosquitto
def on_connect(mosq, obj, rc):
print "Connected to %s:%d" % (mosq._host, mosq._port)
def on_message(mosq, obj, msg):
print(msg.topic+" "+str(msg.qos)+" "+str(msg.payload))
def on_subscribe(mosq, obj, mid, granted_qos):
print("Subscribed: "+str(mid)+" "+str(granted_qos))
# If you want to use a specific client id, use
# mqttc = mosquitto.Mosquitto("client-id")
# but note that the client id must be unique on the broker. Leaving the client
# id parameter empty will generate a random id for you.
mqttc = mosquitto.Mosquitto()
mqttc.on_message = on_message
mqttc.on_connect = on_connect
mqttc.on_subscribe = on_subscribe
mqttc.connect_srv("mosquitto.org", 60)
mqttc.subscribe("$SYS/broker/version", 0)
rc = 0
while rc == 0:
rc = mqttc.loop()
print("rc: "+str(rc))
@jpmens
Copy link
Author

jpmens commented Nov 13, 2013

IANA specifies secure-mqtt (not mqtts) for port 8883

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment