Golang中socket.io报错:WebSocket握手失败,返回意外状态码403的解决方法

Golang中socket.io报错:WebSocket握手失败,返回意外状态码403的解决方法 我正在尝试在Go和Angular中使用socket.io,但遇到了以下错误:

错误 image

Go代码

gin.SetMode(gin.ReleaseMode)
router := gin.Default()
//CORS
router.Use(cors.New(cors.Config{
AllowOrigins:     []string{"http://localhost:4200"},
AllowMethods:     []string{"PUT", "PATCH", "POST", "GET", "DELETE"},
 AllowHeaders:     []string{"Origin", "X-Requested-With", "Content-Type", "Cache- 
 Control", "Pragma", "Authorization", "Accept", "Accept-Encoding"},

 ExposeHeaders:    []string{"Content-Length"},

 AllowCredentials: true,

 // AllowOriginFunc: func(origin string) bool {

 //  return origin == "*"

 // },

 MaxAge: 12 * time.Hour,

}))
server, err := socketio.NewServer(nil)
if err != nil {

 log.Fatal(err)

}

server.OnConnect("/", func(s socketio.Conn) error {

 s.SetContext("")

 fmt.Println("connected:", s.ID())

 return nil

})

server.OnEvent("/", "message", func(s socketio.Conn, msg string) {

 fmt.Println("notice:", msg)

 s.Emit("response", "Nuevo Pedido")

})

server.OnEvent("/chat", "msg", func(s socketio.Conn, msg string) string {

 s.SetContext(msg)

 return "recv " + msg

})

server.OnEvent("/", "bye", func(s socketio.Conn) string {

 last := s.Context().(string)

 s.Emit("bye", last)

 s.Close()

 return last

})

server.OnDisconnect("/", func(s socketio.Conn, msg string) {

 fmt.Println("closed", msg)

})

router.GET("/socket.io/*any", gin.WrapH(server))

router.POST("/socket.io/*any", gin.WrapH(server))

// router.Handle("WSS", "/socket.io", []gin.HandlerFunc{SocketHandler})

//SERVER PORT

router.Run(":5000")

更多关于Golang中socket.io报错:WebSocket握手失败,返回意外状态码403的解决方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang中socket.io报错:WebSocket握手失败,返回意外状态码403的解决方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


403状态码通常表示服务器理解请求但拒绝授权。在WebSocket握手过程中,这通常是由于CORS配置或身份验证问题导致的。以下是针对Go中socket.io的解决方案:

1. 检查CORS配置

确保CORS配置正确允许WebSocket连接:

router.Use(cors.New(cors.Config{
    AllowOrigins:     []string{"http://localhost:4200"},
    AllowMethods:     []string{"PUT", "PATCH", "POST", "GET", "DELETE", "OPTIONS"},
    AllowHeaders:     []string{
        "Origin", 
        "X-Requested-With", 
        "Content-Type", 
        "Accept", 
        "Authorization",
        "X-Engine-Id",
        "X-Socket-Id",
        "X-Socket-ID",
        "Sec-WebSocket-Key",
        "Sec-WebSocket-Version",
        "Sec-WebSocket-Extensions",
        "Upgrade",
        "Connection",
    },
    ExposeHeaders:    []string{"Content-Length"},
    AllowCredentials: true,
    MaxAge: 12 * time.Hour,
}))

2. 添加OPTIONS方法处理

确保OPTIONS预检请求被正确处理:

router.OPTIONS("/socket.io/*any", func(c *gin.Context) {
    c.Header("Access-Control-Allow-Origin", "http://localhost:4200")
    c.Header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
    c.Header("Access-Control-Allow-Headers", "Origin, Content-Type, Accept, Authorization")
    c.Header("Access-Control-Allow-Credentials", "true")
    c.Status(200)
})

3. 使用socket.io的CORS中间件

socket.io有自己的CORS配置,需要单独设置:

server, err := socketio.NewServer(&socketio.Options{
    Cors: &socketio.Cors{
        Origin:      "http://localhost:4200",
        Credentials: true,
    },
    Transports: []string{"websocket", "polling"},
})
if err != nil {
    log.Fatal(err)
}

4. 完整的修复示例

package main

import (
    "fmt"
    "log"
    "time"
    
    "github.com/gin-contrib/cors"
    "github.com/gin-gonic/gin"
    socketio "github.com/googollee/go-socket.io"
)

func main() {
    gin.SetMode(gin.ReleaseMode)
    router := gin.Default()
    
    // CORS配置
    router.Use(cors.New(cors.Config{
        AllowOrigins:     []string{"http://localhost:4200"},
        AllowMethods:     []string{"GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"},
        AllowHeaders:     []string{
            "Origin",
            "Content-Type",
            "Accept",
            "Authorization",
            "X-Requested-With",
            "X-Engine-Id",
            "X-Socket-Id",
        },
        ExposeHeaders:    []string{"Content-Length"},
        AllowCredentials: true,
        MaxAge:           12 * time.Hour,
    }))
    
    // 处理OPTIONS预检请求
    router.OPTIONS("/socket.io/*any", func(c *gin.Context) {
        c.Header("Access-Control-Allow-Origin", "http://localhost:4200")
        c.Header("Access-Control-Allow-Credentials", "true")
        c.Header("Access-Control-Allow-Headers", "Origin, Content-Type, Accept, Authorization")
        c.Status(200)
    })
    
    // 创建socket.io服务器
    server, err := socketio.NewServer(&socketio.Options{
        Cors: &socketio.Cors{
            Origin:      "http://localhost:4200",
            Credentials: true,
        },
        Transports: []string{"websocket", "polling"},
    })
    if err != nil {
        log.Fatal(err)
    }
    
    // Socket.io事件处理
    server.OnConnect("/", func(s socketio.Conn) error {
        fmt.Println("connected:", s.ID())
        return nil
    })
    
    server.OnEvent("/", "message", func(s socketio.Conn, msg string) {
        fmt.Println("notice:", msg)
        s.Emit("response", "Nuevo Pedido")
    })
    
    // 路由处理
    router.GET("/socket.io/*any", gin.WrapH(server))
    router.POST("/socket.io/*any", gin.WrapH(server))
    
    // 启动服务器
    fmt.Println("Server starting on :5000")
    router.Run(":5000")
}

5. Angular客户端配置

确保Angular客户端正确配置:

import { io } from 'socket.io-client';

const socket = io('http://localhost:5000', {
  transports: ['websocket', 'polling'],
  withCredentials: true,
  extraHeaders: {
    "Access-Control-Allow-Origin": "http://localhost:4200"
  }
});

主要问题通常出现在CORS配置不完整或socket.io选项未正确设置。确保服务器端和客户端的CORS配置一致,特别是Allow-CredentialsOrigin设置。

回到顶部