Initialize project with basic structure, including Docker configuration, backend and frontend setup, environment configuration, and essential files for development.
This commit is contained in:
51
backend/internal/realtime/hub.go
Normal file
51
backend/internal/realtime/hub.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package realtime
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Event struct {
|
||||
Topic string `json:"topic"`
|
||||
Data json.RawMessage `json:"data"`
|
||||
}
|
||||
|
||||
type Hub struct {
|
||||
mu sync.RWMutex
|
||||
subs map[string]map[chan Event]struct{}
|
||||
}
|
||||
|
||||
func New() *Hub { return &Hub{subs: make(map[string]map[chan Event]struct{})} }
|
||||
|
||||
func (h *Hub) Publish(topic string, value any) {
|
||||
data, err := json.Marshal(value)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
h.mu.RLock()
|
||||
defer h.mu.RUnlock()
|
||||
for _, key := range []string{"*", topic} {
|
||||
for ch := range h.subs[key] {
|
||||
select {
|
||||
case ch <- Event{Topic: topic, Data: data}:
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Hub) Subscribe(topic string) (<-chan Event, func()) {
|
||||
ch := make(chan Event, 16)
|
||||
h.mu.Lock()
|
||||
if h.subs[topic] == nil {
|
||||
h.subs[topic] = make(map[chan Event]struct{})
|
||||
}
|
||||
h.subs[topic][ch] = struct{}{}
|
||||
h.mu.Unlock()
|
||||
return ch, func() {
|
||||
h.mu.Lock()
|
||||
delete(h.subs[topic], ch)
|
||||
close(ch)
|
||||
h.mu.Unlock()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user