61 lines
1.1 KiB
Go
61 lines
1.1 KiB
Go
package web
|
|
|
|
import (
|
|
"chat/internal/cache"
|
|
"chat/internal/models"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/coder/websocket"
|
|
"github.com/coder/websocket/wsjson"
|
|
)
|
|
|
|
func HandleChat(w http.ResponseWriter, r *http.Request, cache *cache.Cache) {
|
|
// Get channel id from Cache
|
|
roomID := r.URL.Query().Get("room")
|
|
val, found := cache.Get(roomID)
|
|
if !found {
|
|
http.Error(w, "Channel not found", 404)
|
|
return
|
|
}
|
|
ch := val.(*models.Channel)
|
|
|
|
// Accept websocket
|
|
conn, err := websocket.Accept(w, r, &websocket.AcceptOptions{
|
|
InsecureSkipVerify: true,
|
|
})
|
|
if err != nil {
|
|
return
|
|
}
|
|
defer conn.Close(websocket.StatusNormalClosure, "")
|
|
|
|
ctx := r.Context()
|
|
|
|
// Register client to this channel
|
|
ch.Mu.RLock()
|
|
for _, msg := range ch.Messages {
|
|
_ = wsjson.Write(ctx, conn, msg)
|
|
}
|
|
ch.Mu.RUnlock()
|
|
|
|
// Register for live updates
|
|
ch.Mu.Lock()
|
|
if ch.Clients == nil {
|
|
ch.Clients = make(map[*websocket.Conn]bool)
|
|
}
|
|
ch.Clients[conn] = true
|
|
ch.Mu.Unlock()
|
|
|
|
// Simple read loop
|
|
for {
|
|
var msg models.Message
|
|
err := wsjson.Read(ctx, conn, &msg)
|
|
if err != nil {
|
|
break
|
|
}
|
|
|
|
msg.Timestamp = time.Now()
|
|
ch.Broadcast(ctx, msg)
|
|
}
|
|
}
|