-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapplication.go
More file actions
98 lines (88 loc) · 3.75 KB
/
application.go
File metadata and controls
98 lines (88 loc) · 3.75 KB
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
94
95
96
97
98
package wstf
import (
"net/http"
"github.com/gorilla/websocket"
)
type Application struct {
// Main router.
RootRouter *Router
// Router that will be handled on device is connected.
OnConnectionRouter *Router
// Router that will be handled on device is disconnected.
OnDisconnectionRouter *Router
// On read message from client failed, which literally means connection is closed.
OnReadMessageFailed func(connection *Connection, err error)
// On received message from client.
OnReceiveMessage func(connection *Connection, messageType int, message []byte)
// Call when received message is not recognized(and hence unhandled) as requests or other commands.
OnReceiveUnhandledMessage func(connection *Connection, messageType int, message []byte)
// Call when received message starts with '{', but is not a valid request.
OnReceiveInvalidRequest func(connection *Connection, messageType int, message []byte)
}
// Create a new Application with root router.
// Use the RootRouter as param in constructor because it is required.
func NewApplication(rootRouter *Router) *Application {
return &Application{RootRouter: rootRouter}
}
// Get the WebSocket handler for http routing.
//
// The #onNotAbleToUpgradeToWebSocket() will be called if the request not be able to upgrade( by checking request
// metadata, like headers, @see upgrader#AbleToUpgrade()).
//
// The #getWebSocketResponseHeader() will be called if the request can be upgraded. It is expected to
// 1. return `*, false` to *reject* WebSocket connection request.
// - You should handle http.ResponseWrite yourself, like response a status code with some message.
// 2. return `*http.Header, true` to *accept* the WebSocket connection request.
// - In this case, you should ignore the http.ResponseWrite.
// - If the #responseHeader is not nil, it will be included in the response to the client's upgrade request and may
// be used to specify cookies (Set-Cookie) and the application negotiated subprotocol (Sec-WebSocket-Protocol),
// you may checkout github.com/gorilla/websocket/server.go#Upgrade() for more info.
//
// The #onUpgradeToWebSocketFailed() will be called if the request can be upgraded to WebSocket but failed to. The callback
// may be rarely called.
func (m *Application) GetWebsocketHandlerFunc(
upgrader *websocket.Upgrader,
onNotAbleToUpgradeToWebSocket func(w http.ResponseWriter, r *http.Request),
getWebSocketResponseHeader func(conn *Connection, w http.ResponseWriter) (*http.Header, bool),
onUpgradingToWebSocketFailed func(err error, w http.ResponseWriter, r *http.Request),
) func(w http.ResponseWriter, r *http.Request) {
mHandler := func(w http.ResponseWriter, r *http.Request) {
if !AbleToUpgrade(upgrader, w, r) {
onNotAbleToUpgradeToWebSocket(w, r)
return
}
connection := m.NewConnection(nil, r)
responseHeader, pass := getWebSocketResponseHeader(connection, w)
if !pass {
return
}
conn, err := upgrader.Upgrade(w, r, *responseHeader)
if err != nil {
onUpgradingToWebSocketFailed(err, w, r)
return
}
connection.WebSocketConn = conn
connection.OnConnect()
}
return mHandler
}
// The RootRouter is required and hence we don't provide function to set or modify root router.
// An application can have only one router as the home router.
//func (m *Application) SetRootRouter(router *Router) {
// m.RootRouter = router
//}
func (m *Application) OnConnected(router *Router) {
m.OnConnectionRouter = router
}
func (m *Application) OnDisconnected(router *Router) {
m.OnDisconnectionRouter = router
}
// Create a connection instance once a WebSocket connection is established and connected.
func (m *Application) NewConnection(conn *websocket.Conn, req *http.Request) *Connection {
return &Connection{
m,
req,
conn,
make(map[string]interface{}),
}
}