Getting WebSocket connection to 'ws://localhost:7080/query' failed on connecting graphql-ws client with gqlgen golang server

huangapple go评论102阅读模式
英文:

Getting WebSocket connection to 'ws://localhost:7080/query' failed on connecting graphql-ws client with gqlgen golang server

问题

以下是代码中的订阅查询,它在graphql playground上运行良好,但当我尝试使用gqlgen驱动的go服务器连接我的graphql-ws客户端时,出现了"WebSocket connection to 'ws://localhost:7080/query' failed"错误。我尝试使用graphql-ws的useServer函数连接到本地运行的其他localhost服务器,这个方法运行良好,但连接到go服务器时出现了问题。

客户端代码:

(async () => {
    const client = graphqlWs.createClient({
        url: 'ws://localhost:7080/query',
    });

    const onNext = (data) => {
        /* 处理传入的值 */
        console.log("data==>", data)
    };

    try {
        await new Promise((resolve, reject) => {
            unsubscribe = client.subscribe(
                {
                    query: `subscription {
                        ping
                    }`
                },
                {
                    next: onNext,
                    error: reject,
                    complete: resolve
                },
            );
        });
    } catch(e) {
        console.error("E=>", e)
    }
})();

我已经花了两天的时间搜索有关使用纯JS连接go服务器的有用博客和链接,但没有找到任何有用的信息。我还在graphql-ws库的GitHub页面上搜索了列出的问题,但也没有找到类似的问题。

如果需要其他信息,请告诉我。

英文:

The subscription query listed below in code working fine on graphql playground but when i tried to connect my graphql-ws client with gqlgen driven go server, i got WebSocket connection to 'ws://localhost:7080/query' failed error. I tried connecting to my other localhost server running locally using useServer function of graphql-ws that worked nicely but got issue while connecting with go server.

Client Code:-

(async () => {
 const client = graphqlWs.createClient({
            url: 'ws://localhost:7080/query',
        });


 const onNext = (data) => {
          /* handle incoming values */
          console.log("data===>", data)
  };

    await new Promise((resolve, reject) => {
                unsubscribe = client.subscribe(
                    {
                        query: `subscription {
                            ping
                          }`
                       
                    },
                    {
                        next: onNext,
                        error: reject,
                        complete: resolve
                    },
                );
            });
            } catch(e) {
                console.error("E==>", e)
            }
   })();  

Slogging since last two days to get some useful blog and link online but not found anything useful of connecting go server with vanilla js. Also searched listed issues on graphql-ws library on its github page but there also no such issue is listed.

Please let me know if other info is required regarding this.

答案1

得分: 1

gqlgen的ws子协议自gqlgen@v0.15.0起为graphql-transport-ws。如果有人在"helloworld"遇到连接问题,请检查websocket的升级器的checkOrigin属性。

我正在使用gqlgen@v0.17.22,发现Websocket/Subscription的官方示例无法配置checkOrigin属性。问题在于handler.NewDefaultServer已经配置了一个ws传输,我们可以使用handler.New并自己完成其余部分。

srv := handler.New(graphql.NewSchema(client))
srv.AddTransport(transport.Options{})
srv.AddTransport(transport.GET{})
srv.AddTransport(transport.POST{})
srv.AddTransport(transport.MultipartForm{})
srv.SetQueryCache(lru.New(1000))
srv.Use(extension.Introspection{})
srv.Use(extension.AutomaticPersistedQuery{
	Cache: lru.New(100),
})
// 添加由我们自己配置的ws传输
srv.AddTransport(&transport.Websocket{
	Upgrader: websocket.Upgrader{
		//ReadBufferSize:  1024,
		//WriteBufferSize: 1024,
		CheckOrigin: func(r *http.Request) bool {
			// 添加检查origin的逻辑来决定返回true还是false
			return true
		},
	},
	KeepAlivePingInterval: 10 * time.Second,
})
英文:

The ws subprotocol of gqlgen is graphql-transport-ws since gqlgen@v0.15.0. If someone is still facing connection problem at the "helloworld", check the checkOrigin property of websocket's upgrader.

I'm using gqlgen@v0.17.22 and have found out that the offical example of Websocket/Subscription can't config the checkOrigin property. The problem is that the handler.NewDefaultServer already have a configured ws transport, we could use handler.New and do the rest parts ourselves.

srv := handler.New(graphql.NewSchema(client))
srv.AddTransport(transport.Options{})
srv.AddTransport(transport.GET{})
srv.AddTransport(transport.POST{})
srv.AddTransport(transport.MultipartForm{})
srv.SetQueryCache(lru.New(1000))
srv.Use(extension.Introspection{})
srv.Use(extension.AutomaticPersistedQuery{
	Cache: lru.New(100),
})
// add ws transport configured by ourselves
srv.AddTransport(&transport.Websocket{
	Upgrader: websocket.Upgrader{
		//ReadBufferSize:  1024,
		//WriteBufferSize: 1024,
		CheckOrigin: func(r *http.Request) bool {
			// add checking origin logic to decide return true or false
			return true
		},
	},
	KeepAlivePingInterval: 10 * time.Second,
})

答案2

得分: 0

如果你在谈论的是gqlgen,它不支持GraphQL over WebSocket Protocol实现的graphql-ws遗憾的是,它只支持subscriptions-transport-ws的旧协议。(这就是为什么graphql-playground可以工作的原因)。也就是说,你必须使用subscriptions-transport-ws与他们的后端配合使用。

英文:

If you are talking about this gqlgen, it does not support the GraphQL over WebSocket Protocol graphql-ws implements. It, sadly, supports only the legacy protocol of subscriptions-transport-ws. (which is why graphql-playground works). Meaning, you must use the subscriptions-transport-ws with their backend.

huangapple
  • 本文由 发表于 2021年5月24日 23:48:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/67675102.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定