2

Is it possible and if so how to archive it that one application using libmosquitto get messages from one broker and publish it to another?

Schematics

Its pretty simple to just change topic in mosquito_publish function, but set of broker takes place in

mosquitto_connect(mosq, "localhost",1883 , 60); 

Running mosquitto_connet second time e.g.

 mosquitto_connect(mosq, "mqtt.example.io",1883 , 60); 

ends up connecting to last one.

I tried to create two mosquitto structs but I dont know how to inform second one about message form subbed channel in order to get info from it, change it and push to proper broker.

hardillb
  • 54,545
  • 11
  • 67
  • 105
pzydziak
  • 89
  • 1
  • 2
  • 10
  • of course the other question here is why you can't just bridge the 2 brokers, instead of using a client in the middle? – hardillb May 31 '17 at 09:25
  • I have to modify content of messages to publish based on messages from first one broker. – pzydziak May 31 '17 at 09:29

4 Answers4

4

Something like this should do the job (I've not tested it though). You'll have to add error checking.

#include <stdio.h>
#include <mosquitto.h>


void on_connect1(struct mosquitto *mosq, void *obj, int result)
{
    int rc = MOSQ_ERR_SUCCESS;

    if(!result){
        mosquitto_subscribe(mosq, NULL, "/v1/topic1", 0);
    }else{
        fprintf(stderr, "%s\n", mosquitto_connack_string(result));
    }
}

void on_message1(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message)
{
    struct mosquitto *mosq2 = (struct mosquitto *)obj;

    mosquitto_publish(mosq, NULL, "/v1/topic2", message->payloadlen, message->payload, message->qos, message->retain);
}

int main(int argc, char *argv[])
{
    struct mosquitto *mosq1, *mosq2;

    mosquitto_lib_init();

    mosq2 = mosquitto_new(NULL, true, NULL);
    mosq1 = mosquitto_new(NULL, true, mosq2);

    mosquitto_connect_callback_set(mosq1, on_connect1);
    mosquitto_message_callback_set(mosq1, on_message1);

    mosquitto_connect(mosq2, "mqtt.example.io", 1883, 60);
    mosquitto_connect(mosq1, "localhost", 1883, 60);

    mosquitto_loop_start(mosq2);
    mosquitto_loop_forever(mosq1, -1, 1);

    mosquitto_destroy(mosq1);
    mosquitto_destroy(mosq2);

    mosquitto_lib_cleanup();

    return 0;
}
ralight
  • 11,033
  • 3
  • 49
  • 59
  • Thanks, I already managed that problem, but thanks to your answer I know how to use third mosquitto_new arg. – pzydziak May 31 '17 at 09:12
1

Yes,

You need two totally separate instances of client. Which means two separate instances the mosquitto structure returned by the mosquitto_new() function. One for each broker.

At the moment you are re-using the same structure so it is only holding the details of the last call to mosquitto_connect()

hardillb
  • 54,545
  • 11
  • 67
  • 105
0

This command line using mosquitto can do the job:

mosquitto_sub -h localhost -t '#'  | {  while [ 1 -lt 2 ] ;   do   read message ;   if [[ "$message" != "$prev_message" ]]; then  mosquitto_pub -h localhost -t "tenewtest" -m "$message" ; prev_message=$message ; fi ;    done ;  }
David Buck
  • 3,752
  • 35
  • 31
  • 35
Dev
  • 1
  • You missed the requirement to modify the message on the way through the middle (in the comments under the question) – hardillb May 19 '20 at 14:08
  • Yes, it is just a pass through. The publish can be done to a different server. You can also change the message after the read. – Dev May 19 '20 at 19:51
0

If you simply want to forward the messages, then there is a 'bridge' functionality in mosquitto broker. It makes it easier through configuration. It has a feature where you can specify the topics you want to forward & also authentication options. It is quite feature rich.

John_Avi_09
  • 323
  • 1
  • 9