generated from PenaSide/GolangTemplate
82 lines
2.4 KiB
Go
82 lines
2.4 KiB
Go
|
package sse
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
)
|
||
|
|
||
|
type ConnectionDispatcher struct {
|
||
|
buffer *SSEConnectionRingBuffer
|
||
|
}
|
||
|
|
||
|
// bufferSize размер кольца минимум 2
|
||
|
func NewConnectionDispatcher(bufferSize int) *ConnectionDispatcher {
|
||
|
return &ConnectionDispatcher{
|
||
|
buffer: NewSSEConnectionRingBuffer(bufferSize),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (r *ConnectionDispatcher) AddConnection(userID, deviceID string) *SSEConnection {
|
||
|
conn := NewSSEConnection(userID, deviceID)
|
||
|
currentMap := r.buffer.GetCurrent() // тут текущие данные откуда читают воркеры
|
||
|
nextMap := r.buffer.GetNext() // следующая поидее должна быть пустой
|
||
|
|
||
|
for key, value := range currentMap {
|
||
|
nextMap[key] = value
|
||
|
}
|
||
|
|
||
|
// покомментарию Миши копируем слайсы отдельно
|
||
|
existingConnections := nextMap[userID]
|
||
|
newConnections := make([]*SSEConnection, len(existingConnections)+1)
|
||
|
copy(newConnections, existingConnections)
|
||
|
newConnections[len(existingConnections)] = conn
|
||
|
nextMap[userID] = newConnections
|
||
|
|
||
|
r.buffer.Rotate()
|
||
|
|
||
|
return conn
|
||
|
}
|
||
|
|
||
|
func (r *ConnectionDispatcher) RemoveConnection(userID, deviceID string) {
|
||
|
currentMap := r.buffer.GetCurrent() // тут текущие данные откуда читают воркеры
|
||
|
nextMap := r.buffer.GetNext() // следующая на которую переключимся
|
||
|
|
||
|
for key, value := range currentMap {
|
||
|
nextMap[key] = value
|
||
|
}
|
||
|
|
||
|
existingConnections := nextMap[userID]
|
||
|
afterDropConnections := make([]*SSEConnection, 0, len(existingConnections))
|
||
|
|
||
|
for _, conn := range existingConnections {
|
||
|
if conn.DeviceID != deviceID {
|
||
|
afterDropConnections = append(afterDropConnections, conn)
|
||
|
} else {
|
||
|
close(conn.Channel)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// если есть коннекты то складываем оставшиеся после удаления, если == 0 то дропаем этого пользователя из мэпки
|
||
|
if len(afterDropConnections) > 0 {
|
||
|
nextMap[userID] = afterDropConnections
|
||
|
} else {
|
||
|
delete(nextMap, userID)
|
||
|
}
|
||
|
|
||
|
r.buffer.Rotate()
|
||
|
}
|
||
|
|
||
|
func (r *ConnectionDispatcher) SendToUser(userID string, event SSEEvent) error {
|
||
|
currentMap := r.buffer.GetCurrent()
|
||
|
connections := currentMap[userID]
|
||
|
|
||
|
if len(connections) == 0 {
|
||
|
return fmt.Errorf("no active connections for user %s", userID)
|
||
|
}
|
||
|
|
||
|
for _, conn := range connections {
|
||
|
conn.Channel <- event
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|