Ipc: Difference between revisions
(12 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
== General info == | == General info == | ||
Interprocess communication in Hall B is based on package located in $ | Interprocess communication in Hall B is based on package located in $CODA/src/ipc. Currently it is based on ActiveMQ, which can be replaced with another messager if necessary. Switching between messagers shell be done by changing $CODA/src/Makefile.include and recompiling entire $CODA and $CLON areas. ActiveMQ or any other messager must be installed in /usr/local/src area. | ||
Top level classes can be found in $ | Top level classes can be found in $CODA/src/ipc/ipc.s/ipc_lib.h, test program is $CODA/src/ipc/main/ipc_client.cc. In case of switching to another messager, top level API in ipc_lib.h should remain the same to avoid changes in user code, meaning new ipc_lib.h must be written to support another messager. | ||
Sender subscribes to the 4-field | Sender and receiver subscribes to the lists of 4-field topics, different for sender and receiver. Topics in the list are separated by commas (','), for example for 2 topics: | ||
"TOPIC11.TOPIC12.TOPIC13.TOPIC14, TOPIC21.TOPIC22.TOPIC23.TOPIC24" | |||
Every topic contains 4 fields separated by dots ('.'). Following convention is adopted for HallB messaging (defaults are NULL or '*'): | |||
( | TOPIC11 - usually getenv("EXPID") | ||
TOPIC12 - usually getenv("SESSION") | |||
TOPIC13 - message class, for example 'control', 'epics', 'daq' etc | |||
TOPIC14 - message subclass, sometimes unique name of sender (program name), or anything else | |||
If no topics provided, it assumes "EXPID.SESSION.*.*" so all messages will be sent to EXPID and SESSION and processed. | |||
Every message starts from message 'header' in a form of character string, with two possible options: | |||
1. '''non-json message''' - in that form message contains 'header' and 'body'. Message 'header' is the character string containing fields separated by ':', usually with following meaning: | |||
Message format: | "FORMAT:FORMAT1:FORMAT2:....." | ||
FORMAT - message format, for example 'cmd', 'runlog' etc, listener 'MessageActionXXXX.h' must be provided for every format | |||
FORMAT1 (optional, but preferrably sender program name) | |||
FORMAT2 (optional, if needed) | |||
..... | |||
Message 'body' contains the elements or an arrays of elements in any format supported by ActiveMQ. | |||
2. '''json message''' - in that form message contains the list of json strings in following form: | |||
{....} - json | |||
{bla:[{json1},{json2},..]} - list of jsons | |||
and message does NOT contains anything else. | |||
Line 43: | Line 52: | ||
main() | main() | ||
{ | { | ||
// | // add topic(s) to sender's subscribe list; can be overruled by SetTopic() modifier (see below) | ||
server.AddSendTopic(getenv("EXPID"), getenv("SESSION"), NULL, (char *)"server"); | |||
server. | |||
// add topic(s) to receiver's subscribe list | |||
server.AddRecvTopic(getenv("EXPID"), getenv("SESSION"), NULL, (char *)"server"); | |||
server.AddRecvTopic(getenv("EXPID"), getenv("SESSION"), NULL, (char *)"test"); | |||
// open connection to server | |||
server.Open(); | |||
// create listeners | |||
MessageActionControl *control = new MessageActionControl((char *)"myname"); | MessageActionControl *control = new MessageActionControl((char *)"myname"); | ||
MessageActionXXXX *xxxx = new MessageActionXXXX(); | MessageActionXXXX *xxxx = new MessageActionXXXX(); | ||
server. | // add listeners to receiver's list | ||
server. | server.AddCallback(control); | ||
server.AddCallback(xxxx); | |||
// send message | |||
server << clrm << ...stuff... << endm; | server << clrm << ...stuff... << endm; | ||
server.close(); | // send message to different topic; it will overrule topic list set by 'AddSendTopic()' ONLY for this particular message, | ||
// all following messages will use topic set by 'AddSendTopic()', unless 'SetTopic()' modifier is used again | |||
server << clrm << ...stuff... << SetTopic("AA.BB.CC.DD") << endm; | |||
// close connection to server | |||
server.Close(); | |||
} | } | ||
== MessageActionControl.h == | == MessageActionControl.h == | ||
Line 66: | Line 85: | ||
Sends commands and receives status. Command message sent by program 'myname' must has following format: | Sends commands and receives status. Command message sent by program 'myname' must has following format: | ||
server. | server.AddSendTopic(getenv("EXPID"), getenv("SESSION"), "control", destination); | ||
server << clrm << "command:myname" << "quit" << endm; // request to quit | server << clrm << "command:myname" << "quit" << endm; // request to quit | ||
server << clrm << "command:myname" << "status" << endm; // request for status | server << clrm << "command:myname" << "status" << endm; // request for status | ||
Line 75: | Line 95: | ||
server << clrm << "status:myname" << nelem << elem1 << elem2 << .. << endm; | server << clrm << "status:myname" << nelem << elem1 << elem2 << .. << endm; | ||
server << clrm << "statistics:myname" << nelem << elem1 << elem2 << .. << endm; | server << clrm << "statistics:myname" << nelem << elem1 << elem2 << .. << endm; | ||
In examples above message header contains two parts: message format and sender name, that header form shell be typically used for all non-json messages in HallB. | |||
== MessageActionEPICS.h == | |||
Sends and receives non-json EPICS messages. Message sent by program 'myname' must has following format: | |||
server.AddSendTopic(getenv("EXPID"), getenv("SESSION"), "epics", destination); | |||
server << clrm << "epics" << "channel_name" << "channel_type" << Nelements << element1 << element2 << ... << endm; | |||
"channel_type" can be one of following: | |||
char | |||
uchar | |||
short | |||
ushort | |||
int | |||
uint | |||
float | |||
double | |||
string (NOTE: 'Nelements' for 'string' can only be 1, array of strings not supported yet) |
Latest revision as of 13:08, 8 January 2018
General info
Interprocess communication in Hall B is based on package located in $CODA/src/ipc. Currently it is based on ActiveMQ, which can be replaced with another messager if necessary. Switching between messagers shell be done by changing $CODA/src/Makefile.include and recompiling entire $CODA and $CLON areas. ActiveMQ or any other messager must be installed in /usr/local/src area.
Top level classes can be found in $CODA/src/ipc/ipc.s/ipc_lib.h, test program is $CODA/src/ipc/main/ipc_client.cc. In case of switching to another messager, top level API in ipc_lib.h should remain the same to avoid changes in user code, meaning new ipc_lib.h must be written to support another messager.
Sender and receiver subscribes to the lists of 4-field topics, different for sender and receiver. Topics in the list are separated by commas (','), for example for 2 topics:
"TOPIC11.TOPIC12.TOPIC13.TOPIC14, TOPIC21.TOPIC22.TOPIC23.TOPIC24"
Every topic contains 4 fields separated by dots ('.'). Following convention is adopted for HallB messaging (defaults are NULL or '*'):
TOPIC11 - usually getenv("EXPID") TOPIC12 - usually getenv("SESSION") TOPIC13 - message class, for example 'control', 'epics', 'daq' etc TOPIC14 - message subclass, sometimes unique name of sender (program name), or anything else
If no topics provided, it assumes "EXPID.SESSION.*.*" so all messages will be sent to EXPID and SESSION and processed.
Every message starts from message 'header' in a form of character string, with two possible options:
1. non-json message - in that form message contains 'header' and 'body'. Message 'header' is the character string containing fields separated by ':', usually with following meaning:
"FORMAT:FORMAT1:FORMAT2:....."
FORMAT - message format, for example 'cmd', 'runlog' etc, listener 'MessageActionXXXX.h' must be provided for every format FORMAT1 (optional, but preferrably sender program name) FORMAT2 (optional, if needed) .....
Message 'body' contains the elements or an arrays of elements in any format supported by ActiveMQ.
2. json message - in that form message contains the list of json strings in following form:
{....} - json {bla:[{json1},{json2},..]} - list of jsons
and message does NOT contains anything else.
Typical user code includes following:
#include "ipc_lib.h"
#include "MessageActionControl.h"
#include "MessageActionXXXX.h" // XXXX is particular listener, like MessageActionEPICS.h
IpcServer &server = IpcServer::Instance(); // get ipc server instance, it is implemented as singleton
main() { // add topic(s) to sender's subscribe list; can be overruled by SetTopic() modifier (see below) server.AddSendTopic(getenv("EXPID"), getenv("SESSION"), NULL, (char *)"server");
// add topic(s) to receiver's subscribe list server.AddRecvTopic(getenv("EXPID"), getenv("SESSION"), NULL, (char *)"server"); server.AddRecvTopic(getenv("EXPID"), getenv("SESSION"), NULL, (char *)"test");
// open connection to server server.Open();
// create listeners MessageActionControl *control = new MessageActionControl((char *)"myname"); MessageActionXXXX *xxxx = new MessageActionXXXX();
// add listeners to receiver's list server.AddCallback(control); server.AddCallback(xxxx);
// send message server << clrm << ...stuff... << endm;
// send message to different topic; it will overrule topic list set by 'AddSendTopic()' ONLY for this particular message, // all following messages will use topic set by 'AddSendTopic()', unless 'SetTopic()' modifier is used again server << clrm << ...stuff... << SetTopic("AA.BB.CC.DD") << endm;
// close connection to server server.Close(); }
MessageActionControl.h
Sends commands and receives status. Command message sent by program 'myname' must has following format:
server.AddSendTopic(getenv("EXPID"), getenv("SESSION"), "control", destination);
server << clrm << "command:myname" << "quit" << endm; // request to quit server << clrm << "command:myname" << "status" << endm; // request for status server << clrm << "command:myname" << "statistics" << endm; // request for statistics
If information is requested, program suppose to send back following:
server << clrm << "status:myname" << nelem << elem1 << elem2 << .. << endm; server << clrm << "statistics:myname" << nelem << elem1 << elem2 << .. << endm;
In examples above message header contains two parts: message format and sender name, that header form shell be typically used for all non-json messages in HallB.
MessageActionEPICS.h
Sends and receives non-json EPICS messages. Message sent by program 'myname' must has following format:
server.AddSendTopic(getenv("EXPID"), getenv("SESSION"), "epics", destination);
server << clrm << "epics" << "channel_name" << "channel_type" << Nelements << element1 << element2 << ... << endm;
"channel_type" can be one of following:
char uchar short ushort int uint float double string (NOTE: 'Nelements' for 'string' can only be 1, array of strings not supported yet)