Go TCP library: https://github.com/chenjunpc2008/go-tcp
Go TCP client
accepting connection:
+------------+ +-----------------------------+ +----------------+
| | | | | |
| | | | | |
| tcp client |--->| establish remote connection |--->| create session |
| | | | | |
| | | | | |
+------------+ +-----------------------------+ +----------------+
in session:
+-----------------+ +----------------------+ +-------------------------+ +------------+
| | | Handler.Depack() | | | | |
| read connection |--->| unpack packet payload|--->| Handler.OnReceiveData() |--->| user logic |
| | | | | | | |
+-----------------+ +----------------------+ +-------------------------+ +------------+
+------------+ +-----------------------+ +---------------------+
| | | | | Handler.Pack() |
| user logic |--->| client.SendToServer() |--->| pack packet payload |
| | | | | |
+------------+ +-----------------------+ +---------------------+
|
+------------------------+ +------------------+ |
| | | | |
| Handler.OnSendedData() |<---| write connection |<--------|
| | | |
+------------------------+ +------------------+
Go TCP server
accepting connection:
+------------+ +-------------------+ +----------------+
| | | | | |
| | | | | |
| tcp server |--->| accept connection |--->| create session |
| | | | | |
| | | | | |
+------------+ +-------------------+ +----------------+
in session:
+-----------------+ +----------------------+ +-------------------------+ +------------+
| | | Handler.Depack() | | | | |
| read connection |--->| unpack packet payload|--->| Handler.OnReceiveData() |--->| user logic |
| | | | | | | |
+-----------------+ +----------------------+ +-------------------------+ +------------+
+------------+ +--------------------------+ +---------------------+
| | | | | Handler.Pack() |
| user logic |--->| tcpserver.SendToClient() |--->| pack packet payload |
| | | | | |
+------------+ +--------------------------+ +---------------------+
|
+------------------------+ +------------------+ |
| | | | |
| Handler.OnSendedData() |<---| write connection |<--------|
| | | |
+------------------------+ +------------------+
Use example/pressure-server
and example/pressure-client
, 1000 concurrent clients
, 4 KB payload
get a result of 100000 q/s
.
for example: example/pressure-server
- Create your own tcp protocol package pack/depack(or Marshal/Unmarshal) method for tcp transport
- Create a struct for server event call back, and put your own tcp protocol package pack/depack method in Pack()/Depack()
type appHandler struct { } // pack message into the []byte to be written func (hdl *appHandler) Pack(msg interface{}) ([]byte, error) { const ftag = "appHandler.Pack()" // TODO: Do your message pack here -- msg to []byte sends to client var ( ok bool buff []byte sErr string ) buff, ok, sErr = echoprotocol.Pack(msg, 0) if ok { return buff, nil } return buff, fmt.Errorf("echoprotocol.Pack() error %s", sErr) } // depack the message packages from read []byte func (hdl *appHandler) Depack(rawData []byte) ([]byte, []interface{}) { const ftag = "appHandler.Depack()" // TODO: Do your message depack here -- []byte to msg receive from client var ( dataRemain []byte pakgs []interface{} ok bool errMsg string ) dataRemain, pakgs, ok, errMsg = echoprotocol.Depack(rawData) if !ok { // depack have err log.Println(ftag, errMsg) } return dataRemain, pakgs } // new connections event func (hdl *appHandler) OnNewConnection(serverIP string, serverPort uint16) { const ftag = "appHandler.OnNewConnection()" log.Println(ftag, serverIP, serverPort) } // disconnected event func (hdl *appHandler) OnDisconnected(serverIP string, serverPort uint16) { const ftag = "appHandler.OnDisconnected()" log.Println(ftag, serverIP, serverPort) } // receive data event func (hdl *appHandler) OnReceiveData(serverIP string, serverPort uint16, pPacks []interface{}) { const ftag = "appHandler.OnReceiveData()" // log.Println(ftag, serverIP, serverPort) } // data already sended event func (hdl *appHandler) OnSendedData(serverIP string, serverPort uint16, msg interface{}, bysSended []byte, length int) { const ftag = "appHandler.OnSendedData()" // log.Println(ftag, serverIP, serverPort) } // event func (hdl *appHandler) OnEvent(msg string) { const ftag = "appHandler.OnEvent()" log.Println(ftag, msg) } // error func (hdl *appHandler) OnError(msg string, err error) { const ftag = "appHandler.OnError()" log.Println(ftag, msg, err) } // error func (hdl *appHandler) OnErrorStr(msg string) { const ftag = "appHandler.OnErrorStr()" log.Println(ftag, msg) }
- Use the server and go
appHdl := &appHandler{} cnf := tcpserver.DefaultConfig() gServer = tcpserver.NewTCPSvr(appHdl, cnf) err = gServer.StartServer(uint16(gPort)) if nil != err { log.Panicln("StartServer failed", err) }
for example: example/pressure-client
- Create your own tcp protocol package pack/depack(or Marshal/Unmarshal) method for tcp transport
- Create a struct for server event call back, and put your own tcp protocol package pack/depack method in Pack()/Depack()
type appHandler struct { } // pack message into the []byte to be written func (hdl *appHandler) Pack(msg interface{}) ([]byte, error) { const ftag = "appHandler.Pack()" // TODO: Do your message pack here -- msg to []byte sends to client var ( ok bool buff []byte sErr string ) buff, ok, sErr = echoprotocol.Pack(msg, 0) if ok { return buff, nil } return buff, fmt.Errorf("echoprotocol.Pack() error %s", sErr) } // depack the message packages from read []byte func (hdl *appHandler) Depack(rawData []byte) ([]byte, []interface{}) { const ftag = "appHandler.Depack()" // TODO: Do your message depack here -- []byte to msg receive from client var ( dataRemain []byte pakgs []interface{} ok bool errMsg string ) dataRemain, pakgs, ok, errMsg = echoprotocol.Depack(rawData) if !ok { // depack have err log.Println(ftag, errMsg) } return dataRemain, pakgs } // new connections event func (hdl *appHandler) OnNewConnection(serverIP string, serverPort uint16) { const ftag = "appHandler.OnNewConnection()" log.Println(ftag, serverIP, serverPort) } // disconnected event func (hdl *appHandler) OnDisconnected(serverIP string, serverPort uint16) { const ftag = "appHandler.OnDisconnected()" log.Println(ftag, serverIP, serverPort) } // receive data event func (hdl *appHandler) OnReceiveData(serverIP string, serverPort uint16, pPacks []interface{}) { const ftag = "appHandler.OnReceiveData()" // log.Println(ftag, serverIP, serverPort) // TODO: do your receive process here } // data already sended event func (hdl *appHandler) OnSendedData(serverIP string, serverPort uint16, msg interface{}, bysSended []byte, length int) { const ftag = "appHandler.OnSendedData()" // log.Println(ftag, serverIP, serverPort) } // event func (hdl *appHandler) OnEvent(msg string) { const ftag = "appHandler.OnEvent()" log.Println(ftag, msg) } // error func (hdl *appHandler) OnError(msg string, err error) { const ftag = "appHandler.OnError()" log.Println(ftag, msg, err) } // error func (hdl *appHandler) OnErrorStr(msg string) { const ftag = "appHandler.OnErrorStr()" log.Println(ftag, msg) }
- Use the client and go
appHdl := &appHandler{} cnf := tcpclient.DefaultConfig() client := tcpclient.New(appHdl, cnf) cnct_to := 3 * time.Second err = client.ConnectToServer_Timeout(serverIP, serverPort, cnct_to) if nil != err { log.Panicln("ConnectToServer_Timeout failed", err) } // send busy, err = client.SendToServer(msg) if nil != err { log.Println("SendToServer failed", err) break } if busy { log.Println("SendToServer failed because busy") break }