• 在 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/

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

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

  • 相关阅读:
    Python列表和元组知识点
    Python 字符串操作常用知识点
    ng-alain的sf如何自定义部件
    Spring-手写Spring注解版本事务,Spring事物的七大传播行为
    Spring-SpringAOP原理,手写Spring事务框架
    JVM性能优化--类加载器,手动实现类的热加载
    JVM性能优化--字节码技术
    JVM性能优化--JVM参数配置,使用JMeter简单测试配合说明参数调优
    JVM性能优化--Java的垃圾回收机制
    设计模式之原型模式、策略模式、观察者模式
  • 原文地址:https://www.cnblogs.com/chnmig/p/14463837.html
Copyright © 2020-2023  润新知