, Ive , . - . .
:
SubscriptionHandler, subscribeFunction requestStream # SubscriptionHandler # setupSubscription.
SubscriptionHandler WebSocket ( ReconnectingWebSockets) onmessage (SubscriptionHandler # receiveSubscriptionPayload), .
SubscriptionHandler # newSubscription, SubscriptionHandler.subscriptions, ( MD5- ); , :
SubscriptionHandler.subscriptions = {
[md5hash]: {
query: QueryObject,
variables: SubscriptionVariables,
observer: Observer (contains OnNext method)
}
, , SubscriptionHandler # receiveSubscriptionPayload, , , - md5 /, SubscriptionHandler.subscriptions observer onNext.
, , :
export type ServerResponseMessageParsed = {
payload: QueryPayload,
request: {
query: string,
variables: Object,
}
}
, , .
SubscriptionHandler.js
class SubscriptionHandler {
subscriptions: Object;
subscriptionEnvironment: RelayModernEnvironment;
websocket: Object;
constructor(websocketUrl: string, webSocketSettings: WebSocketSettings) {
this.subscriptions = {};
this.subscriptionEnvironment = null;
this.websocket = new ReconnectingWebSocket(
websocketUrl,
null,
webSocketSettings,
);
this.websocket.onmessage = this.receiveSubscriptionPayload;
}
attachEnvironment = (environment: RelayModernEnvironment) => {
this.subscriptionEnvironment = environment;
}
getHash = (query: string, variables: HashVariables) => {
const queryString = query.replace(/\s+/gm, '');
const variablesString = JSON.stringify(variables);
const hash = md5(queryString + variablesString).toString();
return hash;
}
receiveSubscriptionPayload = (message: ServerResponseMessage) => {
const response: ServerResponseMessageParsed = JSON.parse(message.data);
const { query, variables } = response.request;
const hash = this.getHash(query, variables);
const subscription = this.subscriptions[hash];
if (subscription) {
subscription.observer.onNext(response.payload);
} else {
console.warn(Received payload for unregistered hash: ${hash});
}
}
newSubscription = (
subscriptionQuery: GraphQLTaggedNode,
variables: Variables,
configs: GraphQLSubscriptionConfig,
) => {
const config = configs || DEFAULT_CONFIG;
requestSubscription(
this.subscriptionEnvironment,
{
subscription: subscriptionQuery,
variables: {},
...config,
},
);
}
setupSubscription = (
config: ConcreteBatch,
variables: Variables,
cacheConfig: ?CacheConfig,
observer: Observer,
) => {
const query = config.text;
const hash = this.getHash(query, variables);
this.subscriptions[hash] = { query, variables };
const subscription = this.subscriptions[hash];
subscription.observer = observer;
setTimeout(() => {
this.websocket.send(JSON.stringify({ query, variables }));
}, 100);
}
}
const subscriptionHandler = new SubscriptionHandler(WS_URL, WS_OPTIONS);
export default subscriptionHandler;