From 85a9d33ebe9e70347cfff980d0c6fcf0cd40c5a1 Mon Sep 17 00:00:00 2001 From: Diogo Silva Date: Sat, 19 May 2018 00:38:40 -0300 Subject: [PATCH 1/3] Can configure differente linestop, and can close server --- tcp_server.go | 24 +++++++++++++++---- tcp_server_test.go | 59 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 4 deletions(-) diff --git a/tcp_server.go b/tcp_server.go index 588931e..3416162 100644 --- a/tcp_server.go +++ b/tcp_server.go @@ -18,19 +18,21 @@ type server struct { onNewClientCallback func(c *Client) onClientConnectionClosed func(c *Client, err error) onNewMessage func(c *Client, message string) + close chan bool + MessageTerminator rune } // Read client data from channel func (c *Client) listen() { reader := bufio.NewReader(c.conn) for { - message, err := reader.ReadString('\n') + message, err := reader.ReadString(byte(c.Server.MessageTerminator)) if err != nil { c.conn.Close() c.Server.onClientConnectionClosed(c, err) return } - c.Server.onNewMessage(c, message) + go c.Server.onNewMessage(c, message) } } @@ -77,8 +79,16 @@ func (s *server) Listen() { } defer listener.Close() + go func() { + <-s.close + listener.Close() + }() + for { - conn, _ := listener.Accept() + conn, lErr := listener.Accept() + if lErr != nil { + return + } client := &Client{ conn: conn, Server: s, @@ -88,11 +98,17 @@ func (s *server) Listen() { } } +func (s *server) Close() { + s.close <- true +} + // Creates new tcp server instance func New(address string) *server { log.Println("Creating server with address", address) server := &server{ - address: address, + address: address, + close: make(chan bool, 1), + MessageTerminator: '\n', } server.OnNewClient(func(c *Client) {}) diff --git a/tcp_server_test.go b/tcp_server_test.go index 6f84ab1..30108ad 100644 --- a/tcp_server_test.go +++ b/tcp_server_test.go @@ -40,11 +40,16 @@ func Test_accepting_new_client_callback(t *testing.T) { t.Fatal("Failed to connect to test server") } conn.Write([]byte("Test message\n")) + + time.Sleep(100 * time.Millisecond) + conn.Close() // Wait for server time.Sleep(10 * time.Millisecond) + server.Close() + Convey("Messages should be equal", t, func() { So(messageText, ShouldEqual, "Test message\n") }) @@ -58,3 +63,57 @@ func Test_accepting_new_client_callback(t *testing.T) { So(connectinClosed, ShouldEqual, true) }) } + +func Test_accepting_new_client_callback_different_terminator(t *testing.T) { + server := buildTestServer() + + var messageReceived bool + var messageText string + var newClient bool + var connectinClosed bool + + server.OnNewClient(func(c *Client) { + newClient = true + }) + server.OnNewMessage(func(c *Client, message string) { + messageReceived = true + messageText = message + }) + server.OnClientConnectionClosed(func(c *Client, err error) { + connectinClosed = true + }) + server.MessageTerminator = '\u0000' + go server.Listen() + + // Wait for server + // If test fails - increase this value + time.Sleep(10 * time.Millisecond) + + conn, err := net.Dial("tcp", "localhost:9999") + if err != nil { + t.Fatal("Failed to connect to test server") + } + conn.Write([]byte("Test message\u0000")) + + time.Sleep(100 * time.Millisecond) + + conn.Close() + + // Wait for server + time.Sleep(10 * time.Millisecond) + + server.Close() + + Convey("Messages should be equal", t, func() { + So(messageText, ShouldEqual, "Test message\u0000") + }) + Convey("It should receive new client callback", t, func() { + So(newClient, ShouldEqual, true) + }) + Convey("It should receive message callback", t, func() { + So(messageReceived, ShouldEqual, true) + }) + Convey("It should receive connection closed callback", t, func() { + So(connectinClosed, ShouldEqual, true) + }) +} From 98c30d0b63025a087b10c5bfeb7e64a70e335986 Mon Sep 17 00:00:00 2001 From: Diogo Silva Date: Sun, 20 May 2018 11:55:45 -0300 Subject: [PATCH 2/3] Document optional message terminator parameter --- readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/readme.md b/readme.md index 4af6554..d8c4cfc 100644 --- a/readme.md +++ b/readme.md @@ -20,6 +20,7 @@ import "github.com/firstrow/tcp_server" func main() { server := tcp_server.New("localhost:9999") + server.MessageTerminator='\n' // Optional end of message byte, default to newline. server.OnNewClient(func(c *tcp_server.Client) { // new client connected From 058b6d2612e8cfc9906014039708ec8bde600375 Mon Sep 17 00:00:00 2001 From: Diogo Silva Date: Sun, 20 May 2018 11:58:40 -0300 Subject: [PATCH 3/3] No need to add this goroutine on message receiver --- tcp_server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tcp_server.go b/tcp_server.go index 3416162..1a1127d 100644 --- a/tcp_server.go +++ b/tcp_server.go @@ -32,7 +32,7 @@ func (c *Client) listen() { c.Server.onClientConnectionClosed(c, err) return } - go c.Server.onNewMessage(c, message) + c.Server.onNewMessage(c, message) } }