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/

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

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

  • 相关阅读:
    [转]使用WIndows的BAT来延时执行某程序
    Xamarin.Forms之ListView探究笔记
    常用SQL语句集合
    Xamarin.Forms之探索笔记
    (持续更新)Xamarin.Forms之常见的问题
    (持续更新)Xamarin.Forms之DevExpress GridControl的使用技巧
    Xamarin.Forms之Effects的使用
    Xamarin.Android之添加.so文件
    from psycopg2._psycopg import ( ortError: DLL load failed: 找不到指定的模块。的一种解决方案
    ODOO中创建website Part-1 创建模块
  • 原文地址:https://www.cnblogs.com/chnmig/p/14463837.html
Copyright © 2011-2022 走看看