From 318fde814ed7dd8fd71bff2b52f841094ef1103d Mon Sep 17 00:00:00 2001 From: luoyumin Date: Tue, 22 Aug 2023 17:46:08 +0800 Subject: [PATCH] command linger support --- command/linger.go | 9 +++++++++ command/linger_test.go | 2 +- connection.go | 17 +++++++++++++++-- go.sum | 5 +++++ outbound.go | 6 +++++- 5 files changed, 35 insertions(+), 4 deletions(-) diff --git a/command/linger.go b/command/linger.go index 07cbf88..c6ae11e 100644 --- a/command/linger.go +++ b/command/linger.go @@ -10,12 +10,21 @@ */ package command +import ( + "fmt" + "time" +) + type Linger struct { Enabled bool + Seconds time.Duration } func (l Linger) BuildMessage() string { if l.Enabled { + if l.Seconds > 0 { + return fmt.Sprintf("linger %d", l.Seconds) + } return "linger" } return "nolinger" diff --git a/command/linger_test.go b/command/linger_test.go index 8dbd8de..3cd46e2 100644 --- a/command/linger_test.go +++ b/command/linger_test.go @@ -20,5 +20,5 @@ func TestNoLinger_BuildMessage(t *testing.T) { } func TestLinger_BuildMessage(t *testing.T) { - assert.Equal(t, "linger", Linger{true}.BuildMessage()) + assert.Equal(t, "linger", Linger{Enabled: true}.BuildMessage()) } diff --git a/connection.go b/connection.go index 46d0072..23881d2 100644 --- a/connection.go +++ b/connection.go @@ -37,6 +37,7 @@ type Conn struct { logger Logger exitTimeout time.Duration closeOnce sync.Once + closeDelay time.Duration } // Options - Generic options for an ESL connection, either inbound or outbound @@ -116,14 +117,26 @@ func (c *Conn) RemoveEventListener(channelUUID string, id string) { } // SendCommand - Sends the specified ESL command to FreeSWITCH with the provided context. Returns the response data and any errors encountered. -func (c *Conn) SendCommand(ctx context.Context, command command.Command) (*RawResponse, error) { +func (c *Conn) SendCommand(ctx context.Context, cmd command.Command) (*RawResponse, error) { c.writeLock.Lock() defer c.writeLock.Unlock() + if linger, ok := cmd.(command.Linger); ok { + if linger.Enabled { + if linger.Seconds > 0 { + c.closeDelay = linger.Seconds + } else { + c.closeDelay = -1 + } + } else { + c.closeDelay = 0 + } + } + if deadline, ok := ctx.Deadline(); ok { _ = c.conn.SetWriteDeadline(deadline) } - _, err := c.conn.Write([]byte(command.BuildMessage() + EndOfMessage)) + _, err := c.conn.Write([]byte(cmd.BuildMessage() + EndOfMessage)) if err != nil { return nil, err } diff --git a/go.sum b/go.sum index facefbb..9cd1813 100644 --- a/go.sum +++ b/go.sum @@ -1,13 +1,18 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/percipia/eslgo v1.4.1 h1:FpYtzCwrzQuSgB24NyuQC5ibMSHVqCdzaieAcDTltYw= +github.com/percipia/eslgo v1.4.1/go.mod h1:Icri58AZUSyAo+ObKUXhVwSC2aUPZaLzJYO/vKE3kew= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/outbound.go b/outbound.go index 3f0f222..63c6e62 100644 --- a/outbound.go +++ b/outbound.go @@ -96,7 +96,11 @@ func (c *Conn) dummyLoop() { select { case <-c.responseChannels[TypeDisconnect]: c.logger.Info("Disconnect outbound connection", c.conn.RemoteAddr()) - c.Close() + if c.closeDelay >= 0 { + time.AfterFunc(c.closeDelay*time.Second, func() { + c.Close() + }) + } case <-c.responseChannels[TypeAuthRequest]: c.logger.Debug("Ignoring auth request on outbound connection", c.conn.RemoteAddr()) case <-c.runningContext.Done():