From 3aa698d02354333673bdd5dd9b3bcb4515f4932b Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 29 Dec 2015 20:15:00 +0000 Subject: [PATCH] Add -U to mosquitto_sub for unsubscribing from topics. --- ChangeLog.txt | 1 + client/client_shared.c | 27 +++++++++++++++++++++++ client/client_shared.h | 2 ++ client/sub_client.c | 6 +++++- man/mosquitto_sub.1.xml | 47 +++++++++++++++++++++++++++++++++++++++-- 5 files changed, 80 insertions(+), 3 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 2ca432d3..2f995431 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -33,6 +33,7 @@ Client library: Client: - Add -x to mosquitto_sub for printing the payload in hexadecimal format. +- Add -U to mosquitto_sub for unsubscribing from topics. 1.4.4 - 20150916 diff --git a/client/client_shared.c b/client/client_shared.c index 8d9bbddf..82017a5b 100644 --- a/client/client_shared.c +++ b/client/client_shared.c @@ -83,6 +83,12 @@ void client_config_cleanup(struct mosq_config *cfg) } free(cfg->filter_outs); } + if(cfg->unsub_topics){ + for(i=0; iunsub_topic_count; i++){ + free(cfg->unsub_topics[i]); + } + free(cfg->unsub_topics); + } #ifdef WITH_SOCKS free(cfg->socks5_host); free(cfg->socks5_username); @@ -556,6 +562,27 @@ int client_config_line_proc(struct mosq_config *cfg, int pub_or_sub, int argc, c cfg->filter_outs[cfg->filter_out_count-1] = strdup(argv[i+1]); } i++; + }else if(!strcmp(argv[i], "-U") || !strcmp(argv[i], "--unsubscribe")){ + if(pub_or_sub == CLIENT_PUB){ + goto unknown_option; + } + if(i==argc-1){ + fprintf(stderr, "Error: -U argument given but no unsubscribe topic specified.\n\n"); + return 1; + }else{ + if(mosquitto_sub_topic_check(argv[i+1]) == MOSQ_ERR_INVAL){ + fprintf(stderr, "Error: Invalid unsubscribe topic '%s', are all '+' and '#' wildcards correct?\n", argv[i+1]); + return 1; + } + cfg->unsub_topic_count++; + cfg->unsub_topics = realloc(cfg->unsub_topics, cfg->unsub_topic_count*sizeof(char *)); + if(!cfg->unsub_topics){ + fprintf(stderr, "Error: Out of memory.\n"); + return 1; + } + cfg->unsub_topics[cfg->unsub_topic_count-1] = strdup(argv[i+1]); + } + i++; #ifdef WITH_TLS }else if(!strcmp(argv[i], "--tls-version")){ if(i==argc-1){ diff --git a/client/client_shared.h b/client/client_shared.h index caa20b3e..04d42346 100644 --- a/client/client_shared.h +++ b/client/client_shared.h @@ -77,6 +77,8 @@ struct mosq_config { bool no_retain; /* sub */ char **filter_outs; /* sub */ int filter_out_count; /* sub */ + char **unsub_topics; /* sub */ + int unsub_topic_count; /* sub */ bool verbose; /* sub */ bool eol; /* sub */ bool hex_output; /* sub */ diff --git a/client/sub_client.c b/client/sub_client.c index 453aaff1..e4868449 100644 --- a/client/sub_client.c +++ b/client/sub_client.c @@ -108,6 +108,9 @@ void my_connect_callback(struct mosquitto *mosq, void *obj, int result) for(i=0; itopic_count; i++){ mosquitto_subscribe(mosq, NULL, cfg->topics[i], cfg->qos); } + for(i=0; iunsub_topic_count; i++){ + mosquitto_unsubscribe(mosq, NULL, cfg->unsub_topics[i]); + } }else{ if(result && !cfg->quiet){ fprintf(stderr, "%s\n", mosquitto_connack_string(result)); @@ -142,7 +145,7 @@ void print_usage(void) mosquitto_lib_version(&major, &minor, &revision); printf("mosquitto_sub is a simple mqtt client that will subscribe to a single topic and print all messages it receives.\n"); printf("mosquitto_sub version %s running on libmosquitto %d.%d.%d.\n\n", VERSION, major, minor, revision); - printf("Usage: mosquitto_sub [-c] [-h host] [-k keepalive] [-p port] [-q qos] [-R] -t topic ...\n"); + printf("Usage: mosquitto_sub [-c] [-h host] [-k keepalive] [-p port] [-q qos] [-R] {-t topic ... | -U topic ...}\n"); printf(" [-C msg_count] [-T filter_out]\n"); #ifdef WITH_SRV printf(" [-A bind_address] [-S]\n"); @@ -185,6 +188,7 @@ void print_usage(void) printf(" -t : mqtt topic to subscribe to. May be repeated multiple times.\n"); printf(" -T : topic string to filter out of results. May be repeated.\n"); printf(" -u : provide a username (requires MQTT 3.1 broker)\n"); + printf(" -U : unsubscribe from a topic. May be repeated.\n"); printf(" -v : print published messages verbosely.\n"); printf(" -V : specify the version of the MQTT protocol to use when connecting.\n"); printf(" Can be mqttv31 or mqttv311. Defaults to mqttv31.\n"); diff --git a/man/mosquitto_sub.1.xml b/man/mosquitto_sub.1.xml index 22d08eeb..aff023d9 100644 --- a/man/mosquitto_sub.1.xml +++ b/man/mosquitto_sub.1.xml @@ -63,7 +63,10 @@ socks-url protocol-version filter-out - message-topic + + unsub-topic + message-topic + mosquitto_sub @@ -76,8 +79,14 @@ Description mosquitto_sub is a simple MQTT version 3.1.1 - client that will subscribe to a topic and print the messages that + client that will subscribe to topics and print the messages that it receives. + In addition to subscribing to topics, + mosquitto_sub can filter out received messages + so they are not printed (see the option) or + unsubscribe from topics (see the option). + Unsubscribing from topics is useful for clients connecting with + clean session set to false. @@ -406,6 +415,40 @@ argument. + + + + + A topic that will be unsubscribed from. This may be + used on its own or in conjunction with the + option and only makes sense + when used in conjunction with + . + If used with then + subscriptions will be processed before + unsubscriptions. + Note that it is only possible to unsubscribe from + subscriptions that have previously been made. It is not + possible to punch holes in wildcard subscriptions. For + example, subscribing to and + then unsubscribing from + as shown below + will still result in messages matching the + being delivered + to the client. + + mosquitto_sub -t sensors/# -U sensors/+/temperature -v + + + Note also that because retained messages are + published by the broker on receipt of a SUBSCRIBE + command, subscribing and unsubscribing to the same + topic may result in messages being received at the + client. + + This option may be repeated to unsubscribe from multiple topics. + +