WebSocket listen notification API

This commit is contained in:
2024-03-31 13:04:48 +08:00
parent 11377c378b
commit 7873bafa4f
14 changed files with 164 additions and 72 deletions

View File

@ -17,6 +17,9 @@ func authMiddleware(c *fiber.Ctx) error {
tk := strings.Replace(header, "Bearer", "", 1)
token = strings.TrimSpace(tk)
}
if query := c.Query("tk"); len(query) > 0 {
token = strings.TrimSpace(query)
}
c.Locals("token", token)

View File

@ -31,7 +31,17 @@ func notifyUser(c *fiber.Ctx) error {
return fiber.NewError(fiber.StatusNotFound, err.Error())
}
if err := services.NewNotification(client, user, data.Subject, data.Content, data.Links, data.IsImportant); err != nil {
notification := models.Notification{
Subject: data.Subject,
Content: data.Subject,
Links: data.Links,
IsImportant: data.IsImportant,
ReadAt: nil,
RecipientID: user.ID,
SenderID: &client.ID,
}
if err := services.NewNotification(notification); err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error())
}

32
pkg/server/notify_ws.go Normal file
View File

@ -0,0 +1,32 @@
package server
import (
"git.solsynth.dev/hydrogen/identity/pkg/models"
"git.solsynth.dev/hydrogen/identity/pkg/services"
"github.com/gofiber/contrib/websocket"
"github.com/samber/lo"
)
func listenNotifications(c *websocket.Conn) {
user := c.Locals("principal").(models.Account)
// Push connection
services.WsConn[user.ID] = append(services.WsConn[user.ID], c)
// Event loop
var err error
for {
message := services.WsNotifyQueue[user.ID]
if message != nil {
if err = c.WriteMessage(1, message); err != nil {
break
}
}
}
// Pop connection
services.WsConn[user.ID] = lo.Filter(services.WsConn[user.ID], func(item *websocket.Conn, idx int) bool {
return item != c
})
}

View File

@ -1,6 +1,7 @@
package server
import (
"github.com/gofiber/contrib/websocket"
"net/http"
"strings"
"time"
@ -60,9 +61,14 @@ func NewServer() {
{
api.Get("/avatar/:avatarId", getAvatar)
api.Get("/notifications", authMiddleware, getNotifications)
api.Put("/notifications/:notificationId/read", authMiddleware, markNotificationRead)
api.Post("/notifications/subscribe", authMiddleware, addNotifySubscriber)
notify := api.Group("/notifications").Name("Notifications API")
{
notify.Get("/", authMiddleware, getNotifications)
notify.Put("/:notificationId/read", authMiddleware, markNotificationRead)
notify.Post("/subscribe", authMiddleware, addNotifySubscriber)
notify.Get("/listen", authMiddleware, websocket.New(listenNotifications))
}
me := api.Group("/users/me").Name("Myself Operations")
{