Struct Server

Source
pub struct Server(/* private fields */);
Expand description

OPC UA server.

This represents an OPC UA server. Nodes can be added through the several methods below.

Note: The server must be started with ServerRunner::run() before it can accept connections from clients.

Implementations§

Source§

impl Server

Source

pub fn new() -> (Self, ServerRunner)

Creates default server.

If you need more control over the initialization, use ServerBuilder instead, and turn it into Server by calling build().

§Errors

See ServerBuilder::build().

§Panics

See ServerBuilder::build().

Source

pub fn add_namespace(&self, namespace_uri: &str) -> u16

Adds a new namespace to the server. Returns the index of the new namespace.

If the namespace already exists, it is not re-created but its index is returned.

§Panics

The namespace URI must not contain any NUL bytes.

§Examples
let ns_index = server.add_namespace("http://hmi-project.com/UA/");

// Application URI takes index 1, new namespaces start at index 2.
assert!(ns_index >= 2);
Source

pub fn get_namespace_by_name(&self, namespace_uri: &String) -> Option<u16>

Looks up namespace by its URI.

This returns the found namespace index.

§Examples
let ns_index = server.add_namespace("http://hmi-project.com/UA/");

let ns_uri = ua::String::new("http://hmi-project.com/UA/").unwrap();
assert_eq!(server.get_namespace_by_name(&ns_uri), Some(ns_index));
Source

pub fn get_namespace_by_index(&self, namespace_index: u16) -> Option<String>

Looks up namespace by its index.

This returns the found namespace URI.

§Examples
let ns_index = server.add_namespace("http://hmi-project.com/UA/");

let ns_uri = ua::String::new("http://hmi-project.com/UA/").unwrap();
assert_eq!(server.get_namespace_by_index(ns_index), Some(ns_uri));

Namespace index 0 is always the OPC UA namespace with a fixed URI:

let ns_uri = ua::String::new("http://opcfoundation.org/UA/").unwrap();
assert_eq!(server.get_namespace_by_index(0), Some(ns_uri));
Source

pub fn add_node<T: Attributes>(&self, node: Node<T>) -> Result<NodeId>

Adds node to address space.

This returns the node ID that was actually inserted (when no explicit requested new node ID was given in node).

§Errors

This fails when the node cannot be added.

Source

pub fn add_object_node(&self, object_node: ObjectNode) -> Result<NodeId>

Adds object node to address space.

This returns the node ID that was actually inserted (when no explicit requested new node ID was given in node).

§Errors

This fails when the node cannot be added.

Source

pub fn add_variable_node(&self, variable_node: VariableNode) -> Result<NodeId>

Adds variable node to address space.

This returns the node ID that was actually inserted (when no explicit requested new node ID was given in node).

§Errors

This fails when the node cannot be added.

Source

pub fn add_data_source_variable_node( &self, variable_node: VariableNode, data_source: impl DataSource + 'static, ) -> Result<NodeId>

Adds variable node with data source to address space.

This returns the node ID that was actually inserted (when no explicit requested new node ID was given in node).

§Errors

This fails when the node cannot be added.

Source

pub fn add_method_node( &self, method_node: MethodNode, callback: impl MethodCallback + 'static, ) -> Result<(NodeId, (NodeId, NodeId))>

Adds method node to address space.

This returns the node ID that was actually inserted (when no explicit requested new node ID was given in node), along with the node IDs for the input and output argument nodes.

§Errors

This fails when the node cannot be added.

Source

pub fn delete_node(&self, node_id: &NodeId) -> Result<()>

Deletes node from address space.

This also deletes all references leading to the node.

§Errors

This fails when the node cannot be deleted.

Source

pub fn add_reference( &self, source_id: &NodeId, reference_type_id: &NodeId, target_id: &ExpandedNodeId, is_forward: bool, ) -> Result<()>

Adds a reference from one node to another.

§Errors

This fails when adding the reference fails.

§Examples
use open62541_sys::{UA_NS0ID_ORGANIZES};

// let parent_one_node_id = server.add_node(/* snip */)?;
// let parent_two_node_id = server.add_node(/* snip */)?;

let variable_node_id = server.add_node(Node::new(
    parent_one_node_id.clone(),
    ua::NodeId::ns0(UA_NS0ID_ORGANIZES),
    ua::QualifiedName::new(1, "Variable"),
    ua::VariableAttributes::init(),
))?;

// This makes the variable available in two parents.
server.add_reference(
    &parent_two_node_id,
    &ua::NodeId::ns0(UA_NS0ID_ORGANIZES),
    &variable_node_id.clone().into_expanded_node_id(),
    true,
)?;

// Duplicating an existing reference is not allowed.
let error = server.add_reference(
    &parent_one_node_id,
    &ua::NodeId::ns0(UA_NS0ID_ORGANIZES),
    &variable_node_id.clone().into_expanded_node_id(),
    true,
).unwrap_err();
assert_eq!(error.status_code(), ua::StatusCode::BADDUPLICATEREFERENCENOTALLOWED);
Source

pub fn delete_reference( &self, source_node_id: &NodeId, reference_type_id: &NodeId, target_node_id: &ExpandedNodeId, is_forward: bool, delete_bidirectional: bool, ) -> Result<()>

Deletes a reference between two nodes.

§Errors

This fails when deleting the reference fails.

Source

pub fn create_event(&self, event_type: &NodeId) -> Result<NodeId>

Creates an event.

This returns the ua::NodeId of the created event.

§Errors

This fails when the event could not be created.

Source

pub fn trigger_event( &self, event_node_id: &NodeId, origin_id: &NodeId, delete_event_node: bool, ) -> Result<EventId>

Triggers an event.

This returns the ua::EventId of the new event.

§Errors

This fails when the event could not be triggered.

Source

pub fn browse( &self, max_references: usize, browse_description: &BrowseDescription, ) -> BrowseResult

Browses specific node.

Use ua::BrowseDescription::default() to set sensible defaults to browse a specific node’s children (forward references of the HierarchicalReferences type) like this:

use open62541_sys::UA_NS0ID_SERVER_SERVERSTATUS;

let node_id = ua::NodeId::ns0(UA_NS0ID_SERVER_SERVERSTATUS);
let browse_description = ua::BrowseDescription::default().with_node_id(&node_id);
let (references, continuation_point) = server.browse(1000, &browse_description)?;
§Errors

This fails when the node does not exist or it cannot be browsed.

Source

pub fn browse_next( &self, continuation_point: &ContinuationPoint, ) -> BrowseResult

Browses continuation point for more references.

This uses a continuation point returned from browse() whenever not all references were returned (due to max_references).

§Errors

This fails when the browsing was not successful.

Source

pub fn browse_recursive( &self, browse_description: &BrowseDescription, ) -> Result<Array<ExpandedNodeId>>

Browses nodes recursively.

This is a non-standard version of the Browse service that recurses into child nodes. This handles possible loops (that can occur for non-hierarchical references) and adds every node at most once to the resulting list.

Nodes are only added if they match the NodeClassMask in the BrowseDescription. However, child nodes are still recursed into if the NodeClass does not match. So it is possible, for example, to get all VariableNodes below a certain ObjectNode, with additional objects in the hierarchy below.

§Errors

This fails when the browsing was not successful.

§Examples
use open62541_sys::UA_NS0ID_SERVER_SERVERSTATUS;

let targets = server.browse_recursive(
    &ua::BrowseDescription::default().with_node_id(
        &ua::NodeId::ns0(UA_NS0ID_SERVER_SERVERSTATUS),
    ),
)?;

// Browse above returns the expected number of well-known nodes.
assert_eq!(targets.len(), 12);
Source

pub fn browse_simplified_browse_path( &self, origin: &NodeId, browse_path: &[QualifiedName], ) -> Result<Array<BrowsePathTarget>>

Browses simplified browse path.

This specifies a relative path using ua::QualifiedName instead of ua::RelativePath, using forward references and subtypes of HierarchicalReferences, matching the defaults of ua::BrowseDescription. All nodes followed by browse_path shall be of the node classes Object or Variable.

See translate_browse_path_to_node_ids() if you need more control over the references involved.

§Errors

This fails when the browsing was not successful.

§Examples
use open62541_sys::{
    UA_NS0ID_SERVER_SERVERSTATUS, UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_PRODUCTNAME,
};

let target_name_1 = ua::QualifiedName::new(0, "BuildInfo");
let target_name_2 = ua::QualifiedName::new(0, "ProductName");

let targets = server.browse_simplified_browse_path(
    &ua::NodeId::ns0(UA_NS0ID_SERVER_SERVERSTATUS),
    &[target_name_1, target_name_2],
)?;

// Translation above returns a single target.
assert_eq!(targets.len(), 1);
let target = &targets[0];

// The given path leads to the right node ID.
assert_eq!(
    target.target_id(),
    &ua::NodeId::ns0(UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_PRODUCTNAME)
        .into_expanded_node_id()
);

// All relative path elements were processed.
assert_eq!(target.remaining_path_index(), None);
Source

pub fn translate_browse_path_to_node_ids( &self, browse_path: &BrowsePath, ) -> Result<Array<BrowsePathTarget>>

Translates browse path to node IDs.

§Errors

An error will be returned if the translation was not successful.

§Examples
use open62541_sys::{
    UA_NS0ID_SERVER_SERVERSTATUS, UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_PRODUCTNAME,
};

let target_name_1 = ua::QualifiedName::new(0, "BuildInfo");
let target_name_2 = ua::QualifiedName::new(0, "ProductName");

let targets = server.translate_browse_path_to_node_ids(&ua::BrowsePath::init()
    .with_starting_node(&ua::NodeId::ns0(UA_NS0ID_SERVER_SERVERSTATUS))
    .with_relative_path(&ua::RelativePath::init()
        .with_elements(&[
            ua::RelativePathElement::init().with_target_name(&target_name_1),
            ua::RelativePathElement::init().with_target_name(&target_name_2),
        ])
    )
)?;

// Translation above returns a single target.
assert_eq!(targets.len(), 1);
let target = &targets[0];

// The given path leads to the right node ID.
assert_eq!(
    target.target_id(),
    &ua::NodeId::ns0(UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_PRODUCTNAME)
        .into_expanded_node_id()
);

// All relative path elements were processed.
assert_eq!(target.remaining_path_index(), None);
Source

pub fn read_attribute<T: Attribute>( &self, node_id: &NodeId, attribute: T, ) -> Result<DataValue<T::Value>>

Reads node attribute.

This method supports static dispatch to the correct value type at compile time and can be used in two ways:

  1. Use statically known attribute type _T from ua::AttributeId to get correct value type directly.
  2. Use dynamic ua::AttributeId value and handle the resulting ua::Variant.
§Errors

This fails when the node does not exist or the attribute cannot be read.

§Examples
let node_id = ua::NodeId::ns0(UA_NS0ID_SERVER_SERVERSTATUS);

// Use static dispatch to get expected value type directly:
let browse_name = server
    .read_attribute(&node_id, ua::AttributeId::BROWSENAME_T)?
    .into_value();
// The type of `browse_name` is `ua::QualifiedName` here.
assert_eq!(browse_name, ua::QualifiedName::new(0, "ServerStatus"));

// Use dynamic attribute and unwrap `ua::Variant` manually:
let attribute_id: ua::AttributeId = ua::AttributeId::BROWSENAME;
let browse_name = server.read_attribute(&node_id, &attribute_id)?.into_value();
// The type of `browse_name` is `ua::Variant` here.
let browse_name = browse_name.to_scalar::<ua::QualifiedName>().unwrap();
assert_eq!(browse_name, ua::QualifiedName::new(0, "ServerStatus"));
Source

pub fn write_value(&self, node_id: &NodeId, value: &Variant) -> Result<()>

Writes node value.

§Errors

This fails when the node does not exist or its value attribute cannot be written.

Source

pub fn write_data_value( &self, node_id: &NodeId, value: &DataValue, ) -> Result<()>

Writes a DataValue to a node.

§Errors

This fails when the node does not exist or its value attribute cannot be written.

Source

pub fn read_object_property( &self, object_id: &NodeId, property_name: &QualifiedName, ) -> Result<Variant>

Reads object property.

§Errors

This fails when reading the object property was not successful.

§Examples
let value = server.read_object_property(
    &object_node_id,
    &ua::QualifiedName::new(1, "SomeVariable"),
)?;
Source

pub fn write_object_property( &self, object_id: &NodeId, property_name: &QualifiedName, value: &Variant, ) -> Result<()>

Writes object property.

The property is represented as a VariableNode with a HasProperty reference from the ObjectNode. The VariableNode is identified by its BrowseName. Writing the property sets the value attribute of the VariableNode.

§Errors

This fails when writing the object property was not successful.

§Examples
server.write_object_property(
    &object_node_id,
    &ua::QualifiedName::new(1, "SomeVariable"),
    &ua::Variant::scalar(ua::String::new("LoremIpsum")?),
)?;
Source

pub unsafe fn statistics(&self) -> ServerStatistics

Gets server statistics.

§Safety

This must only be called when no other server operations are underway, on this instance or any of its clones (including background activity). In other words, you must have exclusive access to the underlying server and it must not be operating.

Trait Implementations§

Source§

impl Clone for Server

Source§

fn clone(&self) -> Server

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Server

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl Freeze for Server

§

impl RefUnwindSafe for Server

§

impl Send for Server

§

impl Sync for Server

§

impl Unpin for Server

§

impl UnwindSafe for Server

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.