wsconn.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. package websocket
  2. import (
  3. "io"
  4. "net"
  5. "sync"
  6. "time"
  7. "github.com/gorilla/websocket"
  8. "v2ray.com/core/common/errors"
  9. )
  10. type wsconn struct {
  11. wsc *websocket.Conn
  12. reader io.Reader
  13. rlock sync.Mutex
  14. wlock sync.Mutex
  15. }
  16. func (c *wsconn) Read(b []byte) (int, error) {
  17. c.rlock.Lock()
  18. defer c.rlock.Unlock()
  19. for {
  20. reader, err := c.getReader()
  21. if err != nil {
  22. return 0, err
  23. }
  24. nBytes, err := reader.Read(b)
  25. if errors.Cause(err) == io.EOF {
  26. continue
  27. }
  28. return nBytes, err
  29. }
  30. }
  31. func (c *wsconn) getReader() (io.Reader, error) {
  32. if c.reader != nil {
  33. return c.reader, nil
  34. }
  35. _, reader, err := c.wsc.NextReader()
  36. if err != nil {
  37. return nil, err
  38. }
  39. c.reader = reader
  40. return reader, nil
  41. }
  42. func (c *wsconn) Write(b []byte) (int, error) {
  43. c.wlock.Lock()
  44. defer c.wlock.Unlock()
  45. if err := c.wsc.WriteMessage(websocket.BinaryMessage, b); err != nil {
  46. return 0, err
  47. }
  48. return len(b), nil
  49. }
  50. func (c *wsconn) Close() error {
  51. c.wsc.WriteControl(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""), time.Now().Add(time.Second*5))
  52. return c.wsc.Close()
  53. }
  54. func (c *wsconn) LocalAddr() net.Addr {
  55. return c.wsc.LocalAddr()
  56. }
  57. func (c *wsconn) RemoteAddr() net.Addr {
  58. return c.wsc.RemoteAddr()
  59. }
  60. func (c *wsconn) SetDeadline(t time.Time) error {
  61. if err := c.SetReadDeadline(t); err != nil {
  62. return err
  63. }
  64. return c.SetWriteDeadline(t)
  65. }
  66. func (c *wsconn) SetReadDeadline(t time.Time) error {
  67. return c.wsc.SetReadDeadline(t)
  68. }
  69. func (c *wsconn) SetWriteDeadline(t time.Time) error {
  70. return c.wsc.SetWriteDeadline(t)
  71. }