Skip to content

Commit

Permalink
added response timeout
Browse files Browse the repository at this point in the history
1. changed examples to use this package
2. response timeout issue is recorded in original repo at dustin#43
  • Loading branch information
Sergei G committed Jun 6, 2017
1 parent 753e896 commit 4ac9ea7
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 13 deletions.
8 changes: 8 additions & 0 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,11 @@ some preliminary work on `SUBSCRIBE` support from

[shelby]: http://tools.ietf.org/html/draft-shelby-core-coap-01
[coap]: http://tools.ietf.org/html/rfc7252

## Differences from original `dustin/go-coap`

1. Added minor helper function to populate URI options.
2. Added configurable receive timeout in backgwards compatible way. Changed `ResponseTimeout` variable to `DefaultResponseTimeout` to emphasise its role change and to be able to track down its usage within package.
3. Example programs package references have been changed from `dustin/go-coap` to `Kulak/go-coap`.

Motivation for all this change: need to support existing application functionality.
20 changes: 13 additions & 7 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import (
)

const (
// ResponseTimeout is the amount of time to wait for a
// DefaultResponseTimeout is the amount of time to wait for a
// response.
ResponseTimeout = time.Second * 2
DefaultResponseTimeout = time.Second * 2
// ResponseRandomFactor is a multiplier for response backoff.
ResponseRandomFactor = 1.5
// MaxRetransmit is the maximum number of times a message will
Expand All @@ -18,12 +18,18 @@ const (

// Conn is a CoAP client connection.
type Conn struct {
conn *net.UDPConn
buf []byte
conn *net.UDPConn
buf []byte
responseTimeout time.Duration
}

// Dial connects a CoAP client.
func Dial(n, addr string) (*Conn, error) {
return DialWithTimeout(n, addr, DefaultResponseTimeout)
}

// DialWithTimeout provides control of response timeout.
func DialWithTimeout(n, addr string, responseTimeout time.Duration) (*Conn, error) {
uaddr, err := net.ResolveUDPAddr(n, addr)
if err != nil {
return nil, err
Expand All @@ -34,7 +40,7 @@ func Dial(n, addr string) (*Conn, error) {
return nil, err
}

return &Conn{s, make([]byte, maxPktLen)}, nil
return &Conn{s, make([]byte, maxPktLen), responseTimeout}, nil
}

// Send a message. Get a response if there is one.
Expand All @@ -48,7 +54,7 @@ func (c *Conn) Send(req Message) (*Message, error) {
return nil, nil
}

rv, err := Receive(c.conn, c.buf)
rv, err := Receive(c.conn, c.buf, c.responseTimeout)
if err != nil {
return nil, err
}
Expand All @@ -58,7 +64,7 @@ func (c *Conn) Send(req Message) (*Message, error) {

// Receive a message.
func (c *Conn) Receive() (*Message, error) {
rv, err := Receive(c.conn, c.buf)
rv, err := Receive(c.conn, c.buf, c.responseTimeout)
if err != nil {
return nil, err
}
Expand Down
51 changes: 51 additions & 0 deletions client_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package coap_test

import (
"testing"

coap "github.com/Kulak/go-coap"

"time"

"math"
)

func TestTimeoutDefaults(t *testing.T) {
testTimeout(t, coap.DefaultResponseTimeout)
}

func TestTimeout6sec(t *testing.T) {
testTimeout(t, 6*time.Second)
}

func testTimeout(t *testing.T, expectedTimeout time.Duration) {
// send to IP address without CoAP EP
req := coap.Message{
Type: coap.Confirmable,
Code: coap.GET,
MessageID: 12345,
Payload: []byte("undeliverable"),
}
req.SetOption(coap.MaxAge, 3)
req.SetPathString("/some/path")

c, err := coap.DialWithTimeout("udp", "192.168.254.254:5683", expectedTimeout)
if err != nil {
t.Errorf("Error dialing: %v", err)
return
}

start := time.Now()
_, err = c.Send(req)
end := time.Now()
timeout := end.Sub(start)
if err != nil {
// that's not going to get printed unless test fails
t.Logf("Error sending request: %v", err)
if math.Abs(timeout.Seconds()-expectedTimeout.Seconds()) > 0.1 {
t.Fatalf("Expected timeout %v, got %v", expectedTimeout, timeout)
}
return
}
t.Fatal("Response shall timeout.")
}
2 changes: 1 addition & 1 deletion example/client/goap_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package main
import (
"log"

"github.com/dustin/go-coap"
"github.com/Kulak/go-coap"
)

func main() {
Expand Down
2 changes: 1 addition & 1 deletion example/obsclient/obsclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package main
import (
"log"

"github.com/dustin/go-coap"
"github.com/Kulak/go-coap"
)

func main() {
Expand Down
2 changes: 1 addition & 1 deletion example/obsserver/obsserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"net"
"time"

"github.com/dustin/go-coap"
"github.com/Kulak/go-coap"
)

func periodicTransmitter(l *net.UDPConn, a *net.UDPAddr, m *coap.Message) {
Expand Down
2 changes: 1 addition & 1 deletion example/server/coap_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"log"
"net"

"github.com/dustin/go-coap"
"github.com/Kulak/go-coap"
)

func main() {
Expand Down
4 changes: 2 additions & 2 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ func Transmit(l *net.UDPConn, a *net.UDPAddr, m Message) error {
}

// Receive a message.
func Receive(l *net.UDPConn, buf []byte) (Message, error) {
l.SetReadDeadline(time.Now().Add(ResponseTimeout))
func Receive(l *net.UDPConn, buf []byte, responseTimeout time.Duration) (Message, error) {
l.SetReadDeadline(time.Now().Add(responseTimeout))

nr, _, err := l.ReadFromUDP(buf)
if err != nil {
Expand Down

0 comments on commit 4ac9ea7

Please sign in to comment.