QtService
1.1.0
A platform independent library to easily create system services and use some of their features
|
The main interface to implement to create a service. More...
#include <service.h>
Public Types | |
enum | CommandResult { OperationCompleted, OperationPending, OperationFailed, OperationExit, QT_SERVICE_POST_ENUM_DEPRECATED = OperationCompleted, QT_SERVICE_POST_ENUM_DEPRECATED = OperationCompleted } |
Indicates whether a service command has finished or needs to run asynchronously. More... | |
enum | TerminalMode { ReadOnly, WriteOnly, ReadWritePassive, ReadWriteActive } |
The modes a terminal can be in. More... | |
using | QT_SERVICE_POST_USING_DEPRECATED = CommandResult |
Public Slots | |
void | quit () |
Perform a graceful service stop. More... | |
void | reload () |
Perform a reload command. More... | |
void | setTerminalActive (bool terminalActive) |
WRITE accessor for Service::terminalActive. | |
void | setTerminalMode (TerminalMode terminalMode) |
WRITE accessor for Service::terminalMode. | |
void | setGlobalTerminal (bool globalTerminal) |
WRITE accessor for Service::globalTerminal. | |
void | setStartWithTerminal (bool startWithTerminal) |
WRITE accessor for Service::startWithTerminal. | |
Signals | |
void | started (bool success) |
Must be emitted when starting was completed if onStart returned OperationPending. | |
Q_DECL_DEPRECATED void | started () |
void | stopped (int exitCode=EXIT_SUCCESS) |
Must be emitted when stopping was completed if onStop returned OperationPending. | |
void | reloaded (bool success) |
Must be emitted when reloading was completed if onReload returned OperationPending. | |
Q_DECL_DEPRECATED void | reloaded () |
void | paused (bool success) |
Must be emitted when pausing was completed if onPause returned OperationPending. | |
Q_DECL_DEPRECATED void | paused () |
void | resumed (bool success) |
Must be emitted when resuming was completed if onResume returned OperationPending. | |
Q_DECL_DEPRECATED void | resumed () |
void | terminalActiveChanged (bool terminalActive, QPrivateSignal) |
NOTIFY accessor for Service::terminalActive. | |
void | terminalModeChanged (TerminalMode terminalMode, QPrivateSignal) |
NOTIFY accessor for Service::terminalMode. | |
void | globalTerminalChanged (bool globalTerminal, QPrivateSignal) |
NOTIFY accessor for Service::globalTerminal. | |
void | startWithTerminalChanged (bool startWithTerminal, QPrivateSignal) |
NOTIFY accessor for Service::startWithTerminal. | |
Public Member Functions | |
Service (int &argc, char **argv, int=QCoreApplication::ApplicationFlags) | |
Constructs a new service from the main arguments. More... | |
int | exec () |
Starts the service execution. More... | |
Q_INVOKABLE QList< int > | getSockets (const QByteArray &socketName) |
Returns all activated sockets found for the given name. More... | |
Q_INVOKABLE int | getSocket () |
Returns the default activated socket, if one exists. More... | |
QString | backend () const |
READ accessor for Service::backend. | |
QDir | runtimeDir () const |
READ accessor for Service::runtimeDir. | |
bool | isTerminalActive () const |
READ accessor for Service::terminalActive. | |
TerminalMode | terminalMode () const |
READ accessor for Service::terminalMode. | |
bool | isGlobalTerminal () const |
READ accessor for Service::globalTerminal. | |
bool | startWithTerminal () const |
READ accessor for Service::startWithTerminal. | |
Public Member Functions inherited from QObject | |
virtual const QMetaObject * | metaObject () const const |
virtual void * | qt_metacast (const char *) |
virtual int | qt_metacall (QMetaObject::Call, int, void **) |
QObject (QObject *parent) | |
virtual bool | event (QEvent *e) |
virtual bool | eventFilter (QObject *watched, QEvent *event) |
QString | objectName () const const |
void | setObjectName (const QString &name) |
bool | isWidgetType () const const |
bool | isWindowType () const const |
bool | signalsBlocked () const const |
bool | blockSignals (bool block) |
QThread * | thread () const const |
void | moveToThread (QThread *targetThread) |
int | startTimer (int interval, Qt::TimerType timerType) |
int | startTimer (std::chrono::milliseconds time, Qt::TimerType timerType) |
void | killTimer (int id) |
T | findChild (const QString &name, Qt::FindChildOptions options) const const |
QList< T > | findChildren (const QString &name, Qt::FindChildOptions options) const const |
QList< T > | findChildren (const QRegExp ®Exp, Qt::FindChildOptions options) const const |
QList< T > | findChildren (const QRegularExpression &re, Qt::FindChildOptions options) const const |
const QObjectList & | children () const const |
void | setParent (QObject *parent) |
void | installEventFilter (QObject *filterObj) |
void | removeEventFilter (QObject *obj) |
QMetaObject::Connection | connect (const QObject *sender, const char *signal, const char *method, Qt::ConnectionType type) const const |
bool | disconnect (const char *signal, const QObject *receiver, const char *method) const const |
bool | disconnect (const QObject *receiver, const char *method) const const |
void | dumpObjectTree () |
void | dumpObjectInfo () |
void | dumpObjectTree () const const |
void | dumpObjectInfo () const const |
bool | setProperty (const char *name, const QVariant &value) |
QVariant | property (const char *name) const const |
QList< QByteArray > | dynamicPropertyNames () const const |
void | destroyed (QObject *obj) |
void | objectNameChanged (const QString &objectName) |
QObject * | parent () const const |
bool | inherits (const char *className) const const |
void | deleteLater () |
Static Public Member Functions | |
static Service * | instance () |
Returns a reference to the currently running service. More... | |
Static Public Member Functions inherited from QObject | |
QString | tr (const char *sourceText, const char *disambiguation, int n) |
QString | trUtf8 (const char *sourceText, const char *disambiguation, int n) |
QMetaObject::Connection | connect (const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type) |
QMetaObject::Connection | connect (const QObject *sender, const QMetaMethod &signal, const QObject *receiver, const QMetaMethod &method, Qt::ConnectionType type) |
QMetaObject::Connection | connect (const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method, Qt::ConnectionType type) |
QMetaObject::Connection | connect (const QObject *sender, PointerToMemberFunction signal, Functor functor) |
QMetaObject::Connection | connect (const QObject *sender, PointerToMemberFunction signal, const QObject *context, Functor functor, Qt::ConnectionType type) |
bool | disconnect (const QObject *sender, const char *signal, const QObject *receiver, const char *method) |
bool | disconnect (const QObject *sender, const QMetaMethod &signal, const QObject *receiver, const QMetaMethod &method) |
bool | disconnect (const QMetaObject::Connection &connection) |
bool | disconnect (const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method) |
Protected Slots | |
virtual void | terminalConnected (Terminal *terminal) |
Is called by the backend for every newly connected terminal. More... | |
Protected Member Functions | |
virtual bool | preStart () |
Fallback method for otherwise impossible early setup (try to not use it) More... | |
virtual CommandResult | onStart ()=0 |
Is called by the backend to start the service. More... | |
virtual CommandResult | onStop (int &exitCode) |
Is called by the backend to stop the service. More... | |
virtual CommandResult | onReload () |
Is called by the backend to reload the service. More... | |
virtual CommandResult | onPause () |
Is called by the backend to pause the service. More... | |
virtual CommandResult | onResume () |
Is called by the backend to resume the service. More... | |
virtual QVariant | onCallback (const QByteArray &kind, const QVariantList &args) |
Is called by the backend if a platform specific callback was triggered. More... | |
virtual bool | verifyCommand (const QStringList &arguments) |
Is called from the terminal process to perform early CLI validation. More... | |
void | addCallback (const QByteArray &kind, const std::function< QVariant(QVariantList)> &fn) |
Adds a callback to be called by onCallback for the given kind. More... | |
template<typename TFunction > | |
void | addCallback (const QByteArray &kind, const TFunction &fn) |
Adds a callback to be called by onCallback for the given kind. More... | |
template<typename TClass , typename TReturn , typename... TArgs> | |
void | addCallback (const QByteArray &kind, TReturn(TClass::*fn)(TArgs...), std::enable_if_t< std::is_base_of< QtService::Service, TClass >::value, void *>=nullptr) |
Adds a callback to be called by onCallback for the given kind. More... | |
Protected Member Functions inherited from QObject | |
QObject * | sender () const const |
int | senderSignalIndex () const const |
int | receivers (const char *signal) const const |
bool | isSignalConnected (const QMetaMethod &signal) const const |
virtual void | timerEvent (QTimerEvent *event) |
virtual void | childEvent (QChildEvent *event) |
virtual void | customEvent (QEvent *event) |
virtual void | connectNotify (const QMetaMethod &signal) |
virtual void | disconnectNotify (const QMetaMethod &signal) |
Properties | |
QString | backend |
The backend this service is currently run with. More... | |
QDir | runtimeDir |
The runtime directory this service should place runtime files in. More... | |
bool | terminalActive |
Specifies whether the service accepts terminals. More... | |
TerminalMode | terminalMode |
Specifies the mode new terminals are started as. More... | |
bool | globalTerminal |
Specifies whether terminals from all users can connect, or only of the same user as the service. More... | |
bool | startWithTerminal |
Specifies whether terminals should try to start the service if it is not running. More... | |
Properties inherited from QObject | |
objectName | |
The main interface to implement to create a service.
This class is the primary interface for a service. In your own service, you will implement this class and use it as replacement for QCoreApplication:
Rules of usage:**
You should always follow the following rules when using/creating a service:
Indicates whether a service command has finished or needs to run asynchronously.
Enumerator | |
---|---|
OperationCompleted | The command was successfully completed synchronously. |
OperationPending | The command is beeing proccessed asynchronously and the service will emit the corresponding signal once it's done. |
OperationFailed | The command failed synchronously. The system may exit the service afterwards. |
OperationExit | The command executed successfully, but the service should still exit. Only usable from onStart() |
QT_SERVICE_POST_ENUM_DEPRECATED |
|
QT_SERVICE_POST_ENUM_DEPRECATED |
|
The modes a terminal can be in.
|
explicit |
Constructs a new service from the main arguments.
argc | The argc argument of the main |
argv | The argv argument of the main |
Create a service from the arguments passed to the application
|
protected |
Adds a callback to be called by onCallback for the given kind.
kind | The kind of command the callback should be registered for |
fn | The function to be called on such a command |
By using this method you can register a function as callback. When a comand of the given kind is send to the service the default implementation of the Service::onCallback method will call this callback with the arguments it received and return the value returned by it.
|
protected |
Adds a callback to be called by onCallback for the given kind.
TFunction | The type of the functor to be called |
kind | The kind of command the callback should be registered for |
fn | The function to be called on such a command |
By using this method you can register a function as callback. When a comand of the given kind is send to the service the default implementation of the Service::onCallback method will call this callback with the arguments it received and return the value returned by it.
This version will automatically convert the QVariantList arguments to the types that are required by the given method and convert the returned value back to QVariant. Please make shure the arguments types match the ones declared by the service backend, as different number or types can crash your application. Also, make shure all used types are registered to the metatype system via #Q_DECLARE_METATYPE
- otherwise the conversions will fail to compile.
|
protected |
Adds a callback to be called by onCallback for the given kind.
TClass | The type of your service subclass. Must extend QtService::Service |
TReturn | The return-type of the class member |
TArgs | The arguments of the class member |
kind | The kind of command the callback should be registered for |
fn | The function to be called on such a command |
By using this method you can register a function as callback. When a comand of the given kind is send to the service the default implementation of the Service::onCallback method will call this callback with the arguments it received and return the value returned by it.
With this overload you can pass a member function as callback to the service. The service will automatically bind it to the calling instance and then pass the method on to the generic function overload to perform the parameter conversions. (The 3rd parameter is only used as a compiler trick, it is never used and you should never pass anything as the 3rd argument)
This version will automatically convert the QVariantList arguments to the types that are required by the given method and convert the returned value back to QVariant. Please make shure the arguments types match the ones declared by the service backend, as different number or types can crash your application. Also, make shure all used types are registered to the metatype system via #Q_DECLARE_METATYPE
- otherwise the conversions will fail to compile.
QtService::Service::exec | ( | ) |
Starts the service execution.
This method is blocking and will internally call QCoreApplication::exec
at some point. In other words this method starts the service as well as the main event loop.
QtService::Service::getSocket | ( | ) |
Returns the default activated socket, if one exists.
On services that supports socket activation, you can retrieve an activated sockets with this method. If the backend supports getting the default, unnamed socket, then this method is an easy way to get it. If you want multiple sockets or can access them by name only, use Service::getSockets instead.
The returned socket can be used with classes like QTcpServer, QLocalServer or QWebSocketServer. All of these classes have a method to set an already activated socket descriptor they can work with.
QtService::Service::getSockets | ( | const QByteArray & | socketName | ) |
Returns all activated sockets found for the given name.
socketName | The name of the socket to be retrieved |
On services that supports socket activation, you can retrieve the activated sockets with this method. Typically, only one socket is found per name, but sometimes you may want to listen on different interfaces for the same service, thus it is possible multiple sockets share an identity. In case you only have a single unnamed socket, use Service::getSocket instead
The returned sockets can be used with classes like QTcpServer, QLocalServer or QWebSocketServer. All of these classes have a method to set an already activated socket descriptor they can work with.
|
static |
Returns a reference to the currently running service.
This is only set when actually running as service and the service has been created. Otherwise, nullptr is returned
|
protectedvirtual |
Is called by the backend if a platform specific callback was triggered.
kind | The kind of command that is beeing handeled |
args | The arguments of that command |
This method is called by the backend for any kind of custom command. The parameters and return value of the command depend on the kind of command it is. Check the Supported Service Backends documentation for a list of callbacks for each service backend.
Typically, you don't need to implement this method yourself. Instead, simply register a member of your service class as callback for a specific kind. That method will then be called by the default implementation of this method. Example:
|
protectedvirtual |
Is called by the backend to pause the service.
This method is called by the service manager if the serivce should pause whatever it is currently doing. Use the method to pause running operations like stopping accepting on sockets or pausing asynchronours calculations.
Also, depending on the serice backend your process may halt excution after entering the paused state, which means your service will actually stop running until it is resumed - however this behaviour is inconsistent on different platforms and you should never rely on it, only be prepared.
This method can behave in 2 ways. If you return Service::OperationCompleted, that the service engine assumes that pause has successfully been completed and the service leaves the "pausing" state and enters the "paused" state. However, you might need to perform an asynchronous operation during the pause. In that case Service::OperationPending can be returned to indicate that pausing has not been completed yet. The service will remain in the pausing state until you emit Servie::paused. Please note that beeing in the pausing state is also known by the service manager. Depending on the service backend this state may time out leading to the manager killing off your process if it takes to long. In case the application encounters an error, you can abort the command by either returning Service::OperationFailed for a synchronous fail or emit started with a fals result for asynchronous operations.
|
protectedvirtual |
Is called by the backend to reload the service.
This method can be called any time while the service is in it's running state. It is typically used by the service manager to tell the service that some configurations have changed and that it should reload those - it's basically a faster alternative to restarting the whole service.
This method can behave in 2 ways. If you return Service::OperationCompleted, that the service engine assumes that reload has successfully been completed and the service leaves the "reloading" state and goes back to the the "running" state. However, you might need to perform an asynchronous operation during the reload (like reconnecting to some dependend service). In that case Service::OperationPending can be returned to indicate that reloading has not been completed yet. The service will remain in the reloading state until you emit Servie::reloaded. Please note that beeing in the reloading state is also known by the service manager. Depending on the service backend this state may time out leading to the manager killing off your process if it takes to long. In case the application encounters an error, you can abort the command by either returning Service::OperationFailed for a synchronous fail or emit started with a fals result for asynchronous operations.
|
protectedvirtual |
Is called by the backend to resume the service.
This method is called by the service manager if the service should resume it's work after having been paused. This method is called by the backend as soon as the process continues it's execution. You can use the method to continue whatever you paused in Service::onPause.
This method can behave in 2 ways. If you return Service::OperationCompleted, that the service engine assumes that resume has successfully been completed and the service leaves the "resuming" state and enters the "running" state again. However, you might need to perform an asynchronous operation during the resume. In that case Service::OperationPending can be returned to indicate that resuming has not been completed yet. The service will remain in the resuming state until you emit Servie::resumed. Please note that beeing in the resuming state is also known by the service manager. Depending on the service backend this state may time out leading to the manager killing off your process if it takes to long. In case the application encounters an error, you can abort the command by either returning Service::OperationFailed for a synchronous fail or emit started with a fals result for asynchronous operations.
|
protectedpure virtual |
Is called by the backend to start the service.
At the point this method is called first thing after the eventloop has started and the service setup part of the backends has been completed. The service can now start doing it's actual work. Use this method to create the stuff your service needs to run, like starting servers etc.
This method can behave in 4 ways. If you return Service::OperationCompleted, the service engine assumes that startup has successfully been completed and the service leaves the "starting" state and enters the "running" state. However, you might need to perform an asynchronous operation during startup (like connecting to some dependend service). In that case Service::OperationPending can be returned to indicate that starting has not been completed yet. The service will remain in the starting state until you emit Servie::started. Please note that beeing in the starting state is also known by the service manager. Depending on the service backend this state may time out leading to the manager killing off your process if it takes to long. In case the application encounters an error, you can abort the command by either returning Service::OperationFailed for a synchronous fail or emit started with a fals result for asynchronous operations.
One special return value for the start command only is Service::OperationExit. It's the same as Service::OperationCompleted, but tells the system to stop the service immediatly after. This allows you to create "one-shot" style services that only do something when started and the quit.
|
protectedvirtual |
Is called by the backend to stop the service.
exitCode | [out] You can set this to the code your service should exit with |
This method is called by the backends if the service received a request to stop. Use this method to clean up stuff, close connections etc.
This method can behave in 3 ways. If you return Service::OperationCompleted, that the service engine assumes that stop has successfully been completed and the service leaves the "stopping" state and the proccess will quit after the backend completed it's internal cleanups. However, you might need to perform an asynchronous operation during the stop (like writing remaining data). In that case Service::OperationPending can be returned to indicate that stopping has not been completed yet. The service will remain in the stopping state until you emit Servie::stopped. Please note that beeing in the stopping state is also known by the service manager. Depending on the service backend this state may time out leading to the manager killing off your process if it takes to long.
In case you run the method synchronous, you can report an exit code to the parameter. If you don't set it, it will be set to EXIT_SUCCESS
- aka 0
on most platforms. For asynchronous stopping, use the signal parameter instead.
|
signal |
|
protectedvirtual |
Fallback method for otherwise impossible early setup (try to not use it)
true
if the service can continue to start, false
if it should abort starting and exitThis method can be used to perform startup operations that must be done before the eventloop starts. At the point of the method beeing called the QCoreApplication already exists and logging has been set up (however, depending on the platform might not work correctly yet). The services state however is uncertain and not ready yet.
|
slot |
Perform a graceful service stop.
Stops the service by using the appropriate method to do so for each backend. Use this method instead of QCoreApplication::quit (and QCoreApplication::exit), as the latter will not do a proper stop!
This method will initialize the stop which will eventually lead to Service::onStop beeing called and the service to quit
|
slot |
Perform a reload command.
This method will notify the service manager that the service is about to reload and the call Service::onReload. This allows you to perform some kind of reload operation without the service manager triggering it, but still report that it is happening to the manager.
|
signal |
|
signal |
|
signal |
|
protectedvirtualslot |
Is called by the backend for every newly connected terminal.
terminal | The connected terminal |
This methods is called internally if terminal mode is enabled and a terminal has connected. The whole initialization is done internally, which means at this point the terminal is connected and ready to be used. The commands are also already available at this point.
The ownership of the terminal is transferred to this method, whichs means your implementation must now take care of the terminal. The terminals parent object will already be this service instance.
|
protectedvirtual |
Is called from the terminal process to perform early CLI validation.
arguments | The terminal client arguments |
true
if the arguments are valid, false
if notThis method is called on a Terminal client (i.e. not the service process, but the terminal client process) before it tries to connect to the service. You can implement to provide an early validation of command line arguments which leads to a better experience when using terminals.
The arguments are pre-filtered, which means the application name as well as QtService-specific arguments do not appear here. So for example, the command service.exe --terminal --backend windows hello world
can be retrieved from this property as ["hello", "world"]
|
read |
|
readwrite |
Specifies whether terminals from all users can connect, or only of the same user as the service.
Default: false
In local mode (the default) only terminals started from the same user account as the one the service is running as can access the service. This is fine for user-mode services, but system services typically run as system user.
When in global mode, anyone can connect to the service, effectively bridging that barrier.
Accessors | |
---|---|
READ | globalTerminal() |
WRITE | setGlobalTerminal() |
NOTIFY | globalTerminalChanged() |
|
read |
The runtime directory this service should place runtime files in.
Default: Platform dependend
The runtime directory to be used to place sockets, lockfiles and other temporary stuff. This directoy may be managed by the underlying service framework and is the same as reported by the service control
Accessors | |
---|---|
READ | runtimeDir() |
CONSTANT |
|
readwrite |
Specifies whether terminals should try to start the service if it is not running.
Default: false
If enabled, the terminal client will use the ServiceControl of the corresponding service backend to determine whether the service is already running, and if not start it.
This of course will only work if the service supports starting. If status information is supported, the terminals will use that to check the state. Otherwise the simply to start in a fire and forget manner and then try to connect.
Accessors | |
---|---|
READ | startWithTerminal() |
WRITE | setStartWithTerminal() |
NOTIFY | startWithTerminalChanged() |
|
readwrite |
Specifies whether the service accepts terminals.
Default: false
Set this property to true to enable the internal terminal server. When activated, terminals that are created via --terminal
can connect to the service. Otherwise they won't be able to.
Accessors | |
---|---|
READ | isTerminalActive() |
WRITE | setTerminalActive() |
NOTIFY | terminalActiveChanged() |
|
readwrite |
Specifies the mode new terminals are started as.
Default: Service::ReadWriteActive
The terminal mode that terminal clients should use to connect to the service with. The mode determines how I/O is managed between the service and the terminal. The general recommendation is to design a terminal for Service::ReadWriteActive when it is intended to be used by a human, and use one of the other 3 for machine to machine communication, choosing whichever directions of communication are needed.
Please note that this property is evaluated from the terminals themselves, which means you should set it before calling Service::exec. Changing it on the service instance will have no effect.
Accessors | |
---|---|
READ | terminalMode() |
WRITE | setTerminalMode() |
NOTIFY | terminalModeChanged() |