Go language websocket establish connections and regularly send heartbeat

In a lot of work is needed to establish the connection websocket to simulate concurrent users, the beginning is to use a third-party jmeter websocket package to achieve, but found too multithreaded jmeter consume system resources, build around about 8000 when the load is connected machine in pressure measurement process resources had been occupied almost, instead go to achieve.

It is part of the implementation code:

package main

import (
   "encoding/json"
   "flag"
   "fmt"
   "github.com/gorilla/websocket"
   "github.com/satori/go.uuid"
   "log"
   "net/url"
   "regexp"
   "sync"
   "time"
)

type Connetion struct {
   con *websocket.Conn
   mutex sync.Mutex
}

 //定义命令行参数 var addr = flag.String("a", "ip:port", "http service address") var clientUuid = flag.String("u", "", "uuid") var c = flag.Int("c", 5, "number of connections") func webSocketConn(wg sync.WaitGroup, msg []byte) { u := url.URL{Scheme: "ws", Host:* websocket.Dialerdialer *wasAddr} Conn, _, ERR: = dialer.Dial (u.String (), nil) IF ! ERR = nil { fmt.Println (ERR) return } WERR: = conn.WriteMessage (websocket.TextMessage, MSG) // FMT. printf ( "send:% S \ n-", String (MSG)) // 2. Create a regular expression object REGx, _: = regexp.Compile ( " \\ {W}. 8 (-. 4 \\ {W }) {}. 3 - 12 is {W} \\ " ) // 3. regular expressions object matches the specified string RES: regx.FindString = ( string (MSG)) // fmt.Printf (" match clientId:% S \ n-", RES) MSG1: = the make (Map [ String ] interface {}) Msg2:= make(map[string]interface{}) msg2["success"] = true msg1["clientId"] = res msg1["messageType"] = "ACK" msg1["messageId"] = "5e7d6e31e4b079c2b22876d8" msg1["data"] = msg2 aMsg, _ := json.Marshal(msg1) if werr != nil { fmt.Println (WERR) } // declare timer 10s, set the heartbeat time 10s TICKER: = time.NewTicker (time.Second * 10 ) Connect: = & Connetion { CON: Conn, } // Open multithreaded go connect .timeWriter (TICKER, Conn) for { _, Message, ERR: = conn.ReadMessage () IF ! ERR = nil { fmt.Println ( " Read: " , ERR) return } // mutex connect.mutex.Lock () werr2:
= connect.con .WriteMessage (websocket.TextMessage, AMSG) connect.mutex.Unlock () if werr2 != nil { fmt.Println(werr2) } fmt.Printf("received: %s\n", message) } wg.Done() // 每次把计数器-1 } func (con *Connetion)timeWriter(ticker *time.Ticker, c *websocket.Conn) { for { <-ticker.C err := c.SetWriteDeadline(time.Now().Add(10 * time.Second)) //fmt.Println(time.Now().Format(time.UnixDate)) if err != nil { log.Printf("ping error: %s\n", err.Error()) } con.mutex.Lock() if err := c.WriteMessage(websocket.PingMessage, nil); err != nil { log.Printf("ping error: %s\n", err.Error()) } con.mutex.Unlock() } } func NewConnMsg() []byte { msg := make(map[string]interface{}) uuid1,_ := uuid.NewV4() //fmt.Printf("uuid值:%s\n",uuid1) id := uuid1.String() if *clientUuid == "" { msg["clientId"] = id } else { msg["clientId"] = *clientUuid } msg["messageId"] = "5e7d6e31e4b079c2b22876d8" msg["messageType"] = "LOGIN" msg["targetType"] = "PASSENGER"= BMsg, _:json.Marshal (MSG) log.Printf ( "% S \ n-", BMSG) return BMSG } FUNC RUN () { flag.Parse () // command line arguments var WG sync.WaitGroup // declare counter for I: = 0 ; I <C *; I ++ { wg.Add ( . 1 ) // set counter initial value Go webSocketConn (WG, NewConnMsg ()) IF (% C * 200 is ) == 0 { time.sleep (time.Millisecond * 50 ) // fmt.Println (Time.now (). the Format (time.UnixDate)) }// } log.Printf ( " creaate WebSocket Connections: V% \ n- " , * C) wg.Wait () // run blocking code until the counter is decremented to 0 } FUNC main () { // NewConnMsg () RUN () }

Since websocket does not support concurrent write, you need to add are required to write a message in place of the mutex, do not it will error: concurrent write to websocket connection go

Guess you like

Origin www.cnblogs.com/tianyun5115/p/12613274.html