Compare commits
3 Commits
ce537e1373
...
8c33fd2a89
| Author | SHA1 | Date | |
|---|---|---|---|
| 8c33fd2a89 | |||
| ebdbc92693 | |||
| 7b1533b3e6 |
14
client.go
14
client.go
@@ -17,10 +17,11 @@ type Mbclient struct {
|
|||||||
conn net.Conn
|
conn net.Conn
|
||||||
t *time.Timer
|
t *time.Timer
|
||||||
keepAliveDuration time.Duration
|
keepAliveDuration time.Duration
|
||||||
|
timeOut time.Duration
|
||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(Address string, Unit uint8, KeepAlive time.Duration) (*Mbclient, error) {
|
func New(Address string, Unit uint8, KeepAlive, TimeOut time.Duration) (*Mbclient, error) {
|
||||||
|
|
||||||
c := new(Mbclient)
|
c := new(Mbclient)
|
||||||
c.address = Address
|
c.address = Address
|
||||||
@@ -28,6 +29,7 @@ func New(Address string, Unit uint8, KeepAlive time.Duration) (*Mbclient, error)
|
|||||||
c.t = time.NewTimer(0)
|
c.t = time.NewTimer(0)
|
||||||
<-c.t.C
|
<-c.t.C
|
||||||
c.keepAliveDuration = KeepAlive
|
c.keepAliveDuration = KeepAlive
|
||||||
|
c.timeOut = TimeOut
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,7 +56,7 @@ func (m *Mbclient) ReadRegisters(first uint16, numRegs uint16) ([]uint16, error)
|
|||||||
// Wait for closer to exit to mitigate race condiion
|
// Wait for closer to exit to mitigate race condiion
|
||||||
// between closer routine and this code path
|
// between closer routine and this code path
|
||||||
m.wg.Wait()
|
m.wg.Wait()
|
||||||
m.conn, err = net.DialTimeout("tcp", m.address, 5*time.Second)
|
m.conn, err = net.DialTimeout("tcp", m.address, m.timeOut)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -76,6 +78,7 @@ func (m *Mbclient) ReadRegisters(first uint16, numRegs uint16) ([]uint16, error)
|
|||||||
binary.BigEndian.PutUint16(req[8:10], first-1)
|
binary.BigEndian.PutUint16(req[8:10], first-1)
|
||||||
binary.BigEndian.PutUint16(req[10:12], numRegs)
|
binary.BigEndian.PutUint16(req[10:12], numRegs)
|
||||||
m.conn.SetDeadline(time.Now().Add(5 * time.Second))
|
m.conn.SetDeadline(time.Now().Add(5 * time.Second))
|
||||||
|
|
||||||
byteswritten, err := m.conn.Write(req)
|
byteswritten, err := m.conn.Write(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
m.closeConn()
|
m.closeConn()
|
||||||
@@ -85,7 +88,7 @@ func (m *Mbclient) ReadRegisters(first uint16, numRegs uint16) ([]uint16, error)
|
|||||||
m.closeConn()
|
m.closeConn()
|
||||||
return nil, fmt.Errorf("failed to send request")
|
return nil, fmt.Errorf("failed to send request")
|
||||||
}
|
}
|
||||||
m.conn.SetDeadline(time.Now().Add(5 * time.Second))
|
m.conn.SetDeadline(time.Now().Add(m.timeOut))
|
||||||
_, err = io.ReadFull(m.conn, m.header[:])
|
_, err = io.ReadFull(m.conn, m.header[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
m.closeConn()
|
m.closeConn()
|
||||||
@@ -95,10 +98,11 @@ func (m *Mbclient) ReadRegisters(first uint16, numRegs uint16) ([]uint16, error)
|
|||||||
expectedDataLength := responseHeader.length - 1
|
expectedDataLength := responseHeader.length - 1
|
||||||
|
|
||||||
if m.transactionCounter != responseHeader.transactionID {
|
if m.transactionCounter != responseHeader.transactionID {
|
||||||
m.t.Reset(0)
|
m.closeConn()
|
||||||
return nil, fmt.Errorf("modbus transaction mismatch %v != %v", m.transactionCounter, responseHeader.transactionID)
|
return nil, fmt.Errorf("modbus transaction mismatch %v != %v", m.transactionCounter, responseHeader.transactionID)
|
||||||
}
|
}
|
||||||
response := make([]byte, expectedDataLength)
|
response := make([]byte, expectedDataLength)
|
||||||
|
m.conn.SetDeadline(time.Now().Add(m.timeOut))
|
||||||
bytesRead, err := io.ReadFull(m.conn, response)
|
bytesRead, err := io.ReadFull(m.conn, response)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
m.closeConn()
|
m.closeConn()
|
||||||
@@ -112,7 +116,7 @@ func (m *Mbclient) ReadRegisters(first uint16, numRegs uint16) ([]uint16, error)
|
|||||||
err = mbpayload.unMarshal(response)
|
err = mbpayload.unMarshal(response)
|
||||||
if mbpayload.functionCode != 3 {
|
if mbpayload.functionCode != 3 {
|
||||||
m.t.Reset(m.keepAliveDuration)
|
m.t.Reset(m.keepAliveDuration)
|
||||||
return nil, fmt.Errorf("modbus exception %v req: %v", mbpayload.functionCode&0x7F, req)
|
return nil, fmt.Errorf("modbus exception %v req: %x", mbpayload.functionCode&0x7F, req)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
m.t.Reset(m.keepAliveDuration)
|
m.t.Reset(m.keepAliveDuration)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestReadOneRegisterKeepAlive(t *testing.T) {
|
func TestReadOneRegisterKeepAlive(t *testing.T) {
|
||||||
c, err := New("IAM_248000012514.solver.nu:502", 1, 100*time.Millisecond)
|
c, err := New("IAM_248000012514.solver.nu:502", 1, 100*time.Millisecond, 5*time.Second)
|
||||||
t.Log("Connect")
|
t.Log("Connect")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
for n := 0; n < 5; n++ {
|
for n := 0; n < 5; n++ {
|
||||||
@@ -36,7 +36,7 @@ func TestReadOneRegisterKeepAlive(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestReadOneRegisterShortKeepAlive(t *testing.T) {
|
func TestReadOneRegisterShortKeepAlive(t *testing.T) {
|
||||||
c, err := New("IAM_248000012514.solver.nu:502", 1, 10*time.Nanosecond)
|
c, err := New("IAM_248000012514.solver.nu:502", 1, 10*time.Nanosecond, 5*time.Second)
|
||||||
t.Log("Connect")
|
t.Log("Connect")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
for n := 0; n < 5; n++ {
|
for n := 0; n < 5; n++ {
|
||||||
@@ -68,7 +68,7 @@ func TestReadOneRegisterShortKeepAlive(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestReadALot(t *testing.T) {
|
func TestReadALot(t *testing.T) {
|
||||||
c, err := New("IAM_248000012514.solver.nu:502", 1, 100*time.Millisecond)
|
c, err := New("IAM_248000012514.solver.nu:502", 1, 100*time.Millisecond, 5*time.Second)
|
||||||
t.Log("Connect")
|
t.Log("Connect")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
for n := 0; n < 500; n++ {
|
for n := 0; n < 500; n++ {
|
||||||
|
|||||||
Reference in New Issue
Block a user