Skip to content

Commit

Permalink
Merge pull request #9 from hongjinlin/master
Browse files Browse the repository at this point in the history
support goroutine connect to multi devices
  • Loading branch information
robinson authored May 20, 2019
2 parents db01b78 + 80a9124 commit a789e2a
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 8 deletions.
12 changes: 8 additions & 4 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ const (
)

//PDULength variable to store pdu length after connect
var PDULength int //global variable pdulength
//var tt, _ := mb.transporter.(*tcpTransporter)tt, _ := mb.transporter.(*tcpTransporter) int //global variable pdulength

// ClientHandler is the interface that groups the Packager and Transporter methods.
// CliePDULengthntHandler is the interface that groups the Packager and Transporter methods.
type ClientHandler interface {
Packager
Transporter
Expand Down Expand Up @@ -184,7 +184,10 @@ func (mb *client) readArea(area int, dbNumber int, start int, amount int, wordLe
wordLen = s7wlbyte
}
}
maxElements = (PDULength - 18) / wordSize // 18 = Reply telegram header //lth note here

tt, _ := interface{}(mb.transporter).(*TCPClientHandler)

maxElements = (tt.PDULength - 18) / wordSize // 18 = Reply telegram header //lth note here
totElements = amount
for totElements > 0 && err == nil {
numElements = totElements
Expand Down Expand Up @@ -278,7 +281,8 @@ func (mb *client) writeArea(area int, dbnumber int, start int, amount int, wordl
wordlen = s7wlbyte
}
}
maxElements = (PDULength - 35) / wordSize // 35 = Reply telegram header
tt, _ := interface{}(mb.transporter).(*TCPClientHandler)
maxElements = (tt.PDULength - 35) / wordSize // 35 = Reply telegram header
totElements = amount
for totElements > 0 && err == nil {
numElements = totElements
Expand Down
6 changes: 4 additions & 2 deletions multi.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,9 @@ func (mb *client) AGWriteMulti(dataItems []S7DataItem, itemsCount int) (err erro
offset = offset + itemDataSize + 4
dataLength = dataLength + itemDataSize + 4
}
tt, _ := interface{}(mb.transporter).(*TCPClientHandler)
//Checks the size
if offset > PDULength {
if offset > tt.PDULength {
err = fmt.Errorf(ErrorText(errCliSizeOverPDU))
return
}
Expand Down Expand Up @@ -156,7 +157,8 @@ func (mb *client) AGReadMulti(dataItems []S7DataItem, itemsCount int) (err error
s7Multi = append(s7Multi, s7Item...)
offset += len(s7Item)
}
if offset > PDULength {
tt, _ := interface{}(mb.transporter).(*TCPClientHandler)
if offset > tt.PDULength {
err = fmt.Errorf(ErrorText(errCliSizeOverPDU))
return
}
Expand Down
6 changes: 4 additions & 2 deletions tcpclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ type tcpTransporter struct {
remoteTSAPHigh, remoteTSAPLow byte
ConnectionType int
LastPDUType byte

PDULength int
}

func (mb *tcpTransporter) setConnectionParameters(address string, localTSAP uint16, remoteTSAP uint16) {
Expand Down Expand Up @@ -221,8 +223,8 @@ func (mb *tcpTransporter) negotiatePduLength() error {
length := len(response)
if length == 27 && response[17] == 0 && response[18] == 0 { // 20 = size of Negotiate Answer
// Get PDU Size Negotiated
PDULength = int(binary.BigEndian.Uint16(response[25:]))
if PDULength <= 0 {
mb.PDULength = int(binary.BigEndian.Uint16(response[25:]))
if mb.PDULength <= 0 {
err = fmt.Errorf(ErrorText(errCliNegotiatingPDU))
}
} else {
Expand Down
63 changes: 63 additions & 0 deletions test/tcpclient_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
"time"

"../../gos7"
"sync"
"fmt"
)

const (
Expand All @@ -28,3 +30,64 @@ func TestTCPClient(t *testing.T) {
client := gos7.NewClient(handler)
ClientTestAll(t, client)
}

func TestMultiTCPClient(t *testing.T) {
var handlers sync.Map
var clients sync.Map

tcpDevices := make([]map[string]string, 2)
tcpDevices[0] = make(map[string]string, 1)
tcpDevices[1] = make(map[string]string, 1)
tcpDevices[0]["tcpDevice"] = "192.168.10.19:102"
tcpDevices[1]["tcpDevice"] = "192.168.10.10:102"

c := make(chan int)

for k := range tcpDevices {
go func(device map[string]string) {
handler := gos7.NewTCPClientHandler(tcpDevice, rack, slot)
handler.Timeout = 200 * time.Second
handler.IdleTimeout = 200 * time.Second
handler.Logger = log.New(os.Stdout, "tcp: ", log.LstdFlags)
handler.Address = device["tcpDevice"]
handler.Connect()
handlers.Store(device["tcpDevice"], handler)

client := gos7.NewClient(handler)
clients.Store(device["tcpDevice"], client)

c <- 1
}(tcpDevices[k])
}

var cS []int

for n := range c {
cS = append(cS, n)
if len(cS) == len(tcpDevices) {
close(c)
break
}
}

cli, exist := clients.Load("192.168.10.10:102")
client, ok := cli.(gos7.Client)
if exist && ok {
buf := make([]byte, 255)
client.AGReadDB(200, 34, 4, buf)
var s7 gos7.Helper
var result float32
s7.GetValueAt(buf, 0, &result)
fmt.Printf("%v\n", result)
}

defer func() {
handlers.Range(func(key, value interface{}) bool {
h, _ := handlers.Load(key)
if hh, ok := h.(*gos7.TCPClientHandler); ok {
hh.Close()
}
return true
})
}()
}

0 comments on commit a789e2a

Please sign in to comment.