Server API

pvxs::server::Server represents a PVA protocol server.

#include <pvxs/server.h>
namespace pvxs { namespace server { ... } }

The basic recipe to run a server using configuration from the process environment is:

auto serv = server::Config::fromEnv()
            .build()
// calls to serv.addPV() or serv.addSource()
serv.run(); // run intil SIGINT or serv.interrupt()
// could also call serv.start() and later serv.stop()

A useful server will have one or more pvxs::server::Source instances added to it with addSource() method. Common usage will be with pvxs::server::StaticSource and one or more pvxs::server::SharedPV.

If more than one Source is added, then an order of precedence is established through the “order” argument of addSource(). In the event that more than one Source could provide/claim a given PV name, the Source with the lowest “order” will win.

Configuration

The recommended starting point when configuring a Server is pvxs::server::Config::fromEnv() which will use the following environment variables when set.

Entries naming multiple environment variables will prefer the left most which is set. eg. EPICS_PVA_ADDR_LIST is only checked if EPICS_PVAS_BEACON_ADDR_LIST is unset.

EPICS_PVAS_INTF_ADDR_LIST

Space seperated list of local interface addresses to which the server will bind. Port numbers are parsed and ignore. Sets pvxs::server::Config::interfaces

EPICS_PVAS_BEACON_ADDR_LIST or EPICS_PVA_ADDR_LIST

Space seperated list of unicast or broadcast addresses. This list is supplimented all local broadcast addresses if auto-beacon is YES. Sets pvxs::server::Config::beaconDestinations

EPICS_PVAS_AUTO_BEACON_ADDR_LIST or EPICS_PVA_AUTO_ADDR_LIST

YES or NO. Sets pvxs::server::Config::auto_beacon

EPICS_PVAS_SERVER_PORT or EPIC_PVAS_SERVER_PORT

Single integer. Prefered TCP port to bind. If already in use then a random port will be choosen. Sets pvxs::server::Config::tcp_port

EPICS_PVAS_BROADCAST_PORT or EPICS_PVA_BROADCAST_PORT

Single integer. UDP port to bind. If already in use, then an exception is thrown. Sets pvxs::server::Config::udp_port

EPICS_PVAS_IGNORE_ADDR_LIST

Space seperated list of addresses with optional port. Port zero is treated as a wildcard to match any port. UDP traffic from matched addresses will be ignored with no further processing.

EPICS_PVA_CONN_TMO

Inactivity timeout for TCP connections. For compatibility with pvAccessCPP a multiplier of 4/3 is applied. So a value of 30 results in a 40 second timeout.

New in version 0.3.0: All *_ADDR_LIST may contain IPv4 multicast, and IPv6 uni/multicast addresses.

New in version 0.2.0: Prior to 0.2.0 EPICS_PVA_CONN_TMO was ignored.

struct pvxs::server::Config

Configuration for a Server.

Public Functions

Config &applyEnv()

update using defined EPICS_PVA* environment variables

Config &applyDefs(const defs_t &def)

update with definitions as with EPICS_PVA* environment variables. Process environment is not changed.

void updateDefs(defs_t &defs) const

extract definitions with environment variable names as keys. Process environment is not changed.

void expand()

Apply rules to translate current requested configuration into one which can actually be loaded based on current host network configuration.

Explicit use of expand() is optional as the Context ctor expands any Config given. expand() is provided as a aid to help understand how Context::effective() is arrived at.

Post

autoAddrList==false

Server build() const

Create a new Server using the current configuration.

Public Members

std::vector<std::string> interfaces

List of network interface addresses (not host names) to which this server will bind. interfaces.empty() treated as an alias for “0.0.0.0”, which may also be given explicitly. Port numbers are optional and unused (parsed and ignored)

std::vector<std::string> ignoreAddrs

Ignore client requests originating from addresses in this list. Entries must be IP addresses with optional port numbers. Port number zero (default) is treated as a wildcard which matches any port.

Since

0.2.0

std::vector<std::string> beaconDestinations

Addresses (not host names) to which (UDP) beacons message will be sent. May include broadcast and/or unicast addresses. Supplemented iif auto_beacon==true

unsigned short tcp_port = 5075

TCP port to bind. Default is 5075. May be zero.

unsigned short udp_port = 5076

UDP port to bind. Default is 5076. May be zero, cf. Server::config() to find allocated port.

bool auto_beacon = true

Whether to populate the beacon address list automatically. (recommended)

double tcpTimeout = 40.0

Inactivity timeout interval for TCP connections. (seconds)

Since

0.2.0

ServerGUID guid = {}

Server unique ID. Only meaningful in readback via Server::config()

Public Static Functions

Config fromEnv()

Default configuration using process environment.

Config isolated(int family = AF_INET)

Configuration limited to the local loopback interface on a randomly chosen port. Suitable for use in self-contained unit-tests.

Since

0.3.0 Address family argument added.

class pvxs::server::Server

PV Access protocol server instance

Use a Config to determine how this server will bind, listen, and announce itself.

In order to be useful, a Server will have one or more Source instances added to it with addSource().

As a convenience, each Server instance automatically contains a “__builtin” StaticSource to which SharedPV instances can be directly added. The “__builtin” has priority zero, and can be accessed or even removed like any Source explicitly added with addSource().

There is also a “__server” source which provides the special “server” PV used by the pvlist CLI.

Public Functions

constexpr Server() = default

An empty/dummy Server.

Server(const Config&)

Create/allocate, but do not start, a new server with the provided config.

Server &start()

Begin serving. Does not block.

Server &stop()

Stop server.

Server &run()

start() and then (maybe) stop()

run() may be interrupted by calling interrupt(), or by SIGINT or SIGTERM (only one Server per process)

Intended to simple CLI programs. Only one Server in a process may be in run() at any moment. Other use case should call start()/stop()

Server &interrupt()

Queue a request to break run()

const Config &config() const

effective config

client::Config clientConfig() const

Create a client configuration which can communicate with this Server. Suitable for use in self-contained unit-tests.

Server &addPV(const std::string &name, const SharedPV &pv)

Add a SharedPV to the “__builtin” StaticSource.

Server &removePV(const std::string &name)

Remove a SharedPV from the “__builtin” StaticSource.

Server &addSource(const std::string &name, const std::shared_ptr<Source> &src, int order = 0)

Add a Source to this server with an arbitrary source name.

Source names beginning with “__” are reserved for internal use. eg. “__builtin” and “__server”.

Parameters
Exceptions
  • std::runtime_error: If this (name, order) has already been added.

std::shared_ptr<Source> removeSource(const std::string &name, int order = 0)

Disassociate a Source using the name and priority given to addSource()

std::shared_ptr<Source> getSource(const std::string &name, int order = 0)

Fetch a previously added Source.

std::vector<std::pair<std::string, int>> listSource()

List all source names and priorities.

Public Static Functions

Server fromEnv()

Create new server based on configuration from $EPICS_PVA* environment variables.

Shorthand for

Config::fromEnv().build() 
.
Since

0.2.1

IOC Integration

#include <pvxs/server.h>
namespace pvxs { namespace namespace ioc { ... } }

The separate “pvxsIoc” library exists to run a PVXS server as part of an IOC. See also Including PVXS in your application.

IOC Integration respects the $PVXS_LOG as well as $EPICS_PVA* environment variables. Changes to this environment variable are possible prior to calling “*_registerRecordDeviceDriver(pdbbase)”.

IOC shell

The “pvxsIoc” library adds several IOC shell functions and variables.

pvxsr(int level)

PVXS Server Report. Shows information about server config (level==0) or about connected clients (level>0). Indirectly calls pvxs::server::Source::show().

pvxsl(int level)

PVXS Server List. Lists attached Sources and PV names. Indirectly calls pvxs::server::Source::onList().

Adding PVs

server::Server pvxs::ioc::server()

Return the singleton Server instance which is setup for use in an IOC process.

This Server instance is created during a registrar function, started by the initHookAfterCaServerRunning phase of iocInit(). It is stopped and destroyed during an epicsAtExit() hook added during an initHookAfterInitDatabase hook..

Any configuration changes via. epicsEnvSet() must be made before registrars are run by *_registerRecordDeviceDriver(pdbbase).

server::SharedPV and server::Source added before iocInit() will be available immediately. Others may be added (or removed) later.

static void myinitHook(initHookState state) {
    if(state!=initHookAfterIocBuilt)
        return;

    server::SharedPV mypv(...);
    ioc::server()
          .addPV("my:pv:name", mypv);
}
static void myregistrar() {
    initHookRegister(&myinitHook);
}
extern "C" {
    epicsExportRegistrar(myregistrar); // needs matching entry in .dbd
}
Exceptions
  • std::logic_error: if called before instance is created, or after instance is destroyed.