Skip to content

Commit

Permalink
Merge pull request #675 from sruehl/feat/FindServers
Browse files Browse the repository at this point in the history
feat: add support for FindServers and FindServersOnNetwork
  • Loading branch information
magiconair authored Aug 22, 2023
2 parents a140977 + 1ed5a14 commit 8afa891
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 2 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,8 @@ Here is the current set of supported services. For low-level access use the clie

| Service Set | Service | Client | Notes |
|-----------------------------|-------------------------------|--------|--------------|
| Discovery Service Set | FindServers | | |
| | FindServersOnNetwork | | |
| Discovery Service Set | FindServers | Yes | |
| | FindServersOnNetwork | Yes | |
| | GetEndpoints | Yes | |
| | RegisterServer | | |
| | RegisterServer2 | | |
Expand Down
62 changes: 62 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,42 @@ import (
"github.com/gopcua/opcua/uasc"
)

// FindServers returns the servers known to a server or discovery server.
func FindServers(ctx context.Context, endpoint string, opts ...Option) ([]*ua.ApplicationDescription, error) {
opts = append(opts, AutoReconnect(false))
c, err := NewClient(endpoint, opts...)
if err != nil {
return nil, err
}
if err := c.Dial(ctx); err != nil {
return nil, err
}
defer c.Close(ctx)
res, err := c.FindServers(ctx)
if err != nil {
return nil, err
}
return res.Servers, nil
}

// FindServersOnNetwork returns the servers known to a server or discovery server. Unlike FindServers, this service is only implemented by discovery servers.
func FindServersOnNetwork(ctx context.Context, endpoint string, opts ...Option) ([]*ua.ServerOnNetwork, error) {
opts = append(opts, AutoReconnect(false))
c, err := NewClient(endpoint, opts...)
if err != nil {
return nil, err
}
if err := c.Dial(ctx); err != nil {
return nil, err
}
defer c.Close(ctx)
res, err := c.FindServersOnNetwork(ctx)
if err != nil {
return nil, err
}
return res.Servers, nil
}

// GetEndpoints returns the available endpoint descriptions for the server.
func GetEndpoints(ctx context.Context, endpoint string, opts ...Option) ([]*ua.EndpointDescription, error) {
opts = append(opts, AutoReconnect(false))
Expand Down Expand Up @@ -926,6 +962,32 @@ func (c *Client) Node(id *ua.NodeID) *Node {
return &Node{ID: id, c: c}
}

// FindServers finds the servers available at an endpoint
func (c *Client) FindServers(ctx context.Context) (*ua.FindServersResponse, error) {
stats.Client().Add("FindServers", 1)

req := &ua.FindServersRequest{
EndpointURL: c.endpointURL,
}
var res *ua.FindServersResponse
err := c.Send(ctx, req, func(v interface{}) error {
return safeAssign(v, &res)
})
return res, err
}

// FindServersOnNetwork finds the servers available at an endpoint
func (c *Client) FindServersOnNetwork(ctx context.Context) (*ua.FindServersOnNetworkResponse, error) {
stats.Client().Add("FindServersOnNetwork", 1)

req := &ua.FindServersOnNetworkRequest{}
var res *ua.FindServersOnNetworkResponse
err := c.Send(ctx, req, func(v interface{}) error {
return safeAssign(v, &res)
})
return res, err
}

// GetEndpoints returns the list of available endpoints of the server.
func (c *Client) GetEndpoints(ctx context.Context) (*ua.GetEndpointsResponse, error) {
stats.Client().Add("GetEndpoints", 1)
Expand Down
66 changes: 66 additions & 0 deletions examples/discovery/discovery.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright 2018-2020 opcua authors. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.

package main

import (
"context"
"flag"
"fmt"
"github.com/gopcua/opcua"
"github.com/gopcua/opcua/debug"
"log"
)

func main() {
endpoint := flag.String("endpoint", "opc.tcp://localhost:4840", "OPC UA Endpoint URL")
flag.BoolVar(&debug.Enable, "debug", false, "enable debug logging")
flag.Parse()
log.SetFlags(0)

ctx := context.Background()

if err := findServersOnNetwork(ctx, *endpoint); err != nil {
log.Print(err)
}

if err := findServers(ctx, *endpoint); err != nil {
log.Fatal(err)
}
}

func findServersOnNetwork(ctx context.Context, endpoint string) error {
log.Println("Finding servers on network")
servers, err := opcua.FindServersOnNetwork(ctx, endpoint)
if err != nil {
return err
}
for i, server := range servers {
fmt.Printf("%d Server on network:\n", i)
fmt.Printf(" -- RecordID: %v\n", server.RecordID)
fmt.Printf(" -- ServerName: %v\n", server.ServerName)
fmt.Printf(" -- DiscoveryURL: %v\n", server.DiscoveryURL)
fmt.Printf(" -- ServerCapabilities: %v\n", server.ServerCapabilities)
}
return nil
}

func findServers(ctx context.Context, endpoint string) error {
log.Println("Finding servers")
servers, err := opcua.FindServers(ctx, endpoint)
if err != nil {
return err
}
for i, server := range servers {
fmt.Printf("%dth Server:\n", i+1)
fmt.Printf(" -- ApplicationURI: %v\n", server.ApplicationURI)
fmt.Printf(" -- ProductURI: %v\n", server.ProductURI)
fmt.Printf(" -- ApplicationName: %v\n", server.ApplicationName)
fmt.Printf(" -- ApplicationType: %v\n", server.ApplicationType)
fmt.Printf(" -- GatewayServerURI: %v\n", server.GatewayServerURI)
fmt.Printf(" -- DiscoveryProfileURI: %v\n", server.DiscoveryProfileURI)
fmt.Printf(" -- DiscoveryURLs: %v\n", server.DiscoveryURLs)
}
return nil
}

0 comments on commit 8afa891

Please sign in to comment.