snow/handlers/socket.go

134 lines
2.5 KiB
Go
Raw Normal View History

2024-01-20 01:58:57 +00:00
package handlers
import (
2024-01-21 00:18:40 +00:00
"github.com/beevik/etree"
2024-01-20 01:58:57 +00:00
"github.com/ectrc/snow/aid"
"github.com/ectrc/snow/person"
"github.com/gofiber/contrib/websocket"
"github.com/gofiber/fiber/v2"
"github.com/google/uuid"
)
2024-01-20 23:08:29 +00:00
type SocketType string
2024-01-21 17:49:14 +00:00
const SocketTypeXmpp SocketType = "xmpp"
const SocketTypeUnknown SocketType = "unknown"
2024-01-20 23:08:29 +00:00
2024-01-20 01:58:57 +00:00
type Socket struct {
ID string
Connection *websocket.Conn
Person *person.Person
2024-01-21 17:49:14 +00:00
Type SocketType
PresenceState *PresenceState
2024-01-20 01:58:57 +00:00
}
2024-01-21 00:18:40 +00:00
type MessageToWrite struct {
Socket *Socket
Message []byte
}
func (s *Socket) Write(message []byte) {
socketWriteQueue <- MessageToWrite{
Socket: s,
Message: message,
}
}
func (s *Socket) WriteTree(message *etree.Document) {
bytes, err := message.WriteToBytes()
if err != nil {
return
}
socketWriteQueue <- MessageToWrite{
Socket: s,
Message: bytes,
}
}
2024-01-20 01:58:57 +00:00
var (
2024-01-21 00:18:40 +00:00
socketWriteQueue = make(chan MessageToWrite, 1000)
socketHandlers = map[SocketType]func(string) {
2024-01-21 17:49:14 +00:00
SocketTypeXmpp: presenceSocketHandle,
2024-01-20 23:08:29 +00:00
}
2024-01-20 01:58:57 +00:00
sockets = aid.GenericSyncMap[Socket]{}
)
func MiddlewareWebsocket(c *fiber.Ctx) error {
if !websocket.IsWebSocketUpgrade(c) {
return fiber.ErrUpgradeRequired
}
2024-01-20 23:08:29 +00:00
var protocol SocketType
switch c.Get("Sec-WebSocket-Protocol") {
case "xmpp":
protocol = SocketTypeXmpp
default:
protocol = SocketTypeUnknown
}
2024-01-20 01:58:57 +00:00
c.Locals("uuid", uuid.New().String())
2024-01-20 23:08:29 +00:00
c.Locals("protocol", protocol)
2024-01-20 01:58:57 +00:00
return c.Next()
}
func WebsocketConnection(c *websocket.Conn) {
2024-01-20 23:08:29 +00:00
protocol := c.Locals("protocol").(SocketType)
2024-01-20 01:58:57 +00:00
uuid := c.Locals("uuid").(string)
sockets.Add(uuid, &Socket{
ID: uuid,
2024-01-20 23:08:29 +00:00
Type: protocol,
2024-01-20 01:58:57 +00:00
Connection: c,
})
2024-01-21 00:18:40 +00:00
defer func() {
socket, ok := sockets.Get(uuid)
if !ok {
return
}
socket.Connection.Close()
sockets.Delete(uuid)
aid.Print("(xmpp) connection closed", uuid)
}()
2024-01-20 01:58:57 +00:00
2024-01-21 00:18:40 +00:00
if handle, ok := socketHandlers[protocol]; ok {
2024-01-20 23:08:29 +00:00
handle(uuid)
}
2024-01-20 01:58:57 +00:00
}
2024-01-21 17:49:14 +00:00
func GetSocketByPerson(person *person.Person) *Socket {
var recieverSocket *Socket
sockets.Range(func(key string, value *Socket) bool {
if value.Person == nil {
return true
}
if value.Person.ID == person.ID {
recieverSocket = value
return false
}
return true
})
return recieverSocket
}
2024-01-21 00:18:40 +00:00
func init() {
go func() {
for {
if aid.Config != nil {
break
}
}
aid.Print("(socket) write queue started")
for {
message := <-socketWriteQueue
2024-01-21 17:49:14 +00:00
aid.Print("(socket) writing message to", message.Socket.ID, string(message.Message))
2024-01-21 00:18:40 +00:00
message.Socket.Connection.WriteMessage(websocket.TextMessage, message.Message)
}
}()
2024-01-20 01:58:57 +00:00
}