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>

 

posted @ 2018-10-27 21:53  静静别跑  阅读(508)  评论(0编辑  收藏  举报