Closed wHoIsDReAmer closed 7 months ago
Thanks for opening your first issue here! 🎉 Be sure to follow the issue template! If you need help or want to chat with us, join us on Discord https://gofiber.io/discord
@wHoIsDReAmer I would using the official websocket middleware. Using the gorilla one + adaptor defeats the purpose of using Fiber. We also got a socket.io middleware.
https://github.com/gofiber/contrib/tree/main/websocket https://github.com/gofiber/contrib/tree/main/socketio
then I can't handle for gql. Can you present that how gql proceed?
@wHoIsDReAmer You can use it, just beware if performance implication given each request/response has to converted for that handler.
Would it be possible to use the Fiber Websocket instead of gorilla with gql?
No. It can't be Fiber Websocket instead of gorilla with gql.
because gqlgen handler require implement ServeHTTP
if use another third-party library,
but Fiber Websocket middleware doesn't provide http.ResponseWriter
and *http.Request
thus I used gorilla with gql inevitable
Ok, I did some mistakes.
Here's solved code
func GraphQLHandler(eventBus *service.EventBus) (fiber.Handler, fiber.Handler) {
h := handler.NewDefaultServer(gql.NewExecutableSchema(gql.Config{Resolvers: &resolvers.Resolver{
EventBus: eventBus,
}}))
gqlHandler := func(c *fiber.Ctx) error {
httpHandler := adaptor.HTTPHandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := c.UserContext()
h.ServeHTTP(w, r.WithContext(ctx))
})
return httpHandler(c)
}
wsh := handler.New(gql.NewExecutableSchema(gql.Config{Resolvers: &resolvers.Resolver{
EventBus: eventBus,
}}))
wsh.AddTransport(transport.Websocket{
KeepAlivePingInterval: 10 * time.Second,
Upgrader: websocket2.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
CheckOrigin: func(ctx *http.Request) bool {
return true
},
},
})
wsh.Use(extension.Introspection{})
gqlWsHandler := func(c *fiber.Ctx) error {
ctx := c.UserContext()
req := &http.Request{}
fasthttpadaptor.ConvertRequest(c.Context(), req, false)
crw := &commonResponseWriter{c.Context().Conn(), nil, 0}
wsh.ServeHTTP(crw, req.WithContext(ctx))
return nil
}
return gqlHandler, gqlWsHandler
}
type commonResponseWriter struct {
conn net.Conn
header http.Header
status int
}
func (w *commonResponseWriter) Header() http.Header {
if w.header == nil {
w.header = make(http.Header)
}
return w.header
}
func (w *commonResponseWriter) Write(b []byte) (int, error) {
if w.status == 0 {
w.status = http.StatusOK
}
return w.conn.Write(b)
}
func (w *commonResponseWriter) WriteHeader(statusCode int) {
w.status = statusCode
// Write headers to the connection
fmt.Fprintf(w.conn, "HTTP/1.1 %d %s\r\n", statusCode, http.StatusText(statusCode))
w.header.Write(w.conn)
fmt.Fprint(w.conn, "\r\n")
}
func (w *commonResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
reader := bufio.NewReader(w.conn)
writer := bufio.NewWriter(w.conn)
readWriter := bufio.NewReadWriter(reader, writer)
return w.conn, readWriter, nil
}
I implemented Hijack for my own response writer wrapper then gql would proceed request,
Question Description
recently i tried link gqlgen with gofiber, but i can't implement subscription handling in gofiber.
client-side websocket got closed when client is connecting, without any headers here's my code
sorry for my bad english
Code Snippet (optional)
Checklist: