-
Notifications
You must be signed in to change notification settings - Fork 39
Wait for correct response id #77
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,6 +8,7 @@ import ( | |
| "context" | ||
| "encoding/binary" | ||
| "fmt" | ||
| "time" | ||
| ) | ||
|
|
||
| // Logger is the interface to the required logging functions | ||
|
|
@@ -632,12 +633,24 @@ func (mb *client) send(ctx context.Context, request *ProtocolDataUnit) (response | |
| if err != nil { | ||
| return | ||
| } | ||
| aduResponse, err := mb.transporter.Send(ctx, aduRequest) | ||
| if err != nil { | ||
| return | ||
| } | ||
| if err = mb.packager.Verify(aduRequest, aduResponse); err != nil { | ||
| return | ||
|
|
||
| // Wait for correct response ID before throwing error. | ||
| var aduResponse []byte | ||
| maxTime := time.Now().Add(tcpTimeout) | ||
| for { | ||
| aduResponse, err = mb.transporter.Send(ctx, aduRequest) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Calling The Modbus Serial Line spec defines the correct master behaviour explicitly:
So the master must keep waiting, not re-send the request. The retry logic belongs inside the transport's read path. For RTU, |
||
| if err != nil { | ||
| return | ||
| } | ||
| err = mb.packager.Verify(aduRequest, aduResponse) | ||
| if err == nil { | ||
| break | ||
| } | ||
| if time.Now().After(maxTime) { | ||
| err = fmt.Errorf("modbus: response timeout") | ||
| return | ||
| } | ||
|
Comment on lines
+649
to
+652
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The loop never checks |
||
| // Else try again until timeout. | ||
| } | ||
| response, err = mb.packager.Decode(aduResponse) | ||
| if err != nil { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tcpTimeoutis a constant defined intcpclient.goand is meaningless here.client.go's send method is shared by all transports (TCP, RTU, ASCII). For an RTU serial client the timeout is serialTimeout. There is no single correct timeout constant to use here; this approach needs to be rethought.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see your point. Unfortunately it is unlikely I'll have the time for this in the near future.