wsconn.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  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. c.reader = nil
  27. continue
  28. }
  29. return nBytes, err
  30. }
  31. }
  32. func (c *wsconn) getReader() (io.Reader, error) {
  33. if c.reader != nil {
  34. return c.reader, nil
  35. }
  36. _, reader, err := c.wsc.NextReader()
  37. if err != nil {
  38. return nil, err
  39. }
  40. c.reader = reader
  41. return reader, nil
  42. }
  43. func (c *wsconn) Write(b []byte) (int, error) {
  44. c.wlock.Lock()
  45. defer c.wlock.Unlock()
  46. if err := c.wsc.WriteMessage(websocket.BinaryMessage, b); err != nil {
  47. return 0, err
  48. }
  49. return len(b), nil
  50. }
  51. func (c *wsconn) Close() error {
  52. c.wsc.WriteControl(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""), time.Now().Add(time.Second*5))
  53. return c.wsc.Close()
  54. }
  55. func (c *wsconn) LocalAddr() net.Addr {
  56. return c.wsc.LocalAddr()
  57. }
  58. func (c *wsconn) RemoteAddr() net.Addr {
  59. return c.wsc.RemoteAddr()
  60. }
  61. func (c *wsconn) SetDeadline(t time.Time) error {
  62. if err := c.SetReadDeadline(t); err != nil {
  63. return err
  64. }
  65. return c.SetWriteDeadline(t)
  66. }
  67. func (c *wsconn) SetReadDeadline(t time.Time) error {
  68. return c.wsc.SetReadDeadline(t)
  69. }
  70. func (c *wsconn) SetWriteDeadline(t time.Time) error {
  71. return c.wsc.SetWriteDeadline(t)
  72. }