Sending request messages to a message path
A client session can send a request message containing typed data to a message path. One or more client sessions can register to handle messages sent to that message path. The handling client session can then send a response message containing typed data. The response message is sent to the requesting client session directly, through the same message path.
- A client session sends a request message to a message path.
- The control client session receives the request message through a request handler.
- The session client session uses sends a response to the request message.
- The 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 to a message path
Required permissions:
permission for the specified message path- The message path to send the request to and receive the response through
- The request message
- The datatype of the request message
- The datatype of the response message
// Example with json topic type. var jsonType = diffusion.datatypes.json(); // Create a JSON object to send as a request. var requestJson = jsonType.from("hello"); // Send the request to a message path "foo". session.messages.sendRequest('foo', requestJson, jsonType).then(function(response) { console.log(response.get()); }, function(error) {});
[session.messaging sendRequest:[PTDiffusionPrimitive requestWithLongLong:42] toPath:message_path int64NumberCompletionHandler:^(NSNumber *response, NSError *error) { if (error) { NSLog(@"Failed to send to %@. Error: %@", message_path, error); } else { NSLog(@"Received response: %@", response); } }];
//Establish client sesssion final Session session = Diffusion.sessions().principal("client").password("password").open("ws://localhost:8080"); //Obtain the Messaging feature final Messaging messaging = session.feature(Messaging.class); //Create a JSON object to send as a request final JSON request = Diffusion.dataTypes().json().fromJsonString("\"hello\""); //Send the request to a message path "foo" and wait for (at most) 5 seconds until the response is received. final JSON response = messaging.sendRequest("foo", request, JSON.class, JSON.class).get(5, TimeUnit.SECONDS);
Responding to request messages sent to a message path
Required permissions:
permission for the specified message path, permission, and permission to register to receive session property values with the request messageDefine a request handler to receive and respond to request messages that have a specific data type.
var jsonType = diffusion.datatypes.json(); var requestJson = jsonType.from({ "foo": "bar"}); var responseJson = jsonType.from({ "ying": "yang"}); // Define a request handler for json topic type var handler = { onRequest: function(request, context, responder) { responder.respond(responseJson, jsonType); }, onError: function() {}, onClose: function() {} };
@interface NumberRequestDelegate : NSObject<PTDiffusionNumberRequestDelegate> @end @implementation NumberRequestDelegate -(void)diffusionTopicTreeRegistration:(PTDiffusionTopicTreeRegistration *)registration didReceiveRequestWithNumber:(nullable NSNumber *)number context:(PTDiffusionRequestContext *)context responder:(PTDiffusionResponder *)responder; { // Do something when a request is received. } - (void)diffusionTopicTreeRegistration:(nonnull PTDiffusionTopicTreeRegistration *)registration didFailWithError:(nonnull NSError *)error { // Do something if the registration fails. } - (void)diffusionTopicTreeRegistrationDidClose:(nonnull PTDiffusionTopicTreeRegistration *)registration { // Do something if the registration closes. }
private final class JSONRequestHandler implements MessagingControl.RequestHandler<JSON, JSON> { @Override public void onClose() { .... } @Override public void onError(ErrorReason errorReason) { .... } @Override public void onRequest(JSON request, RequestContext context, Responder<JSON> responder) { .... responder.respond(response); } }
Register the request handler against a message path. You can only register one request handler against each message path.
var handler = { onRequest: function(request, context, responder) {}, onError: function() {}, onClose: function() {} }; session.messages.addRequestHandler('topic', handler);
// Ensure to maintain a strong reference to your delegate as it // is referenced weakly by the Diffusion client library. NumberRequestDelegate *const delegate = [NumberRequestDelegate new]; PTDiffusionRequestHandler *const handler = [PTDiffusionPrimitive int64RequestHandlerWithDelegate:delegate]; [session.messagingControl addRequestHandler:handler forPath:path completionHandler:^(PTDiffusionTopicTreeRegistration *registration, NSError *error) { // Check error is `nil`, indicating success. }];
messagingControl.addRequestHandler(messagePath, JSON.class, JSON.class, new JSONRequestHandler());
One-way messaging to a path
Diffusion™ also provides a capability to send one-way messages to a message path. This message is not typed. The handling session cannot respond directly to this message.
- The message path to send the message through
- The request message
- Any additional options, such as headers or a message priority
session.messages.send('message_path', content);
PTDiffusionContent *const content = [[PTDiffusionContent alloc] initWithData:data]; [session.messaging sendWithPath:message_path value:content options:[PTDiffusionSendOptions new] completionHandler:^(NSError *const error) { if (error) { NSLog(@"Failed to send. Error: %@", error); } else { NSLog(@"Sent"); } }];
messaging = session.feature(Messaging.class); messaging.send(message_path, message_content, messaging.sendOptionsBuilder().headers(headers).build());
var messaging = session.Messaging; messaging.Send( message_path, message_content, messaging.CreateSendOptionsBuilder().SetHeaders( headers ).Build() );
SEND_MSG_PARAMS_T params = { .topic_path = message_path, .payload = *content, .headers = headers, .priority = CLIENT_SEND_PRIORITY_NORMAL, .on_send = on_send, .context = context }; /* * Send the message and wait for the callback to acknowledge * delivery. */ send_msg(session, params);
To receive a message sent to a message path, a client session must define a message handler:
// Create a message handler var handler = { onMessage : function(message) { console.log(message); // Log the received message }, onActive : function(unregister) { }, onClose : function() { } };
@interface MessageDelegate : NSObject <PTDiffusionMessageDelegate> @end @implementation MessageDelegate -(void)diffusionTopicTreeRegistration:(PTDiffusionTopicTreeRegistration *)registration hadMessageFromSessionId:(PTDiffusionSessionId *)sessionId path:(NSString *)path content:(PTDiffusionContent *)content context:(PTDiffusionReceiveContext *)context { // Do something when a message is received. } -(void)diffusionTopicTreeRegistrationDidClose:(PTDiffusionTopicTreeRegistration *)registration { // Do something if the registration closes. } -(void)diffusionTopicTreeRegistration:(PTDiffusionTopicTreeRegistration *)registration didFailWithError:(NSError *)error { // Do something if the registration fails. }
private class MyHandler extends MessageHandler.Default { @Override public void onMessage( SessionId sessionId, String topicPath, Content content, ReceiveContext context) { // Do something when a message is received. } }
private class MyHandler : MessageReceiverDefault { public override void OnMessage( SessionId sessionId, string topicPath, IContent content, IReceiveContext context) { // Take action when a message is received. } }
/* * Function called on receipt of a message from a client. * * We print the following information: * 1. The message path on which the message was received. * 2. A hexdump of the message content. * 3. The headers associated with the message. * 4. The session properties that were requested when the handler was * registered. * 5. The user context, as a string. */ int on_msg(SESSION_T *session, const SVC_SEND_RECEIVER_CLIENT_REQUEST_T *request, void *context) { printf("Received message on path %s\n", request->topic_path); hexdump_buf(request->content->data); printf("Headers:\n"); if(request->send_options.headers->first == NULL) { printf(" No headers\n"); } else { for(LIST_NODE_T *node = request->send_options.headers->first; node != NULL; node = node->next) { printf(" Header: %s\n", (char *)node->data); } } printf("Session properties:\n"); char **keys = hash_keys(request->session_properties); if(keys == NULL || *keys == NULL) { printf(" No properties\n"); } else { for(char **k = keys; *k != NULL; k++) { char *v = hash_get(request->session_properties, *k); printf(" %s=%s\n", *k, v); } } free(keys); if(context != NULL) { printf("Context: %s\n", (char *)context); } return HANDLER_SUCCESS; }
Register the message handler against a message path and its descendants:
// Register the handler session.messages.addHandler('message_path', handler).then(function() { // Registration happened successfully }, function(error) { // Registration failed });
// Ensure to maintain a strong reference to your message delegate as it is // referenced weakly by the Diffusion client library. MessageDelegate *const messageDelegate = [MessageDelegate new]; // Use the Messaging Control feature to send a registration request to the // server. [session.messagingControl addMessageHandlerForPath:message_path withDelegate:messageDelegate completionHandler: ^(PTDiffusionTopicTreeRegistration* registration, NSError* error) { // Check error is `nil`, indicating success. // Optionally store a strong reference to registration in order to allow the // handler to be unregistered at the server. }];
session.feature(MessagingControl.class).addMessageHandler(message_path, new MyHandler());
session.MessagingControl.AddMessageHandler( message_path, new MyHandler() );
/* * Register a message handler, and for each message ask for * the $Principal property to be provided. */ LIST_T *requested_properties = list_create(); list_append_last(requested_properties, "$Principal"); MSG_RECEIVER_REGISTRATION_PARAMS_T params = { .on_registered = on_registered, .topic_path = topic, .on_message = on_msg, .session_properties = requested_properties }; list_free(requested_properties, free); register_msg_handler(session, params);
To respond to this message, the receiving client session sends a separate message to the session that sent the message. For more information, see One-way messaging to a session.
This page last modified: 2017/09/21