zoukankan      html  css  js  c++  java
  • golang websocket

    项目名称:websocketa

    1. server.go

    package main
    
    import (
        "github.com/gin-gonic/gin"
        "websocketa/middleware"
        "websocketa/controllers"
    )
    
    func main() {
        route := gin.Default()
        route.Use(middleware.WsMiddleware)
        route.GET("ws", controllers.Wstest)
        route.Run("0.0.0.0:5000")
    }

    2. 处理函数:controllers/controller.go

    package controllers
    
    import (
        "fmt"
        "github.com/gin-gonic/gin"
        "github.com/gorilla/websocket"
        "github.com/json-iterator/go"
        "sync"
        "time"
        "reflect"
        "log"
    )
    
    type dataClient struct {
        Conn     *websocket.Conn
        reciveParam   []string
        exitChan chan struct{}
    }
    func (wc *dataClient) Close() {
        wc.Conn.Close()
    }
    func (wc *dataClient) StartAndWait() {
        wc.exitChan = make(chan struct{})
        defer close(wc.exitChan)
    
        var wg sync.WaitGroup
        wg.Add(2)
        go func() {
            defer wg.Done()
            wc.listen()
        }()
        go func() {
            defer wg.Done()
            wc.write()
        }()
        wg.Wait()
    }
    
    func (wc *dataClient) write() {
        ticker := time.NewTicker(time.Second * 5)
        defer ticker.Stop()
        for {
            select {
            case <-wc.exitChan:
                return
            default:
                wc.send()
                <-ticker.C
            }
        }
    }
    
    func (wc *dataClient) listen() {
        for {
            _, msg, err := wc.Conn.ReadMessage()
            if err != nil {
                wc.exitChan <- struct{}{}
                return
            }
    
            param := string(msg)
            fmt.Println(reflect.TypeOf(param), param)
            err = jsoniter.Unmarshal(msg, wc.reciveParam)
            log.Println(err)
            //wc.send()  // 可以单独发一次消息
        }
    }
    
    func (wc *dataClient) send() {
        var result string
        if len(wc.reciveParam) == 0{
            // 逻辑
            result = "reciveParam is empty"
        }else {
            // 拿到客户端发过来的参数,逻辑操作
            result = fmt.Sprintf("reciveParam is %v", wc.reciveParam)
        }
        returnBytes, _ := jsoniter.Marshal(result)
        fmt.Println(string(returnBytes))
        wc.Conn.WriteMessage(websocket.TextMessage, returnBytes)
    }
    
    func Wstest(ctx *gin.Context) {
        cli := dataClient{
            Conn: ctx.MustGet("websocketConnection").(*websocket.Conn),
            exitChan:make(chan struct{}),
        }
        defer cli.Close()
        cli.StartAndWait()
        fmt.Println(44)
    }

    3. 中间件:middlewares/middleware.go

    package middleware
    
    import (
        "github.com/gin-gonic/gin"
        "github.com/gorilla/websocket"
        "net/http"
        "time"
    )
    
    var wsUpgrade = websocket.Upgrader{
        ReadBufferSize:   1024,
        WriteBufferSize:  1024,
        HandshakeTimeout: 5 * time.Second,
        CheckOrigin: func(r *http.Request) bool {
            return true
        },
        EnableCompression: true,
    }
    
    // websocket中间件
    func WsMiddleware(ctx *gin.Context) {
        conn, err := wsUpgrade.Upgrade(ctx.Writer, ctx.Request, nil)
        if err != nil {
            ctx.AbortWithStatusJSON(400, gin.H{})
        } else {
            ctx.Set("websocketConnection", conn)
            ctx.Next()
        }
    }

    4. 测试:wsTest.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    
    </body>
    <script type="text/javascript">
        let websocket = new WebSocket("ws://localhost:5000/ws");
        websocket.onmessage = function (e) {
            console.log(e.data);
        }
        // websocket.onopen = function () {
            // websocket.send(JSON.stringify([
            //     "hahaha",
            // ]));
            // websocket.send(JSON.stringify([
            //     "item1",
            //     "item2",
            // ]));
        // }
    </script>
    </html>
  • 相关阅读:
    BZOJ_2802_[Poi2012]Warehouse Store_堆+贪心
    BZOJ_1025_[SCOI2009]游戏_DP+置换+数学
    BZOJ_3672_ [Noi2014]购票_CDQ分治+斜率优化
    BZOJ_3671_[Noi2014]随机数生成器_set+贪心
    BZOJ_1998_[Hnoi2010]Fsk物品调度_并查集+置换
    BZOJ_1119_[POI2009]SLO_置换+贪心
    「JOI Open 2016」摩天大楼(笛卡尔树dp+优化)
    【GDOI2020模拟01.16】树上的鼠 (博弈+长链剖分优化dp)
    【GDOI2020模拟01.16】划愤(nim积+行列式)
    Codeforces [Hello 2020] 1284F New Year and Social Network(图论匹配推理+lct)
  • 原文地址:https://www.cnblogs.com/zhzhlong/p/9863611.html
Copyright © 2011-2022 走看看