|
- package main
-
- import (
- "encoding/json"
- "fmt"
- "github.com/brianvoe/gofakeit/v6"
- "github.com/gorilla/websocket"
- log "github.com/sirupsen/logrus"
- "net/http"
- "time"
- )
-
- // We'll need to define an upgradeToWs
- // this will require a Read and Write buffer size
- var upgradeToWs = websocket.Upgrader{
- ReadBufferSize: 1024,
- WriteBufferSize: 1024,
- }
-
- func apiV1WebSocketHandler(w http.ResponseWriter, r *http.Request) {
- upgradeToWs.CheckOrigin = func(r *http.Request) bool { return true }
- ws, err := upgradeToWs.Upgrade(w, r, nil)
- if err != nil {
- log.Println("cannot upgrade websocket", err)
- return
- }
-
- // helpful log statement to show connections
- log.Println("Websocket Api/V1: Client Connected", r.RemoteAddr)
-
- wsReader(ws)
- }
-
- func wsReader(conn *websocket.Conn) {
- wsq.addConnection(conn)
- for {
-
- stillExist := wsq.has(conn)
- if !stillExist {
- return // the connection has been removed.
- }
-
- // read in a message
- messageType, p, err := conn.ReadMessage()
- if err != nil {
- wsq.del(conn)
- log.Println(err)
- return
- }
-
- // WsEchoIncomingMessage(conn, string(p), messageType)
- switch messageType {
- case websocket.TextMessage:
- WsProcessingTxtMessage(conn, string(p))
- break
- case websocket.BinaryMessage:
- WsProcessingBinaryMessage(conn, p)
- break
- case websocket.PingMessage:
- break
- case websocket.PongMessage:
- break
- }
-
- }
- }
-
- func WsProcessingTxtMessage(conn *websocket.Conn, str string) {
- if str == "send dummy string for 500 times" {
- go wsDummySender(conn)
- }
-
- // must be json message with key, value pairs
- incoming := make(map[string]string)
- e := json.Unmarshal([]byte(str), &incoming)
- if e != nil {
- log.Error("ws incoming msg error not json", str, e)
- return
- }
-
- key := incoming["t"]
- for _, v := range apiV1WsHandler {
- if key == v.Keyword {
- v.Handler(conn, incoming)
- return // we have already processed
- }
- }
- }
-
- func WsProcessingBinaryMessage(conn *websocket.Conn, data []byte) {
- return
- }
-
- func WsEchoIncomingMessage(conn *websocket.Conn, msg string, messageType int) {
- // print out that message for clarity
- fmt.Println(msg)
-
- // this is echo
- if err := conn.WriteMessage(messageType, []byte(msg)); err != nil {
- wsq.del(conn)
- log.Println(err)
- return
- }
- }
-
- func WsBroadCast(msg string) {
- wsq.wsDoBroadcast(msg, "")
- }
-
- func WsSend(To string, msg map[string]string) {
- b, e := json.Marshal(msg)
- if e != nil {
- log.Error("cannot broadcast websocket message, cannot convert to json", msg)
- }
-
- conn := wsq.getConnBySessionId(To)
- if conn != nil {
- err := conn.WriteMessage(websocket.TextMessage, b)
- if err != nil {
- wsq.del(conn)
- }
- }
- }
-
- func WsBroadCastExceptMe(me string, msg map[string]string) {
- b, e := json.Marshal(msg)
- if e == nil {
- wsq.wsDoBroadcast(string(b), me)
- }
- }
-
- func wsDummySender(conn *websocket.Conn) {
- //write subsequent 5 copies, each after 1 second
- log.Info("start sending server data to client ..")
- p := "dummy string from server "
- for i := 1; i < 500; i++ {
- time.Sleep(1 * time.Second)
- //msg := fmt.Sprintf("copy %d, %s, %s", i, p, wsDummyString()) // 4M long string no issue
- msg := fmt.Sprintf("copy %d, %s ", i, p)
- log.Info("dummy sender is working, ", msg)
- if err := conn.WriteMessage(websocket.TextMessage, []byte(msg)); err != nil {
- log.Println("wsDummySender stopped on error: ", err)
- return
- }
- }
- }
-
- func wsDummyString() string {
- s := gofakeit.LetterN(4096000) // 4M
- return s
- }
|