|
PdCom
4.2
Process data communication client
|
Base class for PdCom protocol handler. More...
#include <Process.h>
Classes | |
| struct | Message |
| Message structure. More... | |
Public Types | |
| enum | LogLevel_t { Reset, Emergency, Alert, Critical, Error, Warn, Info, Debug, Trace } |
| Log levels used in Message and protocolLog() More... | |
Public Member Functions | |
| Process () | |
| Constructor. | |
| virtual | ~Process () |
| Destructor. More... | |
| std::string | name () const |
| Remote process name string. | |
| std::string | version () const |
| Remote process version string. | |
| void | reset () |
| Reset communications and clean up internal buffers. | |
| virtual std::string | applicationName () const |
| Name of application user application. More... | |
| virtual std::string | hostname () const |
| Host name of remote server. More... | |
| virtual int | read (char *buf, size_t count)=0 |
| Read data from server. More... | |
| virtual void | write (const char *buf, size_t count)=0 |
| Write data to server. More... | |
| virtual void | flush ()=0 |
| Flush unsent data in output buffer. More... | |
| int | asyncData () |
| Library entry point for new data. More... | |
| virtual void | connected ()=0 |
| Protocol initialization completed. More... | |
| bool | list (const std::string &path) const |
| List a directory path. More... | |
| virtual void | listReply (std::list< const Variable *> &variables, std::list< std::string > &directories) |
| Reply to list() call. More... | |
| bool | find (const std::string &path) const |
| Find a variable with a corresponding path. More... | |
| virtual void | findReply (const Variable *variable) |
| Reply to find() More... | |
| bool | login (const char *mech, const char *clientData) const |
| Perform SASL login step. More... | |
| void | logout () const |
| Logout from server. | |
| virtual void | loginReply (const char *mechlist, const char *serverData, int finished) |
| SASL server reply to login() More... | |
| bool | startTLS () const |
| Start TLS. More... | |
| virtual void | startTLSReply () |
| TLS reply. More... | |
| void | ping () const |
| Ping server. | |
| virtual void | pingReply () |
| Ping reply. More... | |
| virtual bool | alive () |
| Test from process whether client is alive. More... | |
| void | subscribe (Subscriber *subscriber, const std::string &path, double interval, int id) const |
| Subscribe to a variable. More... | |
| void | unsubscribe (Subscriber *subscriber) const |
Unsubscribe all subscriptions from subscriber. | |
| void | parameterMonitor (Subscriber *subscriber, bool state) const |
| Turn parameter monitoring on/off. More... | |
| virtual void | processMessage (const Message &message) |
| Message event from process. More... | |
| void | getMessage (uint32_t seqNo) const |
| Request specific message from history. More... | |
| virtual void | getMessageReply (const Message &message) |
| Reply to getMessage() More... | |
| void | activeMessages () const |
| Request a list of all active messages. More... | |
| virtual void | activeMessagesReply (const std::list< Message > &messageList) |
| Reply to activeMessages() More... | |
| virtual void | protocolLog (LogLevel_t severity, const std::string &message) |
| Message event from protocol handler. More... | |
| virtual void | broadcastReply (const std::string &message, const std::string &attr) |
| Server broadcast. More... | |
| void | broadcast (const std::string &message, const std::string &attr="text") |
| Send broadcast to all clients. More... | |
| virtual void | transmitSemaphore (bool state) |
| Client to server communication semaphore. More... | |
Base class for PdCom protocol handler.
This is the base class to interact with real time process server. The PdCom protocol ist implemented using this class.
For socket input and output, the library completely relies on a derived class where read(), write(), flush() and connected() methods are reimplemented.
When data is available for reading, call asyncData() which in turn calls the reimplemented read() method.
When the protocol is initialized, the reimplemented connected() method is called. Other than startTLS(), login(), none of the command methods listed below may be called prior to connected().
After connected(), the following commands can be issued: * list(): list a directory; returns result in listReply() * find(): find a variable; returns result in findReply() * login(): start a SASL login interaction; returns result in loginReply() * ping(): ping the server; returns result in pingReply() * getMessage(): request a specific message result in multiple calls to processMessage() if required * Variable interactions * Variable::Subscription interactions
startTLS() and login() may only be called prior to connected() when the library has called startTLSReply() or loginReply() previously.
All these commands are non-blocking asynchronous calls and either return the result immediately with the corresponding reply methods or issue a command to the server using excessive (!) calls to write(). Data should be written to a buffer to optimize network communication. To flush the buffer to wire, flush() is issued by the library when required.
The server may query presence of the user by issuing an alive() call. Using this call, certain actions could be undertaken by the server if the user is not active any more.
Certain actions in the real time process, such as alarms, triggers a call to processMessage(). Messages are kept in a ring buffer in the process.
Calling activeMessages() will return a list of all active messages as well as the latest message in activeMessagesReply().
Any message can be recalled with getMessage(), the result returned in getMessageReply(). If the message does not exist, the Message returned will have the requested seqNo with path empty.
The subscribe() method subscribes a variable using the path only.
Log levels used in Message and protocolLog()
| Enumerator | |
|---|---|
| Reset | Message is reset. |
| Emergency | Emergency log level. |
| Alert | Alert log level. |
| Critical | Critical log level. |
| Error | Error log level. |
| Warn | Warn log level. |
| Info | Info log level. |
| Debug | Debug log level. |
| Trace | Trace log level. |
|
virtual |
Destructor.
The destructor cleans up all internally allocated structures
| void PdCom::Process::activeMessages | ( | ) | const |
Request a list of all active messages.
This will return a list of active process messages as well as the last message in activeMessagesReply() if its state is Reset.
|
virtual |
Reply to activeMessages()
Reimplement this method to receive the message list.
The process messages received in processMessage() has strictly increasing sequence numbers and time.
| messageList |
|
virtual |
Test from process whether client is alive.
In some cases the server may want to know whether the client is still alive. Default implementation is to return true. Reimplement this if you wish to control presence
|
virtual |
Name of application user application.
The application name is transferred to the server to be able to identify the clients more easily.
| int PdCom::Process::asyncData | ( | ) |
Library entry point for new data.
Calling this method tells the library that new data has arrived from the server and is waiting to be processed.
The library prepares an input buffer and then calls the reimplemented read() virtual method to read incoming data.
The return value of read() is returned by this method, enabling the user to be able to react to read errors, count bytes or even socket close, etc.
| void PdCom::Process::broadcast | ( | const std::string & | message, |
| const std::string & | attr = "text" |
||
| ) |
|
virtual |
Server broadcast.
Reimplement this method to receive server broadcasts
| message | Message |
| attr | Attribute |
|
pure virtual |
Protocol initialization completed.
This is a signal emitted by the library to indicate that protocol initialization has been completed and that library operations can be performed thereafter.
Reimplement this method to get the signal.
Absolutely NO process operations other than asyncData(), startTLS() and login() (and then only due to a previous loginReply() are permitted before this signal has been emitted.
| bool PdCom::Process::find | ( | const std::string & | path | ) | const |
Find a variable with a corresponding path.
If the path search is known (be it successful or unsuccessful), the variable is returned in the call to the reimplemented virtual findReply() method immediately and the method returns true;
If unsuccessful, the command is sent to the server to and the call returns immediately with false. Later on during asyncData(), findReply() is called when the server's reply is processed.
| path | path of variable to find |
|
virtual |
Reply to find()
This virtual method is called within the context of asyncData() when the server's reply to a variable discovery is processed.
findReply()ies are called in strict order of find()
| variable | pointer to Variable; NULL if not found |
|
pure virtual |
Flush unsent data in output buffer.
Reimplement this method to flush data in the output buffer.
This method tells the user that it is time to flush the output buffer to the wire. The library only expects that data is sent to the server within this call.
Essentially this method is a little wrapper around your socket's fflush() function:
| void PdCom::Process::getMessage | ( | uint32_t | seqNo | ) | const |
Request specific message from history.
The message is received in getMessageReply().
If the seqNo is not available, getMessageReply() is called with null path and requested seqNo.
| seqNo | sequence number of message |
|
virtual |
Reply to getMessage()
Reimplement this method to receive responses to getMessage().
| message |
|
virtual |
Host name of remote server.
Reimplement this method to return the remote server host name this library connects to. This is especially important in multi-hosted TLS environments, where multiple hosts resolv to the same IP address. TLS needs to know the original server host name.
| bool PdCom::Process::list | ( | const std::string & | path | ) | const |
List a directory path.
A process command to return all variables and directories within a directory path. The path parameter has typical unix character, with forward slashes '/' separating directories.
listReply() must be reimplemented to receive the reply to this call.
If the directory is cached (for instance a previous call to a similar path, or an entire server listing has been performed), listReply() is called within the context of this call and no server query is performed.
If uncached, the library sends a server query and returns immediately. Later on during asyncData(), the virtual method listReply(), is called when the server's reply is processed.
As a special case, an empty string (std::string()) for path will let the server list all its variables in one go. This possibility must be used with caution, as it can cause heavy network traffic.
| path | directory path |
|
virtual |
Reply to list() call.
You must reimplement this method to receive replies to list() calls.
Note that a variable can have the same path as a directory! An example is a vector variable with atomized elements.
Replies are in strict order of list() calls.
| variables | list of variables |
| directories | string list of directories |
| bool PdCom::Process::login | ( | const char * | mech, |
| const char * | clientData | ||
| ) | const |
Perform SASL login step.
| mech | SASL mechanism |
| clientData | Base64 encoded SASL output data to server |
Setting both mech and clientData to NULL will initate the login process.
Every call to login() is answered by a loginReply(), unless login is not supported. When login is mandatory, loginReply() will be called automatically.
|
virtual |
SASL server reply to login()
loginReply() may be called without calling login() in the case where login is mandatory. In this case, it is called before connected().
| mechlist | Space separated list of supported mechanisms |
| serverData | Base64 encoded SASL data from server |
| finished | > 0: Login successful 0: Login process not finished; another login() step is required < 0: Login failed |
| void PdCom::Process::parameterMonitor | ( | Subscriber * | subscriber, |
| bool | state | ||
| ) | const |
Turn parameter monitoring on/off.
Turning parameter monitoring automatically subscribes changed parameters.
The value is delivered just as with ordinary subscriptions in newValue(const Variable::Subscription* subscription), with the exception that there was no preceding subscribe() and there is no active() call.
There is no automatic unsubscribing. To save memory, it is safe to cancel() the automatic parameter subscription immediately within newValue().
|
virtual |
Ping reply.
You must reimplement this method to receive the reply to a ping() call.
|
virtual |
Message event from process.
This method is called whenever a message event is generated by the process.
Reimplement this method to receive them.
| message |
|
virtual |
|
pure virtual |
Read data from server.
Reimplement this method to transfer data from the server to the library. This method is called within the call to asyncData().
Essentially this method is a little wrapper around your socket's read() function:
The method must return the number of bytes read, which may of coarse be less than count or even 0. Return values of <= 0 are not interpreted by the protocol handler.
| buf | data destination |
| count | buffer size |
read() function, which in turn will be returned by asyncData() | bool PdCom::Process::startTLS | ( | ) | const |
Start TLS.
The initial server communication is in plain text. Encryption on the server side is initiated upon reception of a startTLS() command. The client may continue sending commands to the server, although these are still in plain text. Server replies to these commands are delayed in the server till after successful encryption. The server acknowledges reception of the startTLS() command using startTLSReply() whereafter the client must switch to TLS.
Server replies to commands sent by the client between startTLS() and startTLSReply() are stored in a limited buffer. The connection will be closed by the server if it overflows. Thus it is not recommended to send commands during this period, at least not ones where the replies are expected to be quite long!
Reimplement startTLSReply() to be able to use TLS.
|
virtual |
TLS reply.
Reimplement this command in the client. Upon reception, TLS must be activated.
| void PdCom::Process::subscribe | ( | Subscriber * | subscriber, |
| const std::string & | path, | ||
| double | interval, | ||
| int | id | ||
| ) | const |
Subscribe to a variable.
The subscription rate is specified using interval. Depending on the type of variable, signal or parameter, the interval has different meanings.
For parameters, the interval is ignored completely. Subscribed parameters are only updated when the value changes. It is available in Subscriber::newValue().
For signals, the interval specifies:
interval is ignored. The subscription value is available in Subscriber::newValue().Usually you would use interval <= 0. It reduces the required bandwidth. Fixed subscription interval > 0 is actually only required for logging purposes, such as an oscilloscope or data recorder.
| subscriber | pointer to subscriber object that will receive the subscription |
| path | variable path to subscribe |
| interval | see description |
| id | arbitrary user specified subscription id. The id is copied verbatim to the Variable::Subscription::id or during Subscriber::invalid() |
|
virtual |
Client to server communication semaphore.
Reimplement this method to intercept the transmission semaphore. The default implementation always returns success.
Every interaction from client to server (change a parameter, ping, etc) starts a message tag. If the client is multi-threaded, more than one message tag could be started which would lead to corruption. This semaphore can be used to serialize all client to server interactions.
| state | true = lock; false = release |
|
pure virtual |
Write data to server.
Reimplement this method to transfer data from the library to the server. This method is called when any library operation requires data to be sent to the server.
Note: the library makes many calls to write(), so use buffered output otherwise you're in for performance problems!
Essentially this method is a little wrapper around your socket's write() function:
Note: the library does not have an internal buffer and expects that all data is sent. If your implementation might send less than count, it is your responsibility to buffer the data and send it later.
| buf | data to be sent |
| count | number of bytes to send |
1.8.14