配置Apollo连接到Hasura并尝试设置GraphQL订阅不起作用。没有错误或其他任何东西,只是不工作。我已经创建了一个简单的Angular项目(称之为Base Demo),并配置了Apollo,订阅确实可以工作。我使用的是相同的节点版本和相同的库以及ngx-admin的库版本。
如果我在ngx-admin中使用相同的代码来配置GraphQL(我只是克隆了项目以确保没有添加任何代码),它就无法工作。没有显示任何订阅的结果,但我也没有得到任何错误。浏览器控制台中的ws连接看起来与Base Demo项目中的完全相同。
// GraphQLModule.ts
import {NgModule} from '@angular/core';
import {ApolloModule, APOLLO_OPTIONS} from 'apollo-angular';
import {ApolloClientOptions, InMemoryCache, split} from '@apollo/client/core';
import {HttpLink} from 'apollo-angular/http';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { GraphQLWsLink } from '@apollo/client/link/subscriptions';
import { createClient } from 'graphql-ws';
import { getMainDefinition } from '@apollo/client/utilities';
const uri = 'http://localhost:8080/v1/graphql';
const wsUri = 'ws://localhost:8080/v1/graphql';
export function createApollo(httpLink: HttpLink, http: HttpClient): ApolloClientOptions<any> {
var token = "<token>";
const authLink = httpLink.create({
uri,
headers: !token ? new HttpHeaders() :
new HttpHeaders()
.set('Authorization', `Bearer ${token}`)
.set('x-hasura-role', "manager"),
});
const wsLink = new GraphQLWsLink(createClient({
url: wsUri,
connectionParams: {
headers: !token ? {} :
{
Authorization: `Bearer ${token}`,
'x-hasura-role': "user",
}
}
}));
// The split function takes three parameters:
//
// * A function that's called for each operation to execute
// * The Link to use for an operation if the function returns a "truthy" value
// * The Link to use for an operation if the function returns a "falsy" value
const splitLink = split(
({ query }) => {
const definition = getMainDefinition(query);
return (
definition.kind === 'OperationDefinition' &&
definition.operation === 'subscription'
);
},
wsLink,
authLink,
);
return {
cache: new InMemoryCache({
addTypename: false,
}),
link: splitLink,
};
}
@NgModule({
exports: [ApolloModule],
providers: [
{
provide: APOLLO_OPTIONS,
useFactory: createApollo,
deps: [HttpLink, HttpClient],
},
],
})
export class GraphQLModule {}
// subscription-page.component.ts
import { Component, OnInit } from '@angular/core';
import { Subscription } from 'rxjs';
import { ApiService } from '../../../services/api.service';
@Component({
selector: 'app-subscription-page',
templateUrl: './subscription-page.component.html',
styleUrls: ['./subscription-page.component.scss']
})
export class SubscriptionPageComponent implements OnInit {
data: any;
subscription?: Subscription;
constructor(
private api: ApiService,
) {}
ngOnInit(): void {
this.subscription = this.api.subscribe()
.subscribe({
next: (v) => this.data = v,
error: (e) => console.error(e),
complete: () => console.info('complete')
})
}
ngOnDestroy(): void {
this.subscription?.unsubscribe();
}
}
环境:
Node, npm: node v14.21.3 (npm v6.14.18)
OS: Ubuntu 18.04
Browser: Chrome, Firefox
Angular 13.3.12
Nebular 9.1.0-rc.8
克隆ngx-admin repo并在那里配置Apollo,我希望订阅可以像正常的Angular项目一样工作。
1条答案
按热度按时间rjee0c151#
在上周和今天之间浪费了8个多小时试图找到问题所在,逐行查看每个文件和配置并做了一些测试之后,我终于找到了解决方案。罪魁祸首是
pace-js
,它包含在ngx-admin中,但最终我从未使用过。pace-js
跟踪websockets会导致一些问题,因此解决方案是禁用该跟踪:现在一切正常我将实际上完全消除
pace-js
,因为我不使用它无论如何。