added long pooling
This commit is contained in:
parent
19297b331e
commit
17b0970364
6
main.go
6
main.go
@ -2,6 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"backend/src/args_parser"
|
"backend/src/args_parser"
|
||||||
|
"backend/src/client_notifier"
|
||||||
"backend/src/config"
|
"backend/src/config"
|
||||||
"backend/src/core/models"
|
"backend/src/core/models"
|
||||||
"backend/src/core/repos"
|
"backend/src/core/repos"
|
||||||
@ -80,6 +81,8 @@ func main() {
|
|||||||
emailRepo := repos.NewEmailRepo()
|
emailRepo := repos.NewEmailRepo()
|
||||||
actionTokenRepo := repos.NewActionTokenRepo(sqlDb)
|
actionTokenRepo := repos.NewActionTokenRepo(sqlDb)
|
||||||
|
|
||||||
|
clientNotifier := client_notifier.NewBasicNotifier()
|
||||||
|
|
||||||
userService := services.NewUserService(
|
userService := services.NewUserService(
|
||||||
services.UserServiceDeps{
|
services.UserServiceDeps{
|
||||||
Jwt: jwtUtil,
|
Jwt: jwtUtil,
|
||||||
@ -116,6 +119,9 @@ func main() {
|
|||||||
dummyGroup.Use(middleware.NewAuthMiddleware(userService))
|
dummyGroup.Use(middleware.NewAuthMiddleware(userService))
|
||||||
dummyGroup.GET("/", handlers.NewDummyHandler())
|
dummyGroup.GET("/", handlers.NewDummyHandler())
|
||||||
|
|
||||||
|
lpGroup := r.Group("/pooling")
|
||||||
|
lpGroup.GET("/", handlers.NewLongPoolingHandler(clientNotifier))
|
||||||
|
|
||||||
listenAddr := fmt.Sprintf(":%d", conf.GetPort())
|
listenAddr := fmt.Sprintf(":%d", conf.GetPort())
|
||||||
logger.Log().Msgf("server listening on %s", listenAddr)
|
logger.Log().Msgf("server listening on %s", listenAddr)
|
||||||
|
|
||||||
|
|||||||
12
src/client_notifier/event.go
Normal file
12
src/client_notifier/event.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package client_notifier
|
||||||
|
|
||||||
|
type Event struct {
|
||||||
|
Type EventType
|
||||||
|
Data []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
type EventType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
EventTypeEmailConfirmed EventType = "event_email_confirmed"
|
||||||
|
)
|
||||||
57
src/client_notifier/notifier.go
Normal file
57
src/client_notifier/notifier.go
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
package client_notifier
|
||||||
|
|
||||||
|
import "sync"
|
||||||
|
|
||||||
|
type ClientNotifier interface {
|
||||||
|
RegisterClient(id string) <-chan Event
|
||||||
|
UnregisterClient(id string)
|
||||||
|
NotifyClient(id string, e Event)
|
||||||
|
}
|
||||||
|
|
||||||
|
type client struct {
|
||||||
|
id string
|
||||||
|
eventChan chan Event
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBasicNotifier() ClientNotifier {
|
||||||
|
return &basicNotifier{
|
||||||
|
m: &sync.RWMutex{},
|
||||||
|
clients: map[string]client{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type basicNotifier struct {
|
||||||
|
m *sync.RWMutex
|
||||||
|
clients map[string]client
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *basicNotifier) RegisterClient(id string) <-chan Event {
|
||||||
|
p.m.Lock()
|
||||||
|
defer p.m.Unlock()
|
||||||
|
|
||||||
|
eventChan := make(chan Event)
|
||||||
|
p.clients[id] = client{
|
||||||
|
id: id,
|
||||||
|
eventChan: eventChan,
|
||||||
|
}
|
||||||
|
|
||||||
|
return eventChan
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *basicNotifier) UnregisterClient(id string) {
|
||||||
|
p.m.Lock()
|
||||||
|
defer p.m.Unlock()
|
||||||
|
|
||||||
|
delete(p.clients, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *basicNotifier) NotifyClient(id string, e Event) {
|
||||||
|
p.m.RLock()
|
||||||
|
defer p.m.RUnlock()
|
||||||
|
|
||||||
|
client, ok := p.clients[id]
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
client.eventChan <- e
|
||||||
|
}
|
||||||
27
src/server/handlers/long_pooling_handler.go
Normal file
27
src/server/handlers/long_pooling_handler.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"backend/src/client_notifier"
|
||||||
|
"backend/src/server/utils"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewLongPoolingHandler(notifier client_notifier.ClientNotifier) gin.HandlerFunc {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
user := utils.GetUserFromRequest(c)
|
||||||
|
if user == nil {
|
||||||
|
c.Data(403, "plain/text", []byte("Unauthorized"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
eventChan := notifier.RegisterClient(user.Id)
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-c.Done():
|
||||||
|
notifier.UnregisterClient(user.Id)
|
||||||
|
case event := <-eventChan:
|
||||||
|
c.Data(200, "application/json", event.Data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
14
src/server/utils/user.go
Normal file
14
src/server/utils/user.go
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"backend/src/core/models"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetUserFromRequest(c *gin.Context) *models.UserDTO {
|
||||||
|
if user, ok := c.Get("user"); ok {
|
||||||
|
return user.(*models.UserDTO)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user