You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

126 lines
2.6 KiB

package handlers
import (
"fmt"
"html/template"
"net/http"
"sync"
"github.com/gorilla/websocket"
"github.com/markbates/goth/gothic"
)
type Handler struct {
Template template.Template
}
type Message struct {
Id string
Action string
Message string
}
type PageData struct {
Username string
}
type hub struct {
clients map[*websocket.Conn]bool
Broadcast chan []byte
register chan *websocket.Conn
unregister chan *websocket.Conn
mutex sync.RWMutex
}
var Hub = &hub{
clients: make(map[*websocket.Conn]bool),
Broadcast: make(chan []byte),
register: make(chan *websocket.Conn),
unregister: make(chan *websocket.Conn),
}
var upgrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
return true // this should change
},
}
func (h *hub) Run() {
for {
select {
case conn := <-h.register:
h.mutex.Lock()
h.clients[conn] = true
h.mutex.Unlock()
fmt.Printf("Client connected. Total clients: %d\n", len(h.clients))
case conn := <-h.unregister:
h.mutex.Lock()
if _, ok := h.clients[conn]; ok {
delete(h.clients, conn)
conn.Close()
}
h.mutex.Unlock()
fmt.Printf("Client disconnected. Total clients: %d\n", len(h.clients))
case message := <-h.Broadcast:
h.mutex.RLock()
for conn := range h.clients {
if err := conn.WriteMessage(websocket.TextMessage, message); err != nil {
fmt.Printf("Error sending message to client: %v\n", err)
// Remove failed connection
delete(h.clients, conn)
conn.Close()
}
}
h.mutex.RUnlock()
}
}
}
func (h *Handler) Home(w http.ResponseWriter, r *http.Request) {
session, err := gothic.Store.Get(r, "user-session")
if err != nil {
http.Error(w, "Error retrieving session for welcome page", http.StatusInternalServerError)
}
username, ok := session.Values["user_name"].(string)
var pagedata PageData
if ok {
pagedata.Username = username
} else {
pagedata.Username = ""
}
err = h.Template.ExecuteTemplate(w, "index.html", &pagedata)
if err != nil {
http.Error(w, "Template rendering error", http.StatusInternalServerError)
}
}
func (h *Handler) WsHandler(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
fmt.Println("upgrade error:", err)
return
}
Hub.register <- conn
defer conn.Close()
for {
_, messageBytes, err := conn.ReadMessage()
if err != nil && !websocket.IsCloseError(
err,
websocket.CloseNormalClosure,
websocket.CloseGoingAway,
websocket.CloseNoStatusReceived,
) {
fmt.Printf("error reading message: %v", err)
}
Hub.Broadcast <- messageBytes
}
}