-1

My question is simple. I want to know how to fix port client has.

According to Eclipse documents and IBM's, User has to fix broker address(this is absolutely natural). But There are no mentions about way of how to fix client site port. https://www.ibm.com/support/knowledgecenter/en/SSFKSJ_7.5.0/com.ibm.mq.javadoc.doc/WMQMQxrClasses/com/ibm/micro/client/mqttv3/MqttClient.html

MQTT must be also on TCP Layer, so I think it's possible to fix port.

If you have ideas, let me know. Thanks

Jason
  • 371
  • 5
  • 9
  • 17

2 Answers2

1

You don't specify the client's port, as it is choosen by the OS, just as with any client to server connection, like you don't need to do that with a HTTP connection either.

You specify the IP address and port of the MQTT broker in the URL you pass in the form of tcp://<address>:<port>, for example tcp://localhost:4922.

The code below shows how I connect a Paho client in an OSGi context, where all connections parameters are retrieved from the bundle context.

private void configureMqtt(BundleContext context) throws IOException, MqttException {
    String broker = context.getProperty("mqtt.broker");

    if (broker == null) {
        throw new ServiceException("Define mqtt.broker");
    }

    String client = context.getProperty("mqtt.clientname");

    if (client == null) {
        throw new ServiceException("Define mqtt.clientname");
    }

    String dir = context.getProperty("mqtt.persistence");

    if (dir == null) {
        dir = "mqtt";
    };

    File directory = context.getDataFile(dir);
    directory.mkdirs();

    logger.config(() -> String.format("MQTT broker: %s, clientname: %s persistence: %s", broker, client, directory.getAbsolutePath()));
    connectOptions = new MqttConnectOptions();
    connectOptions.setWill(GARAGE + "/door", new byte[0], 0, true);

    String ka = context.getProperty("mqtt.keepalive");
    if (ka != null) {
        connectOptions.setKeepAliveInterval(Integer.valueOf(ka));
    }

    persistence = new MqttDefaultFilePersistence(directory.getCanonicalPath());
    mqttClient = new MqttAsyncClient(broker, client, persistence);
    mqttClient.setCallback(this);
    connect();
}

private void connect() {
    logger.fine("Connecting to MQTT broker");

    try {
        IMqttToken token = mqttClient.connect(connectOptions);

        IMqttActionListener listener = new IMqttActionListener() {
            @Override
            public void onSuccess(IMqttToken asyncActionToken) {
                logger.log(Level.INFO, "Connected to MQTT broker");
            }

            @Override
            public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                logger.log(Level.WARNING, "Could not connect to MQTT broker, retrying in 3 seconds", exception);
                service.schedule(this::connect, 3, TimeUnit.SECONDS);
            }
        };

        token.setActionCallback(listener);
    } catch (MqttException e) {
        logger.log(Level.SEVERE, "Cannot reconnect to MQTT broker, giving up", e);
    }
}
M. le Rutte
  • 3,525
  • 3
  • 18
  • 31
1

Under normal circumstance you don't set the source port for TCP connections, you just let the OS pick a random free port.

If you fix the source port then you can only ever run 1 instance of the client at a time on a given machine and if you get a connection failure you have to wait for the TCP stack to free that socket up again before you can reconnect.

If for some reason you REALLY NEED to fix the source port then you could probably write a custom javax.net.SocketFactory implementation that you can hard code the source port. Then pass this in as part of the MQTTConnectOptions object, but again I'm really struggling to come up with a reason this is a good idea.

hardillb
  • 54,545
  • 11
  • 67
  • 105