client.go 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. package server
  2. import (
  3. "github.com/gogf/gf/net/gtcp"
  4. "github.com/gogf/gf/os/glog"
  5. "io"
  6. "net"
  7. "strings"
  8. "syscall"
  9. "time"
  10. )
  11. type Client struct {
  12. Id string
  13. srv *Server
  14. conn *gtcp.Conn
  15. sendChan chan []byte
  16. closeChan chan struct{}
  17. closeHandler func(id string, c *Client)
  18. nc *gtcp.Conn
  19. lastHeartBeat time.Time
  20. done chan struct{}
  21. gatewayId uint16
  22. }
  23. func (c *Client) ReadLoop() {
  24. defer c.srv.grWG.Done()
  25. for {
  26. buf, err := c.nc.RecvTil([]byte{0x16})
  27. if err != nil {
  28. c.readError(err)
  29. return
  30. }
  31. if len(buf) > 0 {
  32. err = c.srv.message.Decode(buf)
  33. if err != nil {
  34. glog.Errorf("解析报文失败:%s", err.Error())
  35. }
  36. }
  37. }
  38. }
  39. func (c *Client) SetId(id string) {
  40. c.Id = id
  41. }
  42. func (c *Client) readError(err error) {
  43. defer c.closeConnection()
  44. if err == io.EOF || isErrConnReset(err) {
  45. return
  46. }
  47. glog.Errorf("读取数据发生错误:%s", err.Error())
  48. }
  49. func (c *Client) closeConnection() {
  50. c.nc.Close()
  51. c.nc = nil
  52. close(c.done)
  53. if c.closeHandler != nil {
  54. c.closeHandler(c.Id, c)
  55. }
  56. }
  57. // isErrConnReset read: connection reset by peer
  58. func isErrConnReset(err error) bool {
  59. if ne, ok := err.(*net.OpError); ok {
  60. return strings.Contains(ne.Err.Error(), syscall.ECONNRESET.Error())
  61. }
  62. return false
  63. }
  64. func (c *Client) send(buf []byte) error {
  65. if c.nc == nil {
  66. return nil
  67. }
  68. err := c.nc.Send(buf)
  69. if err != nil {
  70. glog.Error(err)
  71. c.closeConnection()
  72. return err
  73. }
  74. return nil
  75. }