Ipc: Difference between revisions

From CLONWiki
Jump to navigation Jump to search
Boiarino (talk | contribs)
Boiarino (talk | contribs)
Line 5: Line 5:
Top level classes can be found in $CLON/src/ipc/ipc.s/ipc_lib.h, test program is $CLON/src/ipc/main/ipc_client.cc.
Top level classes can be found in $CLON/src/ipc/ipc.s/ipc_lib.h, test program is $CLON/src/ipc/main/ipc_client.cc.


Sender subscribes to the 4-field topic
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:


  "TOPIC1"."TOPIC2"."TOPIC3"."TOPIC4"
  "TOPIC11.TOPIC12.TOPIC13.TOPIC14, TOPIC21.TOPIC22.TOPIC23.TOPIC24"


and start message from message header in a form of character string
Every topic contains 4 fields separated by dots ('.'). Following convention is adopted for HallB messaging (defaults are NULL or '*'):


  (char *)"FORMAT:TOPIC4:TOPIC3:TOPIC2:TOPIC1"
  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


with following format:
Every message starts from message 'header' in a form of character string, with two possible forms:


Topic (defaults are NULL or '*'):
1. '''non-json''' - in that form message contains 'header' and 'body'. Message 'header' is the character string containing fields separated by ':', usually with following meaning:


  TOPIC1 - usually getenv("EXPID")
  "FORMAT:FORMAT1:FORMAT2:....."
TOPIC2 - usually getenv("SESSION")
TOPIC3 - message class, for example 'control', 'epics', 'daq' etc
TOPIC4 - unique name of sender, usually program name


Message header:
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''' - in that form message contains the list of json strings in following form:
 
[{json1},{json2},..]
 
and message does NOT contains anything else.


FORMAT - message format, for example 'cmd', 'json' etc, 'MessageActionXXXX.h' must be provided for every format
TOPIC4 (optional, but preferrably sender program name)
TOPIC3 (optional, usually not used)
TOPIC2 (optional, usually not used)
TOPIC1 (optional, usually not used)




Line 43: Line 49:
  main()
  main()
  {
  {
   // following call sets topic for sender ("par1.par2.par3.par4") and receiver ("par1.par2.par5.par6")
   // add topic(s) to sender's subscribe list; can be overruled by SetTopic() modifier (see below)
  // 1st and 2nd params - usually EXPID and SESSION, or EXPID and NULL
  server.SendTopic(getenv("EXPID"), getenv("SESSION"), NULL, (char *)"server");
  // 3rd and 4th params - 'class' and 'destination' for sender only, for example 'epics' and 'dbrouter' (sending to class 'epics' and destination 'dbrouter')
 
   // 5th and 6th params (optional) - 'class' and 'destination' for receiver only, for example 'epics' and '*' (listen for messages with class 'epics' and any destination)
   // add topic(s) to receiver's subscribe list
  // for example:
   server.RecvTopic(getenv("EXPID"), getenv("SESSION"), NULL, (char *)"server");
   server.init(getenv("EXPID"), getenv("SESSION"), (char *)"epics", (char *)"dbrouter", (char *)"epics", (char *)"*");
  server.RecvTopic(getenv("EXPID"), getenv("SESSION"), NULL, (char *)"test");
 
  // connect to server
  server.Connect();


  // create listeners
   MessageActionControl  *control = new MessageActionControl((char *)"myname");
   MessageActionControl  *control = new MessageActionControl((char *)"myname");
   MessageActionXXXX        *xxxx = new MessageActionXXXX();
   MessageActionXXXX        *xxxx = new MessageActionXXXX();


   server.addActionListener(control);
  // add listeners to receiver's list
   server.addActionListener(xxxx);
   server.RecvListener(control);
   server.RecvListener(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 'SendTopic' ONLY for this particular message
   server << clrm << ...stuff... << SetTopic("AA.BB.CC.DD") << endm;
 
  // disconnect from server
  server.Disconnect();
  }
  }


== MessageActionControl.h ==
== MessageActionControl.h ==

Revision as of 22:49, 5 January 2018

General info

Interprocess communication in Hall B is based on package located in $CLON/src/ipc. Currently it is based on ActiveMQ, which can be replaced with another messager if necessary, for example jlab-developed xMsg. Switching between messagers is done by changing $CLON/src/Makefile.include and recompiling entire $CLON area. ActiveMQ or any other messager must be installed in /usr/local/src area.

Top level classes can be found in $CLON/src/ipc/ipc.s/ipc_lib.h, test program is $CLON/src/ipc/main/ipc_client.cc.

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

Every message starts from message 'header' in a form of character string, with two possible forms:

1. non-json - 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 - in that form message contains the list of json strings in following form:

[{json1},{json2},..]

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.SendTopic(getenv("EXPID"), getenv("SESSION"), NULL, (char *)"server");
  // add topic(s) to receiver's subscribe list
  server.RecvTopic(getenv("EXPID"), getenv("SESSION"), NULL, (char *)"server");
  server.RecvTopic(getenv("EXPID"), getenv("SESSION"), NULL, (char *)"test");
  // connect to server
  server.Connect();
  // create listeners
  MessageActionControl  *control = new MessageActionControl((char *)"myname");
  MessageActionXXXX        *xxxx = new MessageActionXXXX();
  // add listeners to receiver's list
  server.RecvListener(control);
  server.RecvListener(xxxx);
  // send message
  server << clrm << ...stuff... << endm;
  // send message to different topic; it will overrule topic list set by 'SendTopic' ONLY for this particular message
  server << clrm << ...stuff... << SetTopic("AA.BB.CC.DD") << endm;
  // disconnect from server
  server.Disconnect();
}

MessageActionControl.h

Sends commands and receives status. Command message sent by program 'myname' must has following format:

server.init(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 messages in CLAS12.


MessageActionEPICS.h

Sends and receives EPICS messages. Message sent by program 'myname' must has following format:

server.init(getenv("EXPID"), getenv("SESSION"), "epics", destination);
server << clrm << "epics" << "myname" << "hostname" << "username" << unix_time << "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)