Apollo GraphQL Client连接ws://localhost:8080失败,求解决方法
前端使用Apollo GraphQL Client,BFF服务基于gqlgen搭建。
前端Apollo配置代码
const wsLink = new GraphQLWsLink(createClient({url: 'ws://localhost:8080/'}))
后端gqlgen服务代码
srv := handler.NewDefaultServer(generated.NewExecutableSchema(generated.Config{Resolvers: &resolvers.Resolver{}})) srv.AddTransport(&transport.Websocket{}) srv.AddTransport(transport.POST{}) if helpers.Env("MODE") == "PRODUCTION" { cache, err := apq.NewCache(24 * time.Hour) if err != nil { log.Fatalf("cannot create APQ redis cache: %v", err) } srv.Use(extension.AutomaticPersistedQuery{Cache: cache}) } router.Handle("/", srv) if helpers.Env("MODE") == "DEVELOPMENT" { router.Handle("/playground", playground.Handler("GraphQL playground", "/")) log.Printf("connect to http://localhost:%s/playground for GraphQL playground", port) } log.Fatal(http.ListenAndServe(":"+port, router))
当前遇到错误:
WebSocket connection to 'ws://localhost:8080/' failed: error while trying to do a subscription
已尝试替换连接地址为ws://localhost:8080/subscriptions、ws://localhost:8080/graphql、ws://myIP:8080/,均未解决问题。
配置WebSocket传输的Upgrader
gqlgen的transport.Websocket必须配置Upgrader才能正确处理HTTP到WebSocket的升级请求,现有代码仅添加了传输但未配置关键的跨域校验逻辑。修改后端代码:srv.AddTransport(&transport.Websocket{ Upgrader: websocket.Upgrader{ CheckOrigin: func(r *http.Request) bool { // 开发环境可直接返回true,生产环境需根据业务域名设置合法Origin校验 return true }, }, })浏览器的同源策略会拦截跨域WebSocket请求,
CheckOrigin返回true是开发环境下快速验证的方案,生产环境务必替换为严格的域名校验逻辑。确认Apollo Client与后端的协议兼容性
前端使用的GraphQLWsLink基于graphql-ws库,对应graphql-transport-ws协议,gqlgen默认支持该协议,无需额外配置。需确保前端链接的URL与后端路由完全匹配——后端将gqlgen handler挂载到了根路径/,因此前端URLws://localhost:8080/是正确的,无需修改为其他路径。排查路由中间件的拦截问题
若使用第三方路由库而非标准http.ServeMux,需确保WebSocket升级请求(GET方法)能被正确路由到/路径的gqlgen handler。部分路由库会默认限制请求方法,需手动允许GET请求访问该路径。验证端口与服务可用性
确认后端服务确实监听8080端口,无其他进程占用该端口;同时检查本地防火墙是否允许8080端口的WebSocket连接。添加日志定位具体错误
在后端开启调试日志,或为WebSocket传输添加日志钩子,查看连接失败时的详细错误信息。例如,可在HTTP服务器添加请求日志中间件,确认WebSocket升级请求是否成功到达gqlgen handler。
内容的提问来源于stack exchange,提问作者nastaran jalali

