Just a second...

Sending request messages to a session

A client session can send a request message containing typed data directly to a client session. The receiving client session can then send a response message containing typed data. The request and response messages are addressed through the same message path.

A control client session on the left. Diffusion in the centre. Another client session on the right. An arrow representing the request message goes from the control client session through a shape representing the message path inside the Diffusion server and continues to the other client session. An arrow representing the response message goes from the receiving client session back through the message path on the Diffusion server to the control client session.
When a request message is sent to a specific client session and that session responds, the following events occur:
  1. A control client session sends a request message to a client session, specifying the message path to send the message through and the session ID of the client session to send the request message to.
  2. The client session receives the request message through a request stream.
  3. The client session uses a responder to send a response to the request message.
  4. The control client session receives the response.

Both the request message and the response message contain typed values. The messages can contain data of one of the following types: JSON, binary, string, 64-bit integer, or double. The response message is not required to be the same data type as the request it responds to.

Sending a request to a session

Required permissions: send_to_session permission for the specified message path and register_handler permission

Usually, it is a control client session in your organization's backend that sends messages directly to other sessions.

Send the request message specifying the following information:
  • The session ID of the client session to send the request to
  • The message path to send the request and receive the response through
  • The request message
  • The datatype of the request message
  • The datatype of the response message
JavaScript
control.messages.sendRequest('foo', 'Hello client', session_id, diffusion.datatypes.json(), diffusion.datatypes.json())
Apple
[session.messagingControl sendRequest:[PTDiffusionPrimitive requestWithLongLong:42]
                          toSessionId:sessionId
                                 path:message_path
         int64NumberCompletionHandler:^(NSNumber *response, NSError* error)
{
    if (error) {
        NSLog(@"Failed to send to %@. Error: %@", message_path, error);
    } else {
        NSLog(@"Received response: %@", response);
    }
}];
Java and Android
//Establish client session and control session
    final Session control = Diffusion.sessions().principal("control").password("password").open("ws://localhost:8080");
    final Session client = Diffusion.sessions().principal("client").password("password").open("ws://localhost:8080");
                        
    //Obtain the Messaging and MessagingControl features
    final MessagingControl messagingControl = control.feature("MessagingControl.class");
    final Messaging messaging = client.feature(Messaging.class);
    
    //Create a JSON object to send as a request
    final JSON request = Diffusion.dataTypes().json().fromJsonString("\"hello\"");
    
    //Create a local request stream for the client to receive direct requests from the control session
    messaging.setRequestStream("foo", JSON.class, JSON.class, requestStream);
    
    //Send the request to a message path "foo" and wait for (at most) 5 seconds until the response is received.
    final JSON response = messagingControl.sendRequest(client.getSessionId(), "foo", request, JSON.class, JSON.class).get(5, TimeUnit.SECONDS);

Responding to messages sent to a session

Required permissions: send_to_message_handler for the specified message path

Define a request stream to receive and respond to request messages that have a specific data type.

JavaScript
var handler = {
    onRequest : function(request, context, responder) {
        ....
        responder.respond(response);
    },
    onError : function(error) {},
    onClose : function() {}
}
Apple
@interface NumberRequestStreamDelegate : NSObject<PTDiffusionNumberRequestStreamDelegate>
@end

@implementation NumberRequestStreamDelegate
- (void)    diffusionStream:(nonnull PTDiffusionStream *)stream
didReceiveRequestWithNumber:(nullable NSNumber *)number
                  responder:(nonnull PTDiffusionResponder *)responder
{
    // Do something when a request is received.
}

- (void)diffusionStream:(nonnull PTDiffusionStream *)stream
       didFailWithError:(nonnull NSError *)error
{
    // Do something if the stream fails.
}

- (void)diffusionDidCloseStream:(nonnull PTDiffusionStream *)stream
{
    // Do something if the stream closes.
}
Java and Android
private final class JSONRequestStream implements Messaging.RequestStream<JSON, JSON> {

    @Override
    public void onClose() {
        ....
    }

    @Override
    public void onError(ErrorReason errorReason) {
        ....
    }

    @Override
    public void onRequest(String path, JSON request, Responder<JSON> responder) {
        ....
    }
}

Add the request stream against a message path. You can only add one request stream for each message path.

JavaScript
control.messages.setRequestStream("foo", diffusion.datatypes.json(), diffusion.datatypes.json(), request_stream);
Apple
// Ensure to maintain a strong reference to your request stream as it
// is referenced weakly by the Diffusion client library.
NumberRequestStreamDelegate *delegate = [NumberRequestStreamDelegate new];
PTDiffusionRequestStream *requestStream = [PTDiffusionPrimitive int64RequestStreamWithDelegate:delegate];
[session.messaging setRequestStream:requestStream forPath:message_path];
Java and Android
messaging.setRequestStream("foo", JSON.class, JSON.class, requestStream);

One-way messaging to a session

Note: One-way messaging was deprecated in Diffusion™ Cloud 6.2 and will be removed in a future release. Use request-response messaging instead.

Diffusion Cloud also provides a legacy capability to send one-way messages to a session. This message is not typed. The receiving session cannot respond directly to this message.

Send a one-way message specifying the following information:
  • The session ID of the client session to send the message to
  • The message path to send the message through
  • The message content
  • Any additional options, such as headers or a message priority
JavaScript
session.messages.send('message_path', content, session_id);
Apple
[session.messagingControl sendToSessionId:sessionId
                                     path:message_path
                                  message:[[PTDiffusionBytes alloc] initWithData:data]
              completionHandler:^(NSError* error)
{
    if (error) {
        NSLog(@"Failed to send to %@. Error: %@", message_path, error);
    } else {
        NSLog(@"Sent");
    }
}];
Java and Android
session.feature(MessagingControl.class).send(session_id, message_path, content, send_callback);
.NET
session.MessagingControl.Send( session_id, message_path, content, send_callback );
C
SEND_MSG_TO_SESSION_PARAMS_T params = {
        .topic_path = message_path,
        .session_id = *session_id,
        .content = *content,
        .options.headers = headers,
        .options.priority = CLIENT_SEND_PRIORITY_NORMAL,
        .on_send = on_send,
        .context = context
};

/*
 * Send the message and wait for the callback to acknowledge
 * delivery.
 */
send_msg_to_session(session, params);

To receive a message sent directly to a client session, that client session must add a message stream to receive messages sent through that message path:

JavaScript
// Create with a default listener function
session.messages.listen('message_path', function(message) {
    // Do something with the message
});
Apple
@interface MessageStreamDelegate : NSObject <PTDiffusionMessageStreamDelegate>
@end

@implementation MessageStreamDelegate

-(void)          diffusionStream:(PTDiffusionStream *)stream
    didReceiveMessageOnTopicPath:(NSString *)path
                         content:(PTDiffusionContent *)content
                         context:(PTDiffusionReceiveContext *)context
{
    // Do something when a message is received.
}

-(void)diffusionDidCloseStream:(PTDiffusionStream *)stream
{
    // Do something if the stream closes.
}

-(void)diffusionStream:(PTDiffusionStream *)stream didFailWithError:(NSError *)error
{
    // Do something if the stream fails.
}

// ... in later code 

// Ensure to maintain a strong reference to your message stream delegate as it
// is referenced weakly by the Diffusion client library.
MessageStreamDelegate *const delegate = [MessageStreamDelegate new];

// Create a locally evaluated topic selector specifying the messaging paths that
// should be captured by the stream.
PTDiffusionTopicSelector *const topicSelector =
    [PTDiffusionTopicSelector topicSelectorWithExpression:message_path];

// Use the Messaging feature to add a local stream using your delegate against
// the topic selector.
[session.messaging addMessageStreamWithSelector:topicSelector
                                       delegate:delegate];
Java and Android
session.feature(Messaging.class).addMessageStream(message_path, stream);
.NET
session.Messaging.AddMessageStream( message_path, stream );
C
/*
 * Register a listener for messages on the given path.
 */
MSG_LISTENER_REGISTRATION_PARAMS_T listener_params = {
        .topic_path = message_path,
        .listener = on_stream_message,
        .context = context
};
register_msg_listener(session, listener_params);

You can also add a fallback message stream to receive messages sent through any message path that does not have a stream add against it:

Apple
// Ensure to maintain a strong reference to your message stream delegate as it
// is referenced weakly by the Diffusion client library.
MessageStreamDelegate *const delegate = [MessageStreamDelegate new];

// Use the Messaging feature to add a local fallback stream using your delegate.
[session.messaging addFallbackMessageStreamWithDelegate:delegate];
Java and Android
messaging.addFallbackMessageStream(message_stream);
.NET
session.Messaging.AddFallbackMessageStream( stream );
C
 /*
 * Register a listener for any other messages.
 * (.topic_path is NULL).
 */
MSG_LISTENER_REGISTRATION_PARAMS_T global_listener_params = {
        .listener = on_stream_message,
        .context = context
};
register_msg_listener(session, global_listener_params);

To respond to this message, the receiving client session sends a separate message to the message path through which the received message was sent. For more information, see One-way messaging to a path. However, if multiple client sessions have added messages handlers on this message path, the one-way message sent in response is not guaranteed to be received by the client session that sent the original one-way message.