gopcua / opcua

Native Go OPC-UA library
MIT License
854 stars 258 forks source link

The session was closed by the client. StatusBadSessionClosed (0x80260000) #428

Open beyondyinjl2 opened 3 years ago

beyondyinjl2 commented 3 years ago

Use c.Client.Read(req) to read data regularly, once per second, after reading for a period of time (more than an hour), the error is reported as follows: The session was closed by the client. StatusBadSessionClosed (0x80260000) opcua: sechan: secure channel not open. panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x10 pc=0x713431]

goroutine 9382 [running]: github.com/gopcua/opcua.(Client).ActivateSession(0xc0000fe000, 0x0, 0x0, 0x0) /home/go-talkweb/pkg/mod/github.com/gopcua/opcua@v0.2.0-rc1/client.go:653 +0x51 github.com/gopcua/opcua.(Client).monitor(0xc0000fe000, 0x8d45e0, 0xc000070800) /home/go-talkweb/pkg/mod/github.com/gopcua/opcua@v0.2.0-rc1/client.go:360 +0xc85 created by github.com/gopcua/opcua.(*Client).Connect.func1 /home/go-talkweb/pkg/mod/github.com/gopcua/opcua@v0.2.0-rc1/client.go:216 +0x65

beyondyinjl2 commented 3 years ago

The session id is not valid. StatusBadSessionIDInvalid (0x80250000) The operation could not complete because the client is not connected to the server. StatusBadServerNotConnected (0x800D0000) sechan: secure channel not open.

m-manns commented 3 years ago

Hey,

I have the same error on my program with the v0.1.13 version and a KEPServerEX 6 OPC Server (but also other OPC servers). I decided to make a little snippet from the regread example to understand where the problem came from and use the new release v0.2.0-rc2 version. Here is it:

package main

import (
    "context"
    "log"
    "time"

    "github.com/gopcua/opcua"
    "github.com/gopcua/opcua/debug"
    "github.com/gopcua/opcua/ua"
)

func main() {
    debug.Enable = true
    endpoint := "opc.tcp://192.168.0.43:49320"
    nodeID := "ns=5;s=Test.Functions.Ramp1"
    secPolicy := ua.SecurityPolicyURIPrefix + "None"

    ctx := context.Background()
    // ctx, cancel := context.WithTimeout(context.Background(), 10000*time.Millisecond)
    // defer cancel()

    opts := make([]opcua.Option, 0, 8)
    opts = append(opts, opcua.ApplicationName("Test"))
    opts = append(opts, opcua.ProductURI("urn:test:driver:client:opc"))
    opts = append(opts, opcua.AuthUsername("testuser", "testuser"))
    endpoints, err := opcua.GetEndpoints(ctx, endpoint)
    if err != nil {
        log.Fatal(err)
    }
    var serverEndpoint *ua.EndpointDescription
    for _, e := range endpoints {
        if e.SecurityPolicyURI == secPolicy &&
            (serverEndpoint == nil || e.SecurityLevel >= serverEndpoint.SecurityLevel) {
            serverEndpoint = e
        }
    }
    opts = append(opts, opcua.SecurityFromEndpoint(serverEndpoint, ua.UserTokenTypeUserName))
    opts = append(opts, opcua.SecurityMode(ua.MessageSecurityModeNone))
    opts = append(opts, opcua.Lifetime(time.Duration(1*time.Minute)))
    // opts = append(opts, opcua.AutoReconnect(true))

    c := opcua.NewClient(endpoint, opts...)
    if err := c.Connect(ctx); err != nil {
        log.Fatal(err)
    }
    defer c.Close()

    id, err := ua.ParseNodeID(nodeID)
    if err != nil {
        log.Fatalf("invalid node id: %v", err)
    }
    regResp, err := c.RegisterNodes(&ua.RegisterNodesRequest{
        NodesToRegister: []*ua.NodeID{id},
    })
    if err != nil {
        log.Fatalf("RegisterNodes failed: %v", err)
    }

    for x := range time.Tick(time.Duration(1 * time.Second)) {
        req := &ua.ReadRequest{
            MaxAge: 2000,
            NodesToRead: []*ua.ReadValueID{
                &ua.ReadValueID{NodeID: regResp.RegisteredNodeIDs[0]},
            },
            TimestampsToReturn: ua.TimestampsToReturnBoth,
        }

        resp, err := c.Read(req)
        if err != nil {
            log.Fatalf("Read failed: %s", err)
        }
        if resp.Results[0].Status != ua.StatusOK {
            log.Fatalf("Status not OK: %v", resp.Results[0].Status)
        }
        log.Printf("RESULT: %+v = %+v\n", x.Format("2006-01-02 15:04:05"), resp.Results[0].Value.Value())
    }

    // _, err = c.UnregisterNodes(&ua.UnregisterNodesRequest{
    //  NodesToUnregister: []*ua.NodeID{id},
    // })
    // if err != nil {
    //  log.Fatalf("UnregisterNodes failed: %v", err)
    // }
}

After 10 minutes of OPC reading, I get the following error (after enabling the debug and disabling autoreconnect):

2021/04/09 16:24:09 RESULT: 2021-04-09 16:24:09 = 52973
debug: uasc 2/603: send *ua.ReadRequest with 96 bytes
debug: conn 2: recv MSGF with 82 bytes
debug: uasc 2/603: recv MSGF with 82 bytes
debug: uasc 2/603: recv *ua.ReadResponse
debug: sending *ua.ReadResponse to handler
2021/04/09 16:24:10 RESULT: 2021-04-09 16:24:10 = 52974
debug: uasc 2/604: send *ua.ReadRequest with 96 bytes
debug: uasc readChunk EOF
2021/04/09 16:24:11 Read failed: EOF

Same error when enabling autoreconnect

2021/04/09 16:43:31 RESULT: 2021-04-09 16:43:31 = 54130
debug: uasc 2/603: send *ua.ReadRequest with 96 bytes
debug: conn 2: recv MSGF with 82 bytes
debug: uasc 2/603: recv MSGF with 82 bytes
debug: uasc 2/603: recv *ua.ReadResponse
debug: sending *ua.ReadResponse to handler
2021/04/09 16:43:32 RESULT: 2021-04-09 16:43:32 = 54131
debug: uasc 2/604: send *ua.ReadRequest with 96 bytes
debug: uasc readChunk EOF
debug: client: monitor: disconnected
debug: client: monitor: auto-reconnecting
2021/04/09 16:43:33 Read failed: EOF

I don't know if it is an configuration error of my client of not...

Thanks.

m-manns commented 3 years ago

Hi, Turns out it was KEPServerEX 6 OPC Server that does not follow the standard and expects a security token renewal even if securityPolicyUri is none.

pedroliveira7 commented 3 years ago

Hi, Turns out it was KEPServerEX 6 OPC Server that does not follow the standard and expects a security token renewal even if securityPolicyUri is none.

I'm having the same problem here. Do you know if it is possible to change in KEPServer configuration?

magiconair commented 2 years ago

I think this might have been fixed by #466