NetConn converts a *websocket.Conn into a net.Conn. It's for tunneling arbitrary protocols over WebSockets. Few users of the library will need this but it's tricky to implement correctly and so provided in the library. See https://github.com/nhooyr/websocket/issues/100. Every Write to the net.Conn
(ctx context.Context, c *Conn, msgType MessageType)
| 46 | // |
| 47 | // Furthermore, the ReadLimit is set to -1 to disable it. |
| 48 | func NetConn(ctx context.Context, c *Conn, msgType MessageType) net.Conn { |
| 49 | c.SetReadLimit(-1) |
| 50 | |
| 51 | nc := &netConn{ |
| 52 | c: c, |
| 53 | msgType: msgType, |
| 54 | readMu: newMu(c), |
| 55 | writeMu: newMu(c), |
| 56 | } |
| 57 | |
| 58 | nc.writeCtx, nc.writeCancel = context.WithCancel(ctx) |
| 59 | nc.readCtx, nc.readCancel = context.WithCancel(ctx) |
| 60 | |
| 61 | nc.writeTimer = time.AfterFunc(math.MaxInt64, func() { |
| 62 | if !nc.writeMu.tryLock() { |
| 63 | // If the lock cannot be acquired, then there is an |
| 64 | // active write goroutine and so we should cancel the context. |
| 65 | nc.writeCancel() |
| 66 | return |
| 67 | } |
| 68 | defer nc.writeMu.unlock() |
| 69 | |
| 70 | // Prevents future writes from writing until the deadline is reset. |
| 71 | nc.writeExpired.Store(1) |
| 72 | }) |
| 73 | if !nc.writeTimer.Stop() { |
| 74 | <-nc.writeTimer.C |
| 75 | } |
| 76 | |
| 77 | nc.readTimer = time.AfterFunc(math.MaxInt64, func() { |
| 78 | if !nc.readMu.tryLock() { |
| 79 | // If the lock cannot be acquired, then there is an |
| 80 | // active read goroutine and so we should cancel the context. |
| 81 | nc.readCancel() |
| 82 | return |
| 83 | } |
| 84 | defer nc.readMu.unlock() |
| 85 | |
| 86 | // Prevents future reads from reading until the deadline is reset. |
| 87 | nc.readExpired.Store(1) |
| 88 | }) |
| 89 | if !nc.readTimer.Stop() { |
| 90 | <-nc.readTimer.C |
| 91 | } |
| 92 | |
| 93 | return nc |
| 94 | } |
| 95 | |
| 96 | type netConn struct { |
| 97 | c *Conn |