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
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 |
|
} |
|
}
|
|
|