PubSub+ Messaging API For C  7.31.0.7
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ex/ios/examples/AppTransitionsExample.m
/*
p
* Copyright 2014-2024 Solace Corporation. All rights reserved.
*/
#import "AppTransitionsExample.h"
@implementation AppTransitionsExample
@synthesize session_p;
@synthesize suspended;
@synthesize requestSuspend;
@synthesize requestResume;
- (id)initWithExampleInterface:(ExampleInterface *)exampleInterface {
self = [super initWithExampleInterface:exampleInterface];
// Set example name and description
self.name = @"AppTransitions";
self.description =
@"Demonstrates how to respond to changes in application state";
// Setup example parameters
[self.parameters addParameter:PARAMETER_NUM_MESSAGES];
[self.parameters addParameter:PARAMETER_DESTINATION_TOPIC];
[self.parameters parameterWithId:PARAMETER_NUM_MESSAGES].value = @"100";
suspended = NO;
requestSuspend = NO;
requestResume = NO;
return self;
}
- (void)run {
[super run];
// Context variables
// Message variables
solClient_opaqueMsg_pt msg_p = NULL;
int msgsSent = 0;
// Initialize the API; this must be done prior to first usage
if (self.requestSuspend) {
[self blockThreadDuringSuspension];
// If cancellation is requested, branch to appropriate label;
// otherwise, repeat while loop
if (self.requestCancel) {
goto notInitialized;
}
} else {
[self handleErrorWithReturnCode:rc
errorString:"solClient_initialize()"];
goto notInitialized;
}
}
// Set up logging level and log example and API information
[self setLoggingLevel];
"AppTransitionsExample.m (Copyright 2014-2024 Solace Corporation. All rights reserved.)\n");
[self logCCSMPVersion];
// Create a context, and specify that the context thread be created
// automatically instead of having the application create its own
// context thread.
solClient_log(SOLCLIENT_LOG_INFO, "Creating solClient context");
&contextFuncInfo, sizeof(contextFuncInfo))) != SOLCLIENT_OK) {
if (self.requestSuspend) {
[self blockThreadDuringSuspension];
// If cancellation is requested, branch to appropriate label;
// otherwise,
// repeat while loop
if (self.requestCancel) {
goto cleanup;
}
} else {
[self handleErrorWithReturnCode:rc
errorString:"solClient_context_create()"];
goto cleanup;
}
}
solClient_log(SOLCLIENT_LOG_INFO, "Creating solClient sessions.");
while ((rc = [self createAndConnectSessionWithContext:context_p
session:&session_p
messageCallback:messageReceiveCallback
eventCallback:eventCallback]) !=
if (self.requestSuspend) {
[self blockThreadDuringSuspension];
// If cancellation is requested, branch to appropriate label;
// otherwise, repeat while loop
if (self.requestCancel) {
goto cleanup;
}
} else {
[self handleErrorWithReturnCode:rc
errorString:"createAndConnectSessionWithContext"
":session:messageCallback:"
"eventCallback:userData:"];
goto cleanup;
}
}
[[self.parameters parameterWithId:PARAMETER_DESTINATION_TOPIC]
.value cStringUsingEncoding:NSASCIIStringEncoding])) !=
if (self.requestSuspend) {
[self blockThreadDuringSuspension];
// If cancellation is requested, branch to appropriate label;
// otherwise,
// repeat while loop
if (self.requestCancel) {
goto sessionConnected;
}
} else {
[self
handleErrorWithReturnCode:rc
errorString:"solClient_session_topicSubscribe()"];
goto sessionConnected;
}
}
solClient_log(SOLCLIENT_LOG_INFO, "Publishing messages.\n");
for (msgsSent = 0;
msgsSent < [self.parameters parameterWithId:PARAMETER_NUM_MESSAGES]
.value.integerValue &&
!self.requestCancel;
++msgsSent) {
// Allocate memory for the message that is to be sent
while ((rc = solClient_msg_alloc(&msg_p)) != SOLCLIENT_OK) {
if (self.requestSuspend) {
[self blockThreadDuringSuspension];
// If cancellation is requested, branch to appropriate label;
// otherwise, repeat while loop
if (self.requestCancel) {
goto sessionConnected;
}
} else {
[self handleErrorWithReturnCode:rc
errorString:"solClient_msg_alloc()"];
goto sessionConnected;
}
}
// Set the message delivery mode
if (self.requestSuspend) {
[self blockThreadDuringSuspension];
// If cancellation is requested, branch to appropriate label;
// otherwise,
// repeat while loop
if (self.requestCancel) {
goto freeMessage;
}
} else {
[self handleErrorWithReturnCode:
rc errorString:"solClient_msg_setDeliveryMode()"];
goto freeMessage;
}
}
// Set the destination
destination.dest =
[[self.parameters parameterWithId:PARAMETER_DESTINATION_TOPIC].value
cStringUsingEncoding:NSASCIIStringEncoding];
while ((rc = solClient_msg_setDestination(msg_p, &destination,
sizeof(destination))) !=
if (self.requestSuspend) {
[self blockThreadDuringSuspension];
// If cancellation is requested, branch to appropriate label;
// otherwise,
// repeat while loop
if (self.requestCancel) {
goto freeMessage;
}
} else {
[self
handleErrorWithReturnCode:rc
errorString:"solClient_msg_setDestination()"];
goto freeMessage;
}
}
// Add some content to the message
msg_p, COMMON_ATTACHMENT_TEXT,
(solClient_uint32_t)strlen(COMMON_ATTACHMENT_TEXT))) !=
if (self.requestSuspend) {
[self blockThreadDuringSuspension];
// If cancellation is requested, branch to appropriate label;
// otherwise, repeat while loop
if (self.requestCancel) {
goto freeMessage;
}
} else {
[self handleErrorWithReturnCode:
rc errorString:"solClient_msg_setBinaryAttachment()"];
goto freeMessage;
}
}
// Send the message
while ((rc = solClient_session_sendMsg(session_p, msg_p)) !=
if (self.requestSuspend) {
[self blockThreadDuringSuspension];
// If cancellation is requested, branch to appropriate label;
// otherwise, repeat while loop
if (self.requestCancel) {
goto freeMessage;
}
} else {
[self handleErrorWithReturnCode:rc
errorString:"solClient_session_sendMsg()"];
goto freeMessage;
}
}
freeMessage:
while ((rc = solClient_msg_free(&msg_p)) != SOLCLIENT_OK) {
if (self.requestSuspend) {
[self blockThreadDuringSuspension];
// If cancellation is requested, branch to appropriate label;
// otherwise, repeat while loop
if (self.requestCancel) {
goto sessionConnected;
}
} else {
[self handleErrorWithReturnCode:rc
errorString:"solClient_msg_free()"];
goto sessionConnected;
}
}
// Wait one second between sending messages. This provides time for
// the final message to be received.
[NSThread sleepForTimeInterval:1];
}
[[self.parameters parameterWithId:PARAMETER_DESTINATION_TOPIC]
.value cStringUsingEncoding:NSASCIIStringEncoding])) !=
if (self.requestSuspend) {
[self blockThreadDuringSuspension];
// If cancellation is requested, branch to appropriate label;
// otherwise,
// repeat while loop
if (self.requestCancel) {
goto sessionConnected;
}
} else {
[self
handleErrorWithReturnCode:rc
errorString:"solClient_session_topicSubscribe()"];
goto sessionConnected;
}
}
sessionConnected:
// Disconnect the session
if ((rc = solClient_session_disconnect(self.session_p)) != SOLCLIENT_OK) {
[self handleErrorWithReturnCode:rc
errorString:"solClient_session_disconnect()"];
}
cleanup:
// Cleanup solclient
if ((rc = solClient_cleanup()) != SOLCLIENT_OK) {
[self handleErrorWithReturnCode:rc errorString:"solClient_cleanup()"];
}
notInitialized:
[self cleanup];
}
- (void)suspend {
// Verify that the example is running and that suspension has not already
// been requested
if (self.running && !self.requestSuspend) {
"[SUSPEND] Suspending example...\n");
// Inform the example that suspension is requested
self.requestSuspend = YES;
// Manually disconnect from the session
if ((rc = solClient_session_disconnect(self.session_p)) !=
"[SUSPEND] Failed to disconnect session!\n");
[self handleErrorWithReturnCode:rc
errorString:"solClient_session_disconnect()"];
} else {
"[SUSPEND] Session disconnected.\n");
}
}
}
- (void)resume {
// Verify that the example is suspended and that resumption has not already
// been requested
if (self.suspended && !self.requestResume) {
solClient_log(SOLCLIENT_LOG_NOTICE, "[RESUME] Resuming example...\n");
// Manually reconnect the session
if ((rc = solClient_session_connect(self.session_p)) != SOLCLIENT_OK) {
"[RESUME] Failed to reconnect session!");
[self handleErrorWithReturnCode:rc
errorString:"solClient_session_connect()"];
"[RESUME] Could not resume example from suspension! "
"Cancelling...\n");
[self cancel];
} else {
"[RESUME] Session reconnected.\n");
// Inform the example that resumption is requested
self.requestResume = YES;
}
}
}
- (void)blockThreadDuringSuspension {
self.suspended = YES;
"[THREAD BLOCK] Thread blocked while waiting for resume or cancel "
"request.\n");
// Block thread during suspension
while (!self.requestResume && !self.requestCancel) {
[NSThread sleepForTimeInterval:1];
}
// When thread is no longer blocked, reconnect the session (except if the
// cancel button was pressed)
if (self.requestResume) {
"[THREAD BLOCK] Got resume request.\n");
self.requestResume = NO;
} else {
"[THREAD BLOCK] Got cancel request.\n");
}
self.requestSuspend = NO;
self.suspended = NO;
}
@end