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/

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

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

  • 相关阅读:
    origin/HEAD -> origin/master 这个分支是干嘛的啊
    使用Spring Boot来加速Java web项目的开发
    分辨真假数据科学家的20个问题及回答
    我的数学建模历程
    计算机科学中最重要的32个算法
    期权交易基本原理——买进看跌期权(Long Put),卖出看跌期权(Short Put)
    期货交易术语
    apecceosummit2016
    opencv 61篇
    server-pc--------------->lspci,lsusb,meminfo等配置信息
  • 原文地址:https://www.cnblogs.com/chnmig/p/14463837.html
Copyright © 2011-2022 走看看