- With issues:
- Use the search tool before opening a new issue.
- Please provide source code and commit sha if you found a bug.
-
Review existing issues and provide feedback or react to them.
-
go version: "go version go1.11.2 darwin/amd64"
- gin version (or commit ref): "v1.3.0"
- operating system: "macos mojave 10.14.2"
Description
I'm trying to use gin-gonic with https://github.com/googollee/go-socket.io . go-socket.io repo is using gorilla's websocket for handling connections etc and it uses hijack inside of it. Problem is, when I pass context (request and responseWriter) into go-socket.io's ServeHTTP method, gin still trying to write headers while upgrading connection. I'm getting "[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 200 with 400" on every connection.
Here are the sample code:
var (
srv *http.Server
socketSrv *socketio.Server
)
func main() {
socketSrv, err = socketio.NewServer(nil)
if err != nil {
log.Fatalf("failed to create new socketio server instance.")
}
gin.SetMode(gin.DebugMode)
server := gin.New()
server.Use(gin.Logger())
root := server.Group("/")
{
root.GET("/", homeHandler)
root.GET("/stats/", statsHandler)
root.Handle ("GET", "/socket.io/", handler())
root.Handle ("WS", "/socket.io/", handler())
root.Handle ("WSS", "/socket.io/", handler())
}
go func() {
if err := srv.ListenAndServe(); err != nil {
log.Printf("%v", err)
}
}()
Stop()
}
func Stop() {
quit := make(chan os.Signal, 1)
signal.Notify(quit, os.Interrupt, syscall.SIGTERM)
<-quit
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
log.Printf("Server shutdown error: %v", err)
os.Exit(1)
}
log.Printf("Server successfuly stopped.")
}
func initws(c *gin.Context) {
if c.IsWebsocket() {
err := socketSrv.On("connection", func(so socketio.Socket) {
log.Println("on connection")
so.On("disconnection", func() {
log.Println("on disconnect")
})
})
if err != nil {
log.Printf("error :%e", err)
}
err = socketSrv.On("error", func(so socketio.Socket, err error) {
log.Println("error:", err)
})
if err != nil {
log.Printf("error :%e", err)
}
socketSrv.ServeHTTP(c.Writer, c.Request)
return
}
}
func handler() gin.HandlerFunc {
return func(context *gin.Context) {
initws(context)
context.Abort()
return
}
}
Output: [GIN] 2018/12/18 - 17:18:04 | 400 | 117.48µs | ::1 | GET /socket.io/?EIO=3&transport=websocket [GIN-debug] [WARNING] Headers were already written. Wanted to override status code 200 with 400
PS Socket and connection is working fine. Only problem is that log.
Screenshots
Comment From: iquad
Seems like go-socket.io was returning 400 itself then using same connection.
Comment From: doquangtan
Use can use this lib socket.io golang. It is socketio server version 4.x and it can using with client version 3.x, 4.x
import (
"github.com/gin-gonic/gin"
socketio "github.com/doquangtan/socket.io/v4"
)
func main() {
io := socketio.New()
io.OnConnection(func(socket *socketio.Socket) {
// ...
})
router := gin.Default()
router.GET("/socket.io/", gin.WrapH(io.HttpHandler()))
router.Run(":3300")
}