Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

155 lines
3.4KB

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "github.com/brianvoe/gofakeit/v6"
  6. "github.com/gorilla/websocket"
  7. log "github.com/sirupsen/logrus"
  8. "net/http"
  9. "time"
  10. )
  11. // We'll need to define an upgradeToWs
  12. // this will require a Read and Write buffer size
  13. var upgradeToWs = websocket.Upgrader{
  14. ReadBufferSize: 1024,
  15. WriteBufferSize: 1024,
  16. }
  17. func apiV1WebSocketHandler(w http.ResponseWriter, r *http.Request) {
  18. upgradeToWs.CheckOrigin = func(r *http.Request) bool { return true }
  19. ws, err := upgradeToWs.Upgrade(w, r, nil)
  20. if err != nil {
  21. log.Println("cannot upgrade websocket", err)
  22. return
  23. }
  24. // helpful log statement to show connections
  25. log.Println("Websocket Api/V1: Client Connected", r.RemoteAddr)
  26. wsReader(ws)
  27. }
  28. func wsReader(conn *websocket.Conn) {
  29. wsq.addConnection(conn)
  30. for {
  31. stillExist := wsq.has(conn)
  32. if !stillExist {
  33. return // the connection has been removed.
  34. }
  35. // read in a message
  36. messageType, p, err := conn.ReadMessage()
  37. if err != nil {
  38. wsq.del(conn)
  39. log.Println(err)
  40. return
  41. }
  42. // WsEchoIncomingMessage(conn, string(p), messageType)
  43. switch messageType {
  44. case websocket.TextMessage:
  45. WsProcessingTxtMessage(conn, string(p))
  46. break
  47. case websocket.BinaryMessage:
  48. WsProcessingBinaryMessage(conn, p)
  49. break
  50. case websocket.PingMessage:
  51. break
  52. case websocket.PongMessage:
  53. break
  54. }
  55. }
  56. }
  57. func WsProcessingTxtMessage(conn *websocket.Conn, str string) {
  58. if str == "send dummy string for 500 times" {
  59. go wsDummySender(conn)
  60. }
  61. // must be json message with key, value pairs
  62. incoming := make(map[string]string)
  63. e := json.Unmarshal([]byte(str), &incoming)
  64. if e != nil {
  65. log.Error("ws incoming msg error not json", str, e)
  66. return
  67. }
  68. key := incoming["t"]
  69. for _, v := range apiV1WsHandler {
  70. if key == v.Keyword {
  71. v.Handler(conn, incoming)
  72. return // we have already processed
  73. }
  74. }
  75. }
  76. func WsProcessingBinaryMessage(conn *websocket.Conn, data []byte) {
  77. return
  78. }
  79. func WsEchoIncomingMessage(conn *websocket.Conn, msg string, messageType int) {
  80. // print out that message for clarity
  81. fmt.Println(msg)
  82. // this is echo
  83. if err := conn.WriteMessage(messageType, []byte(msg)); err != nil {
  84. wsq.del(conn)
  85. log.Println(err)
  86. return
  87. }
  88. }
  89. func WsBroadCast(msg string) {
  90. wsq.wsDoBroadcast(msg, "")
  91. }
  92. func WsSend(To string, msg map[string]string) (e error) {
  93. conn := wsq.getConnBySessionId(To)
  94. return wsSendByConn(conn, msg)
  95. }
  96. func wsSendByConn(c *websocket.Conn, msg map[string]string) (e error) {
  97. b, e := json.Marshal(msg)
  98. if e != nil {
  99. log.Error("cannot broadcast websocket message, cannot convert to json", msg)
  100. }
  101. e = c.WriteMessage(websocket.TextMessage, b)
  102. if e != nil {
  103. wsq.del(c)
  104. }
  105. return
  106. }
  107. func WsBroadCastExceptMe(me string, msg map[string]string) {
  108. b, e := json.Marshal(msg)
  109. if e == nil {
  110. wsq.wsDoBroadcast(string(b), me)
  111. }
  112. }
  113. func wsDummySender(conn *websocket.Conn) {
  114. //write subsequent 5 copies, each after 1 second
  115. log.Info("start sending server data to client ..")
  116. p := "dummy string from server "
  117. for i := 1; i < 500; i++ {
  118. time.Sleep(1 * time.Second)
  119. //msg := fmt.Sprintf("copy %d, %s, %s", i, p, wsDummyString()) // 4M long string no issue
  120. msg := fmt.Sprintf("copy %d, %s ", i, p)
  121. log.Info("dummy sender is working, ", msg)
  122. if err := conn.WriteMessage(websocket.TextMessage, []byte(msg)); err != nil {
  123. log.Println("wsDummySender stopped on error: ", err)
  124. return
  125. }
  126. }
  127. }
  128. func wsDummyString() string {
  129. s := gofakeit.LetterN(4096000) // 4M
  130. return s
  131. }