Files
go-otel/internal/websocket/server.go
T
2025-11-06 18:57:28 +01:00

155 lines
3.3 KiB
Go

package websocket
import (
"encoding/json"
"log"
"net/http"
"sync"
"github.com/gorilla/websocket"
)
type DataType string
const (
DataTypeTraces DataType = "traces"
DataTypeMetrics DataType = "metrics"
DataTypeLogs DataType = "logs"
)
type HistoryProvider interface {
GetHistory() []HistoryEntry
}
type HistoryEntry struct {
Type string `json:"type"`
Timestamp int64 `json:"timestamp"`
Data interface{} `json:"data"`
}
type Entry struct {
Type string `json:"type"`
Data interface{} `json:"data"`
}
type Broadcaster interface {
Broadcast(data *Entry)
}
var upgrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
return true
},
}
type Server struct {
clients map[*websocket.Conn]bool
mutex sync.Mutex
historyProvider HistoryProvider
}
func New(historyProvider HistoryProvider) *Server {
return &Server{
clients: make(map[*websocket.Conn]bool),
historyProvider: historyProvider,
}
}
func (s *Server) HandleConnections(w http.ResponseWriter, r *http.Request) {
ws, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Printf("failed to upgrade connection: %v", err)
return
}
defer ws.Close()
s.mutex.Lock()
s.clients[ws] = true
s.mutex.Unlock()
log.Printf("client connected")
// // Send history to new client
// if s.historyProvider != nil {
// history := s.historyProvider.GetHistory()
// for _, entry := range history {
// if data, err := json.Marshal(entry); err == nil {
// if err := ws.WriteMessage(websocket.TextMessage, data); err != nil {
// log.Printf("failed to send history to client: %v", err)
// break
// }
// }
// }
// }
for {
// Read message from browser
_, _, err := ws.ReadMessage()
if err != nil {
log.Printf("read error: %v", err)
break
}
}
s.mutex.Lock()
delete(s.clients, ws)
s.mutex.Unlock()
log.Printf("client disconnected")
}
func (s *Server) Broadcast(entry *Entry) {
s.mutex.Lock()
defer s.mutex.Unlock()
msg, err := json.Marshal(entry)
if err != nil {
log.Printf("failed to marshal log entry: %v", err)
} else {
for client := range s.clients {
if err := client.WriteMessage(websocket.TextMessage, msg); err != nil {
log.Printf("write error: %v", err)
}
}
}
}
func (s *Server) SendHistory(ws *websocket.Conn) {
s.mutex.Lock()
defer s.mutex.Unlock()
history := s.historyProvider.GetHistory() // Assuming GetHistory() returns the history data
for _, entry := range history {
data, err := json.Marshal(entry)
if err != nil {
log.Printf("failed to marshal history entry: %v", err)
continue
}
if err := ws.WriteMessage(websocket.TextMessage, data); err != nil {
log.Printf("write error: %v", err)
}
}
}
func (s *Server) HandleMessage(ws *websocket.Conn, msg []byte) {
var message map[string]interface{}
if err := json.Unmarshal(msg, &message); err != nil {
log.Printf("error unmarshaling message: %v", err)
return
}
// Handle the message (this is just an example, adjust according to your needs)
switch message["type"] {
case "ping":
log.Printf("received ping")
s.SendPong(ws)
default:
log.Printf("unknown message type : %v", message)
}
}
func (s *Server) SendPong(ws *websocket.Conn) {
if err := ws.WriteMessage(websocket.PongMessage, nil); err != nil {
log.Printf("error sending pong: %v", err)
}
}