TipcConnMsgSendRpc


Name

TipcConnMsgSendRpc — make a remote procedure call (RPC) with messages on a connection

Synopsis

T_IPC_MSG TipcConnMsgSendRpc(conn, call_msg, timeout) 
T_IPC_CONN conn; 
T_IPC_MSG call_msg; 
T_REAL8 timeout; 

Arguments

conn — connection to make RPC on

call_msg — call message for RPC

timeout — maximum number of seconds to wait for result message to arrive

Return Values

A result message if successful, NULL otherwise.

Diagnostics

If TipcConnMsgSendRpc fails, it returns NULL and sets the global SmartSockets error number to one of:

Description

TipcConnMsgSendRpc makes a remote procedure call (RPC) with messages on a connection. One message is sent as the RPC call from the caller end of the connection, and another message is sent back as the RPC result to the caller. The callee end of the connection must be prepared to receive the call message and send back the result message. The relationship between the call and result message is that the message type number of the result message is always one greater than the message type number of the call message. TipcConnMsgSendRpc sends the message with TipcConnMsgSend, flushes all pending outgoing data with TipcConnFlush, and then waits for the result with TipcConnMsgSearchType.

A message returned by TipcConnMsgSendRpc is normally processed (either with TipcConnMsgProcess, or by accessing it directly without any callbacks) and then destroyed by calling TipcMsgDestroy. Use T_TIMEOUT_FOREVER for timeout to wait until a message arrives.

Caution

The message returned by TipcConnMsgSendRpc should be destroyed when it is no longer needed by calling TipcMsgDestroy, unless the message is passed to another function which takes responsibility for destroying the message, such as TipcConnMsgInsert.

The message type number of the result message must be one greater than the message type number of the call message.

If both ends of the connection attempt to make an RPC at the same time, a deadlock condition can occur.

See Also

TipcConnMsgProcess, TipcConnMsgSearchType

Examples

This example calculates the tangent of a number with a message-based connection RPC. It sends a call message and waits for up to 10 seconds for a result message to be sent back from the other end of the connection. Shown first is a utility fragment that must be used by both the caller and the called program:

#define USER_MT_TANGENT_CALL 100 
#define USER_MT_TANGENT_RESULT 101 /* call num plus one */ 
 
/* utility function to create message types */ 
static void create_tangent_mt() 
{ 
  T_IPC_MT mt; 
 
  mt = TipcMtCreate("tangent_call", USER_MT_TANGENT_CALL, 
                    "real8"); 
  if (mt == NULL) { 
    return;  /* error */ 
  } 
 
  mt = TipcMtCreate("tangent_result", USER_MT_TANGENT_RESULT, 
                    "real8"); 
  if (mt == NULL) { 
    return;  /* error */ 
  } 
} /* create_tangent_mt */ 

Shown next is the caller fragment:

/* calculate tangent via RPC */ 
T_REAL8 tangent_rpc(num) 
T_REAL8 num; 
{ 
  T_IPC_MT mt; 
  T_IPC_MSG call_msg; 
  T_IPC_MSG result_msg; 
  T_REAL8 result; 
 
  mt = TipcMtLookupByNum(USER_MT_TANGENT_CALL); 
  if (mt == NULL) { 
    return;  /* error */ 
  } 
 
  call_msg = TipcMsgCreate(mt); 
  if (call_msg == NULL) { 
    return;  /* error */ 
  } 
 
  if (!TipcMsgAppendReal8(call_msg, num)) { 
    return;  /* error */ 
  } 
 
  /* send/recv RPC messages */ 
  result_msg = TipcConnMsgSendRpc(conn, call_msg, 10.0); 
  if (result_msg == NULL) { 
    return;  /* error */ 
  } 
 
  /* process result without using TipcConnMsgProcess */ 
 
  if (!TipcMsgNextReal8(result_msg, &result)) { 
    return;  /* error */ 
  } 
  if (!TipcMsgDestroy(result_msg)) { 
    return;  /* error */ 
  } 
  if (!TipcMsgDestroy(call_msg)) { 
    return;  /* error */ 
  } 
  return result; 
} /* tangent_rpc */ 

This is the called program’s fragment:

/* callback to process RPC "call" message */ 
static void T_ENTRY process_call(conn, data, arg) 
T_IPC_CONN conn; 
T_IPC_CONN_PROCESS_CB_DATA data; 
T_CB_ARG arg; 
{ 
  T_REAL8 num; 
  T_IPC_MT mt; 
 
  /* have to start at first field */ 
  if (!TipcMsgSetCurrent(data->msg, 0)) { 
    return;  /* error */ 
  } 
 
  /* access the RPC call information */ 
  if (!TipcMsgNextReal8(data->msg, &num)) { 
    return;  /* error */ 
  } 
 
  mt = TipcMtLookupByNum(USER_MT_TANGENT_RESULT); 
  if (mt == NULL) { 
    return;  /* error */ 
  } 
 
  /* send a result message back to the caller */ 
  if (!TipcConnMsgWrite(conn, mt, 
                        T_IPC_FT_REAL8, tan(num), 
                        NULL)) { 
     return;  /* error */ 
  } 
  if (!TipcConnFlush(conn)) { 
    return;  /* error */ 
  } 
} /* process_call */ 
 
/* =========================================================== */ 
/*...code from calling function is below */ 
 
/* fragment that uses process_call */ 
T_IPC_MT mt; 
 
mt = TipcMtLookupByNum(USER_MT_TANGENT_CALL); 
if (mt == NULL) { 
  return;  /* error */ 
} 
 
if (TipcConnProcessCbCreate(conn, mt, process_call, NULL) == NULL) 
{ 
  return;  /* error */ 
} 
 
TipcConnMainLoop(conn, T_TIMEOUT_FOREVER); /* process call messages */ 

TIBCO SmartSockets™ Application Programming Interface
Software Release 6.8, July 2006
Copyright © TIBCO Software Inc. All rights reserved
www.tibco.com