class MyClass : public MqC ... { ... } int main (int argc, MQ_CST argv[]) { MyClass ctx; ... }
MqConfig... or by using command-line arguments.PATH and additional arguments like a script name or required startup options. The startup-prefix is used for two different purpose:The startup-prefix is initially set by ccmsgque during package loading.
struct MqBufferLS * init = MqInitCreate(); MqBufferLAppendC(init, "myExecutable"); MqBufferLAppendC(init, "myFirstArgument");
MQ_INT, get: ConfigGetBuffersize , set: ConfigSetBuffersizeThe send and receive buffersize in bytes (default: 4KB)
MQ_INT, get: ConfigGetDebug , set: ConfigSetDebugDebug a message-queue application. Valid values are 0 <= NUM <= 9 using 0 for "no debugging" and 9 for "maximum debugging". (default: 0)
MQ_TIME_T, get: ConfigGetTimeout , set: ConfigSetTimeoutUser defined timeout used for connection setup and data sending (default: 90 seconds)
MQ_CST, get: ConfigGetName , set: ConfigSetNameUse STRING as basename of the new message-queue object. The name shows up in the debugging output and is used as prefix for the new created command. (default: the name of the executable)
MQ_CST, get: ConfigGetSrvName , set: ConfigSetSrvNameUse STRING as a client specific prefix in the server debugging output. This is used to link debugging and error messages on the server to a specific client connection. (default: empty)
bool, get: ConfigGetIsSilent , set: ConfigSetIsSilentWrite (MQ_NO) or don't write (MQ_YES) any output to stdout or stderr. (default: write to stdout or stderr)
bool, get: ConfigGetIsString , set: ConfigSetIsStringUse (MQ_YES), as much as possible, strings in the data-package. Convert any native data-type, like integer or double, into a string (sending) and back to native (receiving). (default: use binary)
enum MqStartE, get: ConfigGetStartAs , set: ConfigSetStartAs (startAs)Start a new server as thread or spawn a new process or fork a new process. This arguments are used with:
| [in] | startAs | 0=default, 1=fork, 2=thread and 3=spawn |
MQ_CST, get: NO , set: ConfigSetDaemon (pidfile)Close all default IO (e.g stdout, stdin, stderr) and fork the server into the background. (default: no daemon)
| [in] | pidfile | the name of the file to write the PID into |
MQ_CST, get: ConfigGetIoTcpHost/Port/MyHost/MyPort , set: ConfigSetIoTcp (host, port, myhost, myport)Configure a tcp socket link.
| host | client: name of the remote host (default: localhost) server: name of the local interface (default: listen on all interfaces) | |
| port | client: name of the remote port server: name of the local port | |
| myhost | client: name of the local interface | |
| myport | client: name of the local port |
MQ_CST, get: ConfigGetIoUdsFile , set: ConfigSetIoUds (file)Use a uds (http://en.wikipedia.org/wiki/Unix_domain_socket) socket link. The uds communication is usually 50% faster than a local tcp communication but only available on UNIX.
| [in] | file | the name of the uds file |
MQ_SOCK, get: ConfigGetIoPipeSocket , set: ConfigSetIoPipe (socket)Start a pipe server to listen on socket. This is the default mode to start a server. The socket option is special because it is used for internal purpose to submit the socket from the client to the server started as pipe by the client.
| [in] | socket | the file-descriptor number. The only public usage for this option is to serve as interface for an existing tool like (x)inetd. The (x)inetd tool is a UNIX service to listen on a tcp/ip port and start for every connection the proper entry from the file /etc/(x)inetd.conf with the file-descriptor 0 as send/recv socket handle. |
MqC, get: ConfigGetMaster , set: SLAVE OBJECTreturn the master if ctx is a slave-context or NULL if ctx is not a slave-context. !Only a SLAVE has a master!
MQ_SIZE, get: ConfigGetCtxId , set: NO
return an identifier as integer and is unique per parent-context. The parent-context is always 0 and every new child-context get a new identifier by adding 1.
MQ_CST, get: ConfigGetToken , set: NOreturn the current TOKEN IDENTIFIER and is only useful in a service callback. This command is needed on the server to implement a generic service (A ctx.ServiceCreate(MQ_CST const token, IService * const service) with different TOKEN IDENTIFIER but with the same service callback).
bool, get: ConfigGetIsConnected , set: NOIs the ccmsgque context connected ? A context is connected if the ctx.LinkCreate(struct MqBufferLS * args) command was successful and a context is NOT connected if a) the object has just been created or b) the link was deleted with ctx.LinkDelete()
bool, get: ConfigGetIsServer , set: IServerSetup or IServerCleanupTrue if object is a server object (default: MQ_NO, be a client)
bool, get: ConfigGetIsParent , set: NOTrue if object is a parent object (default: MQ_YES, be a parent)
bool, get: ConfigGetIsSlave , set: NOTrue if object is a slave object (default: MQ_NO, not be a slave)
Interface, get: NO , set: ccmsgque::IServerSetupInterface to define a server ccmsgque object. This Interface define the ServerSetup callback called at ctx.LinkCreate(struct MqBufferLS * args) to define the services or to initialize context specific variables. This interface set the isServer configuration value to MQ_YES.
Interface, get: NO , set: ccmsgque::IServerCleanupInterface to define a server ccmsgque object. This Interface define the ServerCleanup callback called at ctx.LinkDelete() to free context specific variables. This interface set the isServer configuration value to MQ_YES.
Interface, get: NO , set: ccmsgque::IFilterFTRInterface required to define a filter data stream object. This Interface define the IFilterFTR callback. The callback is used to act on filter data rows. Every filter input data is a list of filter data rows and every row is a list of filter data columns. Every row is send from one filter-command to the following filter-command as FTR service request. This interface set the isServer configuration value to MQ_YES. (read more at: FILTER MODE)
Interface, get: NO , set: ccmsgque::IFilterEOFInterface required to define a filter data stream object. This Interface define the IFilterEOF callback. The callback is used to act on End-Of-Filter data and is called after all IFilterFTR data was send. Sometimes the filter data can not be served as IFilterFTR data (example: sorting of the input rows need to read all rows before the data can be send to the next filter command) and the IFilterEOF callback is used to continue send IFilterFTR data rows. This interface set the isServer configuration value to MQ_YES. (read more at: FILTER MODE)
Interface, get: NO , set: ccmsgque::IFactoryThe factory pattern is used to create a new application object (read more at: MqSetupS::Factory) Without the Factory pattern only the initial startup context is available to serve incoming requests. In general every server need to provide a Factory pattern.
class Server: public MqC, public IFactory, ... { private: MqC* Factory() const { return new Server(); } ... }
Interface, get: NO , set: ccmsgque::IBgErrorDefine an asyncrone error handler. This handler is used for handle errors send with ctx.SendERROR(). Use int ex.num() or ctx.ErrorGetNum() and string ex.what() or ctx.ErrorGetText() to access the error.
| [in] | ctx | the object from OBJECT CREATION AND DELETION |
| [in] | args | command-line arguments including the "@" item for the --pipe setup |
| [in] | ctx | the object from OBJECT CREATION AND DELETION |
| [in] | parent | the parent object |
| [in] | args | all command-line arguments including the "@" token |
public void ServerSetup() { ServiceCreate ("SRV1", CallbackF(&MyServer::SRV1)); }
The callback is implemented using Interface: IService method Service(MqS ctx) or using t type void CallbackF().
| [in] | timeout | don't wait more than TIMEOUT seconds to get an answer from the server. If no answer is available an error is raised. (default: command-line: --timeout) |
| [in] | MqC.WAIT | use flag value to define the action (default: NO)
|
ctx.SendSTART(); ctx.SendI(num); ctx.SendL_START(); ctx.SendD(balance); ctx.SendC("name of the owner"); ctx.SendB(signature); ctx.SendL_END(); ctx.SendEND_AND_WAIT("SRV1")
num = ctx.ReadI(); ctx.ReadL_START(); balance = ctx.ReadD(); owner = ctx.ReadC(); signature = ctx.ReadB(); ctx.ReadL_END();
| [in] | ctx | the master ccmsgque object as SERVER-PARENT without a CHILD |
| [in] | id | an integer used as unique identifer for the master/slave link |
| [in] | args | command-line arguments passed to the worker-client or the worker-server. all arguments prior the first @ token are added to the worker-client and the other arguments to the worker-server. |
ctx.SlaveWorkerV (7, "--thread", "--silent", "@", "WORKER", "--name", "MyWorker", NULL);
| [in] | ctx | the master ccmsgque object as PARENT without a CHILD |
| [in] | id | an integer used as unique identifer for the master/slave link |
| [in] | slave | the slave ccmsgque object as CLIENT-PARENT without a CHILD |
ccmsgque support 2 different buffer objects:
Both objects are linked:MqBufferC buf = ctx.ReadU(); MQ_BUF buf2 = buf.GetU();
MqBufferC buf = ctx.ReadU(); if (buf.GetType() == MQ_STRT) printf(buf.GetC());
Y : 1 byte signed characterO : 1 byte boolean character using MQ_YES for yes or true or MQ_NO for no or wrongS : 2 byte signed shortI : 4 byte signed integerW : 8 byte signed long long integerF : 4 byte floatD : 8 byte doubleB : unsigned char array used for binary dataC : string data using a \0 at the endL : list type able to hold a list of all items from aboveU : typeless buffer able to hold a single item from above
try { i = ctx.ReadI(); } catch (const exception& ex) { ctx.ErrorSet(ex); cout << ctx.ErrorGetText() << endl; ctx.ErrorReset(); }
command1 | command2 | command3
msgcmd1 @ msgcmd2 @ msgcmd3
#include "ccmsgque.h" using namespace ccmsgque; class mulserver : public MqC, public IServerSetup, public IFactory { private: void MMUL () { SendSTART(); SendD(ReadD() * ReadD()); SendRETURN(); } MqC* Factory() const {return new mulserver();} void ServerSetup () { ServiceCreate("MMUL", CallbackF(&mulserver::MMUL)); } }; int MQ_CDECL main (int argc, MQ_CST argv[]) { mulserver ctx; try { ctx.ConfigSetName ("MyMulServer"); ctx.LinkCreateVC (argc, argv); ctx.ProcessEvent (); } catch (const exception& e) { ctx.ErrorSet(e); } ctx.Exit (); }
> mulserver --tcp --port 7777 --thread
#include <iostream> #include "ccmsgque.h" using namespace std; using namespace ccmsgque; int MQ_CDECL main (int argc, MQ_CST argv[]) { MqC ctx; try { ctx.ConfigSetName ("MyMulClient"); ctx.LinkCreateVC (argc, argv); ctx.SendSTART(); ctx.SendD(3.67); ctx.SendD(22.3); ctx.SendEND_AND_WAIT("MMUL", 5); cout << ctx.ReadD() << endl; } catch (const exception& e) { ctx.ErrorSet(e); } ctx.Exit(); }
> mulclient --tcp --port 7777
#include "ccmsgque.h" using namespace std; using namespace ccmsgque; class manfilter : public MqC, public IFilterFTR { public: void fFTR () { MQ_BUF temp = GetTempBuffer(); SendSTART(); while (ReadItemExists()) { SendU(MqBufferSetV(temp, "<%s>", ReadC())); } SendFTR(); } }; int MQ_CDECL main (int argc, MQ_CST argv[]) { manfilter filter; try { filter.ConfigSetName ("manfilter"); filter.LinkCreateVC(argc, argv); filter.ProcessEvent (); } catch (const exception& e) { filter.ErrorSet(e); } filter.Exit(); }
> echo -e "1:2:3\na:b:c" | atool split -d : @ manfilter @ atool join -d :
1.5.8