Skip to content

Commit 56184ee

Browse files
authored
controller options to set a OnSocketConnect,Disconnect callback function (#56)
1 parent 86769a8 commit 56184ee

File tree

3 files changed

+51
-4
lines changed

3 files changed

+51
-4
lines changed

controller.go

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,11 @@ type Controller interface {
2828
}
2929

3030
type opt struct {
31-
channelFunc func(r *http.Request, viewID string) *string
32-
pathParamsFunc func(r *http.Request) PathParams
33-
websocketUpgrader websocket.Upgrader
31+
onSocketConnect func(userOrSessionID string) error
32+
onSocketDisconnect func(userOrSessionID string)
33+
channelFunc func(r *http.Request, viewID string) *string
34+
pathParamsFunc func(r *http.Request) PathParams
35+
websocketUpgrader websocket.Upgrader
3436

3537
disableTemplateCache bool
3638
disableWebsocket bool
@@ -146,6 +148,27 @@ func WithDropDuplicateInterval(interval time.Duration) ControllerOption {
146148
}
147149
}
148150

151+
// WithOnSocketConnect takes a function that is called when a new websocket connection is established.
152+
// The function should return an error if the connection should be rejected.
153+
// The user or fir's browser session id is passed to the function.
154+
// user must be set in request.Context with the key UserKey by a developer supplied authentication mechanism.
155+
// It can be used to track user connections and disconnections.
156+
// It can be be used to reject connections based on user or session id.
157+
// It can be used to refresh the page data when a user re-connects.
158+
func WithOnSocketConnect(f func(userOrSessionID string) error) ControllerOption {
159+
return func(o *opt) {
160+
o.onSocketConnect = f
161+
}
162+
}
163+
164+
// WithOnSocketDisconnect takes a function that is called when a websocket connection is disconnected.
165+
func WithOnSocketDisconnect(f func(userOrSessionID string)) ControllerOption {
166+
return func(o *opt) {
167+
o.onSocketDisconnect = f
168+
}
169+
170+
}
171+
149172
// DisableTemplateCache is an option to disable template caching. This is useful for development.
150173
func DisableTemplateCache() ControllerOption {
151174
return func(o *opt) {

examples/counter-ticker/main.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,17 @@ func (i *index) updated(ctx fir.RouteContext) error {
116116

117117
func main() {
118118
pubsubAdapter := pubsub.NewInmem()
119-
controller := fir.NewController("counter_app", fir.DevelopmentMode(true), fir.WithPubsubAdapter(pubsubAdapter))
119+
controller := fir.NewController("counter_app",
120+
fir.DevelopmentMode(true),
121+
fir.WithPubsubAdapter(pubsubAdapter),
122+
fir.WithOnSocketConnect(func(userOrSessionID string) error {
123+
fmt.Printf("socket connected for user %s\n", userOrSessionID)
124+
return nil
125+
}),
126+
fir.WithOnSocketDisconnect(func(userOrSessionID string) {
127+
fmt.Printf("socket disconnected for user %s\n", userOrSessionID)
128+
}),
129+
)
120130
http.Handle("/", controller.Route(NewCounterIndex(pubsubAdapter)))
121131
http.ListenAndServe(":9867", nil)
122132
}

websocket.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,20 @@ func onWebsocket(w http.ResponseWriter, r *http.Request, cntrl *controller) {
9696

9797
user := getUserFromRequestContext(r)
9898

99+
connectedUser := user
100+
if user == "" {
101+
connectedUser = sessionID
102+
}
103+
if cntrl.onSocketConnect != nil {
104+
err := cntrl.onSocketConnect(connectedUser)
105+
if err != nil {
106+
return
107+
}
108+
}
109+
if cntrl.onSocketDisconnect != nil {
110+
defer cntrl.onSocketDisconnect(connectedUser)
111+
}
112+
99113
send := make(chan []byte, 100)
100114

101115
ctx := context.Background()

0 commit comments

Comments
 (0)