zoukankan      html  css  js  c++  java
  • 在 Gin 项目中使用 WebSocket

    前言

    实践是检验真理的唯一标准

    正文

    如何将Gin框架的后端与WebSocket服务写在一起, 以达到共用一个端口的情况呢?

    我们来看单纯使用 net 包和 WS 结合

    package main
    
    import (
    	"flag"
    	"fmt"
    	"log"
    	"net/http"
    
    	"github.com/gorilla/websocket"
    )
    
    var addr = flag.String("addr", "localhost:8080", "http service address")
    
    var upgrader = websocket.Upgrader{
    	// 解决跨域问题
    	CheckOrigin: func(r *http.Request) bool {
    		return true
    	},
    } // use default options
    
    func ws(w http.ResponseWriter, r *http.Request) {
    	c, err := upgrader.Upgrade(w, r, nil)
    	if err != nil {
    		log.Print("upgrade:", err)
    		return
    	}
    	defer c.Close()
    	for {
    		mt, message, err := c.ReadMessage()
    		if err != nil {
    			log.Println("read:", err)
    			break
    		}
    		log.Printf("recv: %s", message)
    		err = c.WriteMessage(mt, message)
    		if err != nil {
    			log.Println("write:", err)
    			break
    		}
    	}
    }
    
    func main() {
    	flag.Parse()
    	log.SetFlags(0)
    	http.HandleFunc("/ws", ws)
    	fmt.Println(*addr)
    	log.Fatal(http.ListenAndServe(*addr, nil))
    }
    
    

    其实本质来说, WS服务在握手的过程中最开始也是HTTP请求, 然后再 Upgrade 到WS模式的, Upgrade函数接受三个参数, 一个是返回值套接字, 一个是请求套接字, 一个是返回值的头, 而对于 Gin 的上下文 gin.Context 来说也是有这些数据的, 因此我们修改成

    package control
    
    import (
    	"log"
    	"net/http"
    
    	"github.com/gin-gonic/gin"
    	"github.com/gorilla/websocket"
    )
    
    var upgrader = websocket.Upgrader{
    	// 解决跨域问题
    	CheckOrigin: func(r *http.Request) bool {
    		return true
    	},
    } // use default options
    
    func cmdWebSocket(c *gin.Context) {
    	ws, err := upgrader.Upgrade(c.Writer, c.Request, nil)
    	if err != nil {
    		log.Print("upgrade:", err)
    		return
    	}
    	defer ws.Close()
    	for {
    		mt, message, err := ws.ReadMessage()
    		if err != nil {
    			log.Println("read:", err)
    			break
    		}
    		log.Printf("recv: %s", message)
    		err = ws.WriteMessage(mt, message)
    		if err != nil {
    			log.Println("write:", err)
    			break
    		}
    	}
    }
    
    

    即可

        作者:ChnMig

        出处:http://www.cnblogs.com/chnmig/

        本文版权归作者和博客园所有,欢迎转载。转载请在留言板处留言给我,且在文章标明原文链接,谢谢!

        如果您觉得本篇博文对您有所收获,觉得我还算用心,请点击左下角的 [推荐],谢谢!

  • 相关阅读:
    hdu 2222 Keywords Search
    Meet and Greet
    hdu 4673
    hdu 4768
    hdu 4747 Mex
    uva 1513 Movie collection
    uva 12299 RMQ with Shifts
    uva 11732 strcmp() Anyone?
    uva 1401
    hdu 1251 统计难题
  • 原文地址:https://www.cnblogs.com/chnmig/p/14463837.html
Copyright © 2011-2022 走看看