【发布时间】:2021-06-17 19:49:38
【问题描述】:
我正在尝试实现一些 websocket 服务,因为我使用 gin 作为 web 框架,所以我选择go-socket.io。我运行 go-socket.io 的 cors 示例。服务器代码如下:
package main
import (
"log"
"net/http"
"github.com/gin-gonic/gin"
socketio "github.com/googollee/go-socket.io"
)
func GinMiddleware(allowOrigin string) gin.HandlerFunc {
return func(c *gin.Context) {
c.Writer.Header().Set("Access-Control-Allow-Origin", allowOrigin)
c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT, DELETE")
c.Writer.Header().Set("Access-Control-Allow-Headers", "Accept, Authorization, Content-Type, Content-Length, X-CSRF-Token, Token, session, Origin, Host, Connection, Accept-Encoding, Accept-Language, X-Requested-With")
if c.Request.Method == http.MethodOptions {
c.AbortWithStatus(http.StatusNoContent)
return
}
c.Request.Header.Del("Origin")
c.Next()
}
}
func main() {
router := gin.New()
server := socketio.NewServer(nil)
server.OnConnect("/", func(s socketio.Conn) error {
s.SetContext("")
log.Println("connected:", s.ID())
s.Emit("reply", "hello world")
return nil
})
server.OnEvent("/", "notice", func(s socketio.Conn, msg string) {
log.Println("notice:", msg)
s.Emit("reply", "have "+msg)
})
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.OnError("/", func(s socketio.Conn, e error) {
log.Println("meet error:", e)
})
server.OnDisconnect("/", func(s socketio.Conn, msg string) {
log.Println("closed", msg)
log.Println("why????")
})
go func() {
if err := server.Serve(); err != nil {
log.Fatalf("socketio listen error: %s\n", err)
}
}()
defer server.Close()
router.Use(GinMiddleware("*"))
router.GET("/socket.io/*any", gin.WrapH(server))
router.POST("/socket.io/*any", gin.WrapH(server))
router.StaticFS("/public", http.Dir("../asset"))
if err := router.Run(":8000"); err != nil {
log.Fatal("failed run app: ", err)
}
}
我用js作为客户端写了一个html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Go WebSocket Tutorial</title>
</head>
<body>
<h2>Hello World2</h2>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.4.0/socket.io.js"></script>
<script>
var socket = io.connect("http://localhost:8000/socket.io/",{ transports: ["websocket"], pingInterval: 60000 });
socket.on('news', function (data) {
console.log(data.hello);
socket.emit('my new event', { my:'new data' });/
});
socket.on('other', function (data) {
console.log(data.hello);
socket.emit('event1', { my:'other data' });
});
socket.on("connect_error", (error) => {
// ...
console.log("err:", error)
});
socket.on("disconnect", (reason) => {
if (reason === "io server disconnect") {
// the disconnection was initiated by the server, you need to reconnect manually
// socket.connect();
}
// else the socket will automatically try to reconnect
console.log("reason:", reason)
});
socket.emit("notice", "my_notice")
</script>
</body>
</html>
但我得到重复的重新连接。从 devtools 看来,它似乎连接到服务器,然后关闭连接,并保持这种行为。
【问题讨论】: