/
gin_bridge.go
93 lines (79 loc) · 1.71 KB
/
gin_bridge.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package broker
import (
"errors"
"github.com/gin-gonic/gin"
"github.com/gorilla/websocket"
"github.com/zgwit/iot-master/v4/log"
"io"
"net"
"net/http"
)
var upGrader = &websocket.Upgrader{
//HandshakeTimeout: time.Second,
ReadBufferSize: 512,
WriteBufferSize: 512,
Subprotocols: []string{"mqtt"},
CheckOrigin: func(r *http.Request) bool { return true },
}
func GinBridge(ctx *gin.Context) {
c, err := upGrader.Upgrade(ctx.Writer, ctx.Request, nil)
if err != nil {
log.Error(err)
return
}
defer c.Close()
//阻塞执行
err = Server.EstablishConnection("web", &wsConn{Conn: c.UnderlyingConn(), Raw: c})
if err != nil {
log.Error(err)
}
ctx.Abort()
}
// wsConn is a websocket connection which satisfies the net.Conn interface.
type wsConn struct {
net.Conn
Raw *websocket.Conn
r io.Reader
}
// Read reads the next span of bytes from the websocket connection and returns the number of bytes read.
func (ws *wsConn) Read(p []byte) (int, error) {
if ws.r == nil {
op, r, err := ws.Raw.NextReader()
if err != nil {
return 0, err
}
if op != websocket.BinaryMessage {
err = errors.New("must be binary")
return 0, err
}
ws.r = r
}
var err error
var n, br int
for {
br, err = ws.r.Read(p[n:])
n += br
if err != nil {
ws.r = nil
if errors.Is(err, io.EOF) {
err = nil
}
return n, err
}
if n == len(p) {
return n, err
}
}
}
// Write writes bytes to the websocket connection.
func (ws *wsConn) Write(p []byte) (int, error) {
err := ws.Raw.WriteMessage(websocket.BinaryMessage, p)
if err != nil {
return 0, err
}
return len(p), nil
}
// Close signals the underlying websocket conn to close.
func (ws *wsConn) Close() error {
return ws.Conn.Close()
}