client.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. package polling
  2. import (
  3. "bytes"
  4. "fmt"
  5. "github.com/googollee/go-engine.io/message"
  6. "io"
  7. "io/ioutil"
  8. "net/http"
  9. "net/url"
  10. "time"
  11. "github.com/googollee/go-engine.io/parser"
  12. "github.com/googollee/go-engine.io/transport"
  13. )
  14. type client struct {
  15. req http.Request
  16. url url.URL
  17. seq uint
  18. getResp *http.Response
  19. postResp *http.Response
  20. resp *http.Response
  21. payloadDecoder *parser.PayloadDecoder
  22. payloadEncoder *parser.PayloadEncoder
  23. client *http.Client
  24. state state
  25. }
  26. func NewClient(r *http.Request) (transport.Client, error) {
  27. newEncoder := parser.NewBinaryPayloadEncoder
  28. if _, ok := r.URL.Query()["b64"]; ok {
  29. newEncoder = parser.NewStringPayloadEncoder
  30. }
  31. ret := &client{
  32. req: *r,
  33. url: *r.URL,
  34. seq: 0,
  35. payloadEncoder: newEncoder(),
  36. client: http.DefaultClient,
  37. state: stateNormal,
  38. }
  39. return ret, nil
  40. }
  41. func (c *client) Response() *http.Response {
  42. return c.resp
  43. }
  44. func (c *client) NextReader() (*parser.PacketDecoder, error) {
  45. if c.state != stateNormal {
  46. return nil, io.EOF
  47. }
  48. if c.payloadDecoder != nil {
  49. ret, err := c.payloadDecoder.Next()
  50. if err != io.EOF {
  51. return ret, err
  52. }
  53. c.getResp.Body.Close()
  54. c.payloadDecoder = nil
  55. }
  56. req := c.getReq()
  57. req.Method = "GET"
  58. var err error
  59. c.getResp, err = c.client.Do(req)
  60. if err != nil {
  61. return nil, err
  62. }
  63. if c.resp == nil {
  64. c.resp = c.getResp
  65. }
  66. c.payloadDecoder = parser.NewPayloadDecoder(c.getResp.Body)
  67. return c.payloadDecoder.Next()
  68. }
  69. func (c *client) NextWriter(messageType message.MessageType, packetType parser.PacketType) (io.WriteCloser, error) {
  70. if c.state != stateNormal {
  71. return nil, io.EOF
  72. }
  73. next := c.payloadEncoder.NextBinary
  74. if messageType == message.MessageText {
  75. next = c.payloadEncoder.NextString
  76. }
  77. w, err := next(packetType)
  78. if err != nil {
  79. return nil, err
  80. }
  81. return newClientWriter(c, w), nil
  82. }
  83. func (c *client) Close() error {
  84. if c.state != stateNormal {
  85. return nil
  86. }
  87. c.state = stateClosed
  88. return nil
  89. }
  90. func (c *client) getReq() *http.Request {
  91. req := c.req
  92. url := c.url
  93. req.URL = &url
  94. query := req.URL.Query()
  95. query.Set("t", fmt.Sprintf("%d-%d", time.Now().Unix()*1000, c.seq))
  96. c.seq++
  97. req.URL.RawQuery = query.Encode()
  98. return &req
  99. }
  100. func (c *client) doPost() error {
  101. if c.state != stateNormal {
  102. return io.EOF
  103. }
  104. req := c.getReq()
  105. req.Method = "POST"
  106. buf := bytes.NewBuffer(nil)
  107. if err := c.payloadEncoder.EncodeTo(buf); err != nil {
  108. return err
  109. }
  110. req.Body = ioutil.NopCloser(buf)
  111. var err error
  112. c.postResp, err = c.client.Do(req)
  113. if err != nil {
  114. return err
  115. }
  116. if c.resp == nil {
  117. c.resp = c.postResp
  118. }
  119. return nil
  120. }
  121. type clientWriter struct {
  122. io.WriteCloser
  123. client *client
  124. }
  125. func newClientWriter(c *client, w io.WriteCloser) io.WriteCloser {
  126. return &clientWriter{
  127. WriteCloser: w,
  128. client: c,
  129. }
  130. }
  131. func (w *clientWriter) Close() error {
  132. if err := w.WriteCloser.Close(); err != nil {
  133. return err
  134. }
  135. return w.client.doPost()
  136. }