25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

67 lines
1.5KB

  1. package main
  2. import (
  3. "log"
  4. "net/http"
  5. "time"
  6. "github.com/gorilla/websocket"
  7. )
  8. func registerWSHandlers(mux *http.ServeMux, h *hub) {
  9. upgrader := websocket.Upgrader{CheckOrigin: func(r *http.Request) bool {
  10. origin := r.Header.Get("Origin")
  11. if origin == "" || origin == "null" {
  12. return true
  13. }
  14. return true
  15. }}
  16. mux.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {
  17. conn, err := upgrader.Upgrade(w, r, nil)
  18. if err != nil {
  19. log.Printf("ws upgrade failed: %v (origin: %s)", err, r.Header.Get("Origin"))
  20. return
  21. }
  22. c := &client{conn: conn, send: make(chan []byte, 32), done: make(chan struct{})}
  23. h.add(c)
  24. defer func() {
  25. h.remove(c)
  26. _ = conn.Close()
  27. }()
  28. conn.SetReadDeadline(time.Now().Add(60 * time.Second))
  29. conn.SetPongHandler(func(string) error {
  30. conn.SetReadDeadline(time.Now().Add(60 * time.Second))
  31. return nil
  32. })
  33. go func() {
  34. ping := time.NewTicker(30 * time.Second)
  35. defer ping.Stop()
  36. for {
  37. select {
  38. case msg, ok := <-c.send:
  39. if !ok {
  40. return
  41. }
  42. _ = conn.SetWriteDeadline(time.Now().Add(200 * time.Millisecond))
  43. if err := conn.WriteMessage(websocket.TextMessage, msg); err != nil {
  44. return
  45. }
  46. case <-ping.C:
  47. _ = conn.SetWriteDeadline(time.Now().Add(5 * time.Second))
  48. if err := conn.WriteMessage(websocket.PingMessage, nil); err != nil {
  49. log.Printf("ws ping error: %v", err)
  50. return
  51. }
  52. }
  53. }
  54. }()
  55. for {
  56. _, _, err := conn.ReadMessage()
  57. if err != nil {
  58. return
  59. }
  60. }
  61. })
  62. }