| | |
| | | defer cm.mu.Unlock() |
| | | |
| | | conn, ok := cm.connections[address] |
| | | return conn, ok |
| | | if !ok { |
| | | return nil, false |
| | | } |
| | | connOK, err := cm.CheckConnect(conn, time.Second*1) |
| | | if err != nil { |
| | | logx.Errorf("ping plc err:%v", err.Error()) |
| | | return nil, false |
| | | } |
| | | if connOK { |
| | | return conn, ok |
| | | } |
| | | return nil, false |
| | | } |
| | | |
| | | var connectionManager = newPlcConnectionManager() |
| | |
| | | |
| | | cm.connections[address] = connection |
| | | } |
| | | |
| | | func (cm *ConnectionManager) CheckConnect(conn plc4go.PlcConnection, timeout time.Duration) (bool, error) { |
| | | pingCh := conn.Ping() |
| | | timer := time.NewTimer(timeout) |
| | | |
| | | select { |
| | | case err := <-pingCh: |
| | | if err == nil { |
| | | return true, nil |
| | | } |
| | | return false, err.GetErr() |
| | | case <-timer.C: |
| | | return false, fmt.Errorf("connection timed out after %s", timeout) |
| | | } |
| | | } |
| | | |
| | | func GetModbusConnection(ipAddr string) (plc4go.PlcConnection, error) { |
| | | if conn, ok := connectionManager.GetConnection(ipAddr); ok { |
| | | if conn.IsConnected() { |
| | | return conn, nil |
| | | } |
| | | return conn, nil |
| | | } |
| | | // 创建一个上下文,并设置 3 秒超时 |
| | | ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) |
| | | ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) |
| | | defer cancel() |
| | | conn, err := newGetModbusConnection(ctx, ipAddr) |
| | | if err != nil { |