1

I try to use socketCluster with acknowledgment in NodeJS.

I follow the code in this page: https://socketcluster.io/docs/basic-usage/

[Server] Publish to a channel and wait for acknowledgement

(async () => {
  try {
    // Publish data; wait for an acknowledgement from the back end broker (if it exists).
    await agServer.exchange.invokePublish('foo', 'This is some more data');
  } catch (error) {
    // ... Handle potential error if broker does not acknowledge before timeout.
  }
})();

But I don't get an acknowledgment and I don't know what is missing. I have tried uploading the socket cluster server with this option {ackTimeout: 10000}, but it didn't help. How do I know if the message was received?

2 Answers2

0

If my understanding is good, you get an ACK when
await agServer.exchange.invokePublish('foo', 'This is some more data');

is executed and when you do not enter in catch statement.

agServer.exchange.invokePublish()

The ACK is managed under the hood by SocketCluster, you do not have to manage it or to read it. Is my answer useful ?

0

To reply to your last comment @Lior. The "catch" block will be executed if the ACK has not been received. How to properly retry = I don't know. I am not a SocketCluster expert, but it seems there is no automatic mechanism to handle this. You could put a "do / while" loop around the try / catch block (by preventing infinite loop) :

let i = 0;
let callIsSuccessful = false;
do {
  try {
    // Publish data; wait for an acknowledgement from the back end broker (if it     exists).
    await agServer.exchange.invokePublish('foo', 'This is some more data');
    callIsSuccessful = true;
  } catch (error) {
        // ... Handle potential error if broker does not acknowledge before timeout.
  }
} while (i++ < MAX_RETRIES && (!callIsSuccessful))

You could also recall the function which make the publish action, by recursive way :

callingFunction(paramData, currentRetryNumber){
    if(currentRetryNumber >= MAX_RETRIES){
        return;
    }
    try {
        // Publish data; wait for an acknowledgement from the back end broker (if it     exists).
        await agServer.exchange.invokePublish('foo', 'This is some more data');
    } catch (error) {
        callingFunction(paramData, ++currentRetryNumber);
        // ... Handle potential error if broker does not acknowledge before timeout.
    }
}
(async () => {
    callingFunction(paramData, 0);
})();

Is it satisfying ? ;)

  • Thanks, but my issue is that I am not able to get into the catch block. I have tried to get there by sending it to an offline user. But I don't get an error. – Lior Faigenzon Aug 27 '20 at 06:33
  • 1
    Well, there is no problem... With "invokePublish", you are publishing to a channel. The pub/sub concept implies that the producer does'nt know if the message is correctly received by the subscriber(s). What you do here is : You are correctly publishing to a channel, the SC backend do not see any subscription to your channel ("user is offline"), so there is not message sent to the channel, then the backend replies to you "ACK". Because it is an ACK from the Server, not the 1 or N destinated users. If you want to be sure that the user receive the message, do not use channels, but sockets – Issam El Hachimi Aug 27 '20 at 14:01