λ¬Έμμμλ WsLinkλ₯Ό μ²μ μμ±ν λ connectionParams
μ ν ν°μ μ 곡νλ κ²μΌλ‘ μΉ μμΌμ λν μΈμ¦μ μ€λͺ
ν©λλ€.
κ·Έλ¬λ μ¬μ©μκ° λ‘κ·Έμμνλ€κ° λ€μ λ‘κ·ΈμΈνλ©΄(λ€λ₯Έ ν ν°μΌλ‘) λμ€μ ν ν°μ λ³κ²½νκ³ μ°κ²°μ λ€μ μ΄κΈ°ννλ λ°©λ²μ΄ λΆλΆλͺ ν©λλ€.
λ€μκ³Ό κ°μ΄ μνλ κ²°κ³Όλ₯Ό μ»μ μ μμμ΅λλ€.
export const changeSubscriptionToken = token => {
if (wsLink.subscriptionClient.connectionParams.authToken === token) {
return
}
wsLink.subscriptionClient.connectionParams.authToken = token
wsLink.subscriptionClient.close()
wsLink.subscriptionClient.connect()
}
νμ§λ§ wsLink.subscriptionClient
κ° λΉκ³΅κ°λ‘ νμλκ³ μΈλΆμμ μ‘μΈμ€ν μ μλλ‘ λμ΄ μκΈ° λλ¬Έμ λ€μ ν΄νΉλ λλμ
λλ€.
connectionParamsμμ κ°μ²΄λ‘ ν΄μλλ ν¨μλ₯Ό μ¬μ©ν μ μμ΅λλ€.
const wsLink = new WebSocketLink({
uri: config.subscriptionURL,
options: {
reconnect: true,
connectionParams: () => ({
authToken: reduxStore.getState().authentication.token,
}),
},
});
νΈμ§νλ€:
μ€ μ κΉ, μ΄κ²μ μ²μ μ΄νμ νΈμΆλμ§ μμ΅λλ€... onOperation
μλ² μΈ‘μΌλ‘ ꡬ문 λΆμν μ μλ μλ΅μ μΈμ¦ κ°μ²΄λ₯Ό λ£λ λ€λ₯Έ λ―Έλ€μ¨μ΄μ μ°κ²°λ μ μμ΅λκΉ?
λ€μμ λ΄κ° ApolloClient V1μμ νλ λ°©μμ λͺ¨λΈλ‘ νμ¬ μ€λΉν κ²μ λλ€.
νμ΄λ‘λμ μΈμ¦ ν ν°μ 첨λΆνλ μ λ§ν¬ λ―Έλ€μ¨μ΄ μΆκ°
const authMiddleware = new ApolloLink((operation, forward) => {
// Add the authorization to the headers for HTTP authentication
operation.setContext({
headers: {
authorization: `Bearer ${authToken()}`,
},
});
// Add onto payload for WebSocket authentication
(operation as Operation & { authToken: string | undefined }).authToken = authToken();
return (forward as any)(operation);
});
const myLink = concat(myLink, wsLink);
κ·Έλ° λ€μ μλ² μΈ‘μμ νμΈνκ³ onOperation νν¬λ₯Ό μ¬μ©νμ¬ μ»¨ν μ€νΈμ μ μ©ν μ μμ΅λλ€.
function configureDecodeTokenSocketMiddleware(authURL: string) {
return async function decodeTokenSocketMiddleware<ConnectionParams extends { authToken: string }>(connectionParams: ConnectionParams, operationParams: object) {
let authPayload;
try {
if (typeof connectionParams.authToken === 'string') {
authPayload = await verifyJWT(authURL, connectionParams.authToken);
} else {
throw new Error('Auth Token not available');
}
} catch(e) {
authPayload = {};
}
return {
...operationParams,
context: {
authentication: authPayload,
},
};
};
}
new SubscriptionServer({
execute,
subscribe,
schema,
onOperation: configureDecodeTokenSocketMiddleware(appConfig.authURL),
}, {
server: appConfig.server,
path: `/${appConfig.subscriptionsEndpoint}`,
});
μ΄μ©λ©΄ μ΄ λ©μμ§λ₯Ό λ€μ λ³΄λΌ μ μμ΅λλ€. https://github.com/apollographql/subscriptions-transport-ws/blob/master/src/client.ts#L507
const payload: ConnectionParams = typeof this.connectionParams === 'function' ? this.connectionParams() : this.connectionParams;
this.sendMessage(undefined, MessageTypes.GQL_CONNECTION_INIT, payload);
μ΄ μμ μ μννλ λ° κΆμ₯λλ λ°©λ²μ΄ μμ΅λκΉ?
ꡬλ μ΄ λ¬Έμ
μλ‘μ΄ WebSocketLink
λ μ¬μ ν subscriptions-transport-ws
μ μΈμ€ν΄μ€λ₯Ό μμ±νλ―λ‘ WebSocketLinkκ° μλ Subscription Transport ν΄λΌμ΄μΈνΈμ λ―Έλ€μ¨μ΄λ₯Ό μλμΌλ‘ μ μ©νκ³ μμ΅λλ€.
v1μμμ λμΌν νλ‘μΈμ€λ₯Ό μ¬μ©νκ³ μμ§λ§ WebSocketLink APIμ μΌλΆλ‘ ν¬ν¨νμ§ μλ κ²μ΄ λ€μ ν΄μ»€μ²λΌ λκ»΄μ§λλ€.
// create the web socket link
const wsLink = new WebSocketLink({
uri: 'ws://example.com',
options: {
reconnect: true
}
})
// create my middleware using the applyMiddleware method from subscriptions-transport-ws
const subscriptionMiddleware = {
applyMiddleware (options, next) {
options.auth = { ... }
next()
}
}
// add the middleware to the web socket link via the Subscription Transport client
wsLink.subscriptionClient.use([subscriptionMiddleware])
μ΅μ
κ°μ²΄μ μΆκ°νλ λͺ¨λ κ°μ μλ² μΈ‘μ onOperation
μ½λ°±μμ μ¬μ©ν μ μμ΅λλ€.
λνμ΄ λ¬Έμ κ°
@jbaxleyiii μ΄λ€ μκ°μ΄ μμ΅λκΉ?
λͺ μ£Ό μ μ μ루μ (? μ κ²½μ°μλ μλ μ€μ λλ€)μ λ§λ€μμ΅λλ€.
GraphQLModule
app.module.ts
κ°μ Έμμ΅λλ€.
import { HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
import { Apollo, ApolloModule } from 'apollo-angular';
import { HttpLinkModule } from 'apollo-angular-link-http';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { WebSocketLink } from 'apollo-link-ws';
import { SubscriptionClient } from 'subscriptions-transport-ws';
@NgModule({
exports: [
ApolloModule,
HttpClientModule,
HttpLinkModule
]
})
export class GraphQLModule {
public subscriptionClient: SubscriptionClient = null;
constructor(apollo: Apollo) {
const wssEndpoint = 'wss://your-domain.com/subscriptions';
// It's required to define connectionParams as function, as otherwise the updated token is not transferred
const connectionParams = () => {
const token = sessionStorage.getItem('token');
return token ? { 'Authorization': 'token ' + token } : {};
};
const wsLink = new WebSocketLink({
uri: wssEndpoint,
options: {
connectionParams: connectionParams,
reconnect: true
}
});
this.subscriptionClient = (<any>wsLink).subscriptionClient;
const cache = new InMemoryCache({});
apollo.create({
link: wsLink,
cache: cache.restore(window[ '__APOLLO_CLIENT__' ]),
connectToDevTools: true,
queryDeduplication: true
});
}
}
λ΄ μΈμ¦ μλΉμ€μμ private graphQLModule: GraphQLModule
λ₯Ό ν΅ν΄ μμ±μμ μ΄ λͺ¨λμ μ£Όμ
νκ³ μμ΅λλ€.
λ‘κ·ΈμΈ λλ λ‘κ·Έμμ ν λ€μ μμ
μ μνν©λλ€.
const client = this.graphQLModule.subscriptionClient;
// Close actual connection
client.close(true, true);
// todo: set/unset session token in sessionStorage
// Connect again
(<any>client).connect();
μ΄λ κ² νλ©΄ μ± μμ μ ꡬλ ν΄λΌμ΄μΈνΈκ° μ΄λ¦¬κ³ λ‘κ·ΈμΈ/λ‘κ·Έμμ μ μμ ν λ€μ μ΄κΈ°νλ©λλ€.
μ΄μμ μΌλ‘ μ΄κ²μ μ°λ¦¬κ° ν μ μλ ν ν°μ λΉλκΈ°μμΌλ‘ κ°μ ΈμμΌ νλ κ²½μ°μλ ν¨μλ₯Ό λ°ννλ μ½μμ μ§μν©λλ€.
@clayne11 νμ€νμ§ μμ΅λλ€. React-Nativeμ AsyncStorageλ₯Ό connectionParamsλ‘ μ¬μ©νλ €κ³ ν©λλ€. κ·Έλ¬λ λ΄κ° μΆκ°ν λΉλκΈ° λλ¬Έμ μλ²μ μ μλμ§ μμ μνλ‘ κ³μ 보λ
λλ€.
λ¬Έμ κ° μμ΅λκΉ?
μ
λ°μ΄νΈ:
μ΄ λ¬Έμ λ₯Ό ν΄κ²°νμ§λ§ μμ§ λ§μ€ν° λΈλμΉμ λ³ν©λμ§ μμ ν μμ² μ΄ μμ΅λλ€.
@jonathanheilmann , κ·νμ μ루μ
μ @helios1138 μλ ν΄κ²° λ°©λ²κ³Ό μ μ¬ν©λλ€. κ·Έλ¬λ ꡬλ
ν΄λΌμ΄μΈνΈμ λν connect()
APIλ λΉκ³΅κ°λ‘ νμλλ©° μ΄μμ μΌλ‘λ μ¬μ©νμ§ μμμΌ ν©λλ€.
κ³΅κ° APIμ΄κ³ κ°μ λ‘ λ€μ μ°κ²°ν΄μΌ νλ subscriptionClient.close(false, false)
λ₯Ό μλνμ§λ§ μλνμ§λ§ μ¬μ ν ꡬλ
μ΄ μλνμ§ μμ΅λλ€. νμ¬ μλνλ μ μΌν κ²μ λ€μκ³Ό κ°μ΅λλ€.
subscriptionClient.close();
subscriptionClient.connect(); // this is a private API :-(
μ΄μ λν μλ‘μ΄ μμ΄λμ΄κ° μμ΅λκΉ? μ¬κΈ°μ μ루μ μ΄ μλ κ²μ μ’μν©λλ€. λ‘λν λ λ΄ apollo λ§ν¬λ₯Ό μμ±νμ§λ§ μΌλ¨ λ΄ μ¬μ©μκ° idμ λ‘κ·ΈμΈνλ©΄ 컨ν μ€νΈμμ μ μ‘λλ ν ν°μ μ λ°μ΄νΈνλ κ²μ μ λ§ μ’μν©λλ€.
μ΄κ²μ΄ μ°λ¦¬κ° μκ°ν΄λΌ μ μλ μ΅κ³ μ μ루μ μ λλ€: https://github.com/apollographql/apollo-server/issues/1505.
context
λ λͺ¨λ μμ
μμ μμ±λλ©° μ¬μ©μλ₯Ό λμ μΌλ‘ μ‘°ννκΈ°λ§ νλ©΄ λ©λλ€.
μ΄κ²μ λμκ² λμμ΄λμμ΅λλ€.
https://github.com/apollographql/apollo-link/issues/446#issuecomment -410073779
μΉ μμΌ μ±λμ΄ μ΄λ¦¬λ©΄(Authorization ν€λ = ν ν° AAA ν¬ν¨) μΉ μμΌ λ§ν¬λ₯Ό μ¬μ©νλ κ° νμ μμ²μ νμ AAA ν ν°μΌλ‘ μλ³λ©λλ€.
λλ κ° μμ²μ λν΄ λ€λ₯Έ Authorization ν€λλ₯Ό 보λ΄λ λ°©λ²μ΄ μμ΅λκΉ(λ€λ₯Έ ws μ±λμ λ€μ μ¬λ κ² μ μΈ)?
wsμ λν μ μμ€ νλ‘ν μ½μμ λ¬΄μ¨ μΌμ΄ μΌμ΄λκ³ μλμ§ μ΄ν΄νκ³ μΆμ΅λλ€.
λ΅μ₯ν΄μ£Όμ μ κ°μ¬ν©λλ€!
μ¬κΈ°κΉμ§ λ΄ μ½λκ° μμ΅λλ€(νλμ ν ν°μΌλ‘ μ¬λ°λ₯΄κ² μλν¨).
const wsClient = new SubscriptionClient(
graphqlEndpoint,
{
reconnect: true,
connectionParams: () => ({
headers: {
'Authorization': 'mytokenAAA',
},
}),
},
ws,
);
const link = new WebSocketLink(wsClient);
makePromise(execute(link, options)); // that's using token AAA
// how to make another query (execute) using token BBB without creating another link ?
@sulliwane @RyannGalea @jonathanheilmann @helios1138 ν ν°/μ°κ²° 맀κ°λ³μλ₯Ό λμ μΌλ‘ μ λ°μ΄νΈνλ €λ©΄ SubscriptionClientμ λ―Έλ€μ¨μ΄λ₯Ό μ¬μ©νμ¬ μ€μ ν΄μΌ ν©λλ€. μ¬κΈ°μμ λ΄ μμ μ μ°Έμ‘°νμμμ€. https://gist.github.com/cowlicks/71e766164647f224bf15f086ea34fa52
const subscriptionMiddleware = {
applyMiddleware: function(options, next) {
// Get the current context
const context = options.getContext();
// set it on the `options` which will be passed to the websocket with Apollo
// Server it becomes: `ApolloServer({contetx: ({payload}) => (returns options)
options.authorization = context.authorization;
next()
},
};
const server = new ApolloServer({
context: ({connection, payload, req}) => {
// whatever you return here can be accessed from the middleware of the SubscriptionMiddleware with
// applyMiddleware: (options, next) => options.getContext()
return {authorization: payload.authorization};
},
});
const link = new WebSocketLink({
uri: WS_URL,
webSocketImpl: WebSocket,
options: {
reconnect: true,
}
});
link.subscriptionClient.use([subscriptionMiddleware]);
λ΄κ° μ°Ύμ μ μΌν ν΄κ²°μ± μ ν΄λΌμ΄μΈνΈλ₯Ό μλμΌλ‘ λ«λ κ²μ λλ€ ...
λλ 1.5λ μ μ ν΄κ²°μ± μ κ²μνμ΅λλ€: apollographql/apollo-server#1505. AFAIK μ΄κ²μ μ¬μ ν ββμλν©λλ€.
@clayne11 κ·νμ μ루μ μ λ―Έλ€μ¨μ΄λ₯Ό μ¬μ©νλ κ²μ μλ―Έν©λλ€. νλ₯νλ€κ³ μκ°νμ§λ§ Angular λ° Yoga-Graphqlλ‘ μμ νκ³ μ μ μλ μ΄μ λ‘ μ»¨ν μ€νΈλ₯Ό ν΅ν΄ ν ν°μ λ³΄λΌ μ μμ΅λλ€.
μλ²μ λ―Έλ€μ¨μ΄μ μλ ν ν°μ μ κ·Όν μ μλ λ°©λ²μ΄ μλμ?
λλ Yogaλ₯Ό μ¬μ©νκ³ μμΌλ©° μ΄κ²μ΄ 컨ν
μ€νΈμμ ν ν°μ μ‘μΈμ€νλ λ°©λ²μ
λλ€.
const server = new GraphQLServer({
typeDefs: './src/schema.graphql',
middlewares: [permissions],
resolvers,
context: ({ connection, ...request }) => {
if(connection) {
wsToken: connection.context.authToken
}
}
return ({...request, prisma });
}
});
const options = {
port: process.env.PORT || 4000,
tracing: true,
subscriptions: {
path: "/",
onConnect: async (connectionParams, webSocket) => {
if (connectionParams.authToken) {
// I can access this through context
return {
authToken: connectionParams.authToken
};
}
}
}
};
server.express.use(async (req, res, next) => {
/*
I want to access authToken here
*/
next();
});
server.start(options, ({port}) => {
console.log(`Server is runnning on http://localhost:${port}`);
});
μμΌμ λ«μ§ μκ³ μ¬λ¬ κ°μ§ ν΄λ‘ λ€νΈμν¬ μ€λ₯κ° λ°μν©λλ€ reconnect: true
μ¬μ°κ²°μ 보μ₯ν©λλ€... μμΌμ΄ ν λ²λ§ λ«νλ 무ν 루νμμ μ¬μ°κ²°λλ€λ μ λ§ μ μΈνλ©΄ π
νΈμ§: $ SubscriptionClient.close()
SubscriptionClient.client.close()
λ₯Ό νΈμΆνμ¬ μμ νμ΅λλ€. .... π€
5κ°μ 23κ°μ μ’μμκ° μλ 100κ°μ ν©μ΄μ Έ μλ μΈλ―Έ μ루μ λμ μ ν ν°μΌλ‘ λ€μ μ°κ²°νλ μμ ν ν΄λΌμ΄μΈνΈ λ° μλ² μμ κ° μμ΅λκΉ?
apolloServer.installSubscriptionHandlers(server);
μ κ°μ ꡬλ
μ μ€μΉν©λλ€.
κ·Έλ¦¬κ³ ApolloServerλ₯Ό μμ±ν©λλ€.
const apolloServer = new ApolloServer({
schema,
introspection: true,
subscriptions: {
onConnect: (connectionParams, webSocket, context) => {
},
onDisconnect: (webSocket, context) => {},
...there is no OnOperation: () => {}!!!
},
onOperationμ μΆκ°νλ λ€λ₯Έ λ°©λ²μ΄ μμ΅λκΉ? μλλ©΄ μλμΌλ‘ SubscriptionServerλ₯Ό μμ±νκ³ apolloServer.installSubscriptionHandlers(server)
λ₯Ό μ¬μ©νμ§ μμμΌ ν©λκΉ?
κ²°κ΅ ν΄λΌμ΄μΈνΈλ₯Ό λμ μΌλ‘ μμ±νμ΅λλ€. μ¬μ©μκ° λ‘κ·ΈμΈνμ§ μμ κ²½μ° ν΄λΌμ΄μΈνΈλ new WebSocket
λ§ν¬λ₯Ό μμ±νμ§ μκ³ κ·Έλ μ§ μμΌλ©΄ μμ±ν©λλ€. μλμ generateApolloClient
ν¨μλ SubscriptionClient
λ λ
ΈμΆνλ―λ‘ μ°κ²°λμμ λ λμ€ν¨μΉ νΈμΆμ μΆκ°ν μ μμ΅λλ€(μ: redux storeμ websocketμ΄ μ°κ²°λμμμ μ립λλ€).
/**
* Http link
*/
const httpLink = new HttpLink({
uri: '/graphql'
});
/**
* Perform actions before each http request
*/
const middlewareLink = new ApolloLink((operation, forward) => {
operation.setContext({
headers: {
authorization: localStorage.getItem('token')
}
});
return forward(operation);
});
const cache = new InMemoryCache();
type ApolloSubscriptionClient<TLoggedIn extends boolean> = TLoggedIn extends true ? SubscriptionClient : undefined;
/**
* Function to create our apollo client. After login we want to add subscriptions
* with websocket, so we'll need to recreate the entire client depending on the
* user being logged in or logged out.
*/
export const generateApolloClient = <TLoggedIn extends boolean>(
loggedIn: TLoggedIn
): [ApolloClient<NormalizedCacheObject>, ApolloSubscriptionClient<TLoggedIn>] => {
let link = middlewareLink.concat(httpLink);
// Only apply our subscription client when the user is logged in
let subscriptionClient: SubscriptionClient | undefined;
if (loggedIn) {
subscriptionClient = new SubscriptionClient('ws://localhost:4001/graphql/ws', {
reconnect: true,
connectionParams: () => ({ authorization: localStorage.getItem('token') })
});
const wsLink = new WebSocketLink(subscriptionClient);
link = split(
({ query }) => {
const definition = getMainDefinition(query);
return (
definition.kind === 'OperationDefinition' &&
definition.operation === 'subscription'
);
},
wsLink,
link
);
}
const apolloClient = new ApolloClient({ link, cache });
return [apolloClient, subscriptionClient as ApolloSubscriptionClient<TLoggedIn>];
};
generateApolloClient
ApolloProvider
κ΅¬μ± μμμ μ½λλ λ€μκ³Ό κ°μ΅λλ€.
const GraphqlProvider: React.FC = ({ children }) => {
const dispatch = useAppDispatch();
const loggedIn = useUserLoggedIn();
const [client, setClient] = useState(generateApolloClient(false)[0]);
useEffect(() => {
if (loggedIn) {
const [apolloClient, subscriptionClient] = generateApolloClient(loggedIn);
subscriptionClient.onConnected(() => {
dispatch(setSubscriptionConnected(true));
})
setClient(apolloClient);
}
}, [dispatch, loggedIn]);
return <ApolloProvider client={client}>{children}</ApolloProvider>;
};
μ΄κ²μ μ μλνκ³ μ¬μ©μκ° λ‘κ·Έμμνλ€κ° λ€μ λ‘κ·ΈμΈν λλ§λ€ μλ²μ μ ν ν°μ΄ νμλμ§λ§ μ½κ°μ μΆκ° μμ μ²λΌ 보μ λλ€. μκ°?
@dorsett85 λ΅λ³ κΈ°λ° React/NextJS μ±μ© ν΄λΌμ΄μΈνΈλ₯Ό μλ‘ κ³ μΉλ €λ©΄ λ°μ 컨ν μ€νΈ APIλ₯Ό μ¬μ©νλ κ²μ΄ μ’μ΅λλ€.
----------- 컨ν μ€νΈ API
export const ApolloClientContext = createContext(undefined);
export const ApolloClientContextProvider: React.FC<{}> = ({ children }) => {
const [apolloClient, setApolloClient] = useState(client);
return (
<ApolloClientContext.Provider value={[apolloClient, setApolloClient]}>{children}</ApolloClientContext.Provider>
);
};
------ μν΄λ‘ 곡κΈμ
<ApolloClientContextProvider>
<ApolloClientContext.Consumer>
{([apolloClient, setApolloClient]) => {
return (
<ApolloProvider client={apolloClient}>
<Component {...pageProps} />
</ApolloProvider>
);
}}
</ApolloClientContext.Consumer>
</ApolloClientContextProvider>
-------- μΈμ¦μΌλ‘ μ ν΄λΌμ΄μΈνΈλ₯Ό μμ±νλ μ νΈλ¦¬ν° ν¨μ
export const generateApolloClientWithAuth = (token): ApolloClient<any> => {
const httpLink = createHttpLink({
uri: 'http://localhost:5000/graphql',
fetch,
credentials: 'include'
});
const wsLink = process.browser
? new WebSocketLink({
uri: `ws://localhost:5000/graphql`,
options: {
reconnect: true,
connectionParams() {
console.log('-token', token);
return {
authorization: token ? `Bearer ${token}` : ''
};
}
}
})
: null;
const splitLink = process.browser
? split(
({ query }) => {
const definition = getMainDefinition(query);
return definition.kind === 'OperationDefinition' && definition.operation === 'subscription';
},
wsLink,
httpLink
)
: httpLink;
return new ApolloClient({
ssrMode: true,
link: splitLink,
connectToDevTools: process.env.NODE_ENV === 'development',
cache: new InMemoryCache().restore({})
});
};
---------- λ‘κ·ΈμΈ κ΅¬μ± μμ
const [apolloClient, setApolloClient] = useContext(ApolloClientContext);
----------- λ‘κ·ΈμΈ μ
setApolloClient(generateApolloClientWithAuth(token));
μ€μ μ°Έκ³ μ¬ν: μ 곡λ Apollo ν΄λΌμ΄μΈνΈ μ½λλ SSRμ μ¬μ©ν©λλ€.
@kamilkisiela wsLink.subscriptionClient
νμμ κ³΅κ° νμμΌλ‘ λ§λ€ μ μλμ? λ°κΏμΌ ν κ² κ°μ§λ μμ£ ?
get
λ₯Ό μ¬μ©νμ¬ λ§μ§λ§ κ°μ κ°μ Έμ΅λλ€.
const wsLink = new WebSocketLink({
uri: CLIENT_CONFIG.websocketUrl,
options: {
lazy: true,
reconnect: true,
connectionParams: {
get authorization() {
return user.getAuthorization();
},
},
connectionCallback: (error) => {
//@ts-ignore
if (error?.message === "Authentication Failure!") {
//@ts-ignore
//wsLink.subscriptionClient.close(false, false);
}
},
},
});
λ΄κ° μ΄κ²μ΄ ν¨κ³Όκ° μλ€κ³ λ§νλ©΄ μ무λ λλ₯Ό λ―Ώκ² μ΅λκΉ?
const wsLink = process.browser
? new WebSocketLink({
uri: webSocketUri,
options: {
reconnect: true,
connectionParams: () => ({
token: cookie.get('token'),
}),
},
})
: null;
μ¦
λ³κ²½:
connectionParams: {
token: cookie.get('token'),
},
μκ²:
connectionParams: () => ({
token: cookie.get('token'),
}),
κ°μ₯ μ μ©ν λκΈ
μλ‘μ΄
WebSocketLink
λ μ¬μ νsubscriptions-transport-ws
μ μΈμ€ν΄μ€λ₯Ό μμ±νλ―λ‘ WebSocketLinkκ° μλ Subscription Transport ν΄λΌμ΄μΈνΈμ λ―Έλ€μ¨μ΄λ₯Ό μλμΌλ‘ μ μ©νκ³ μμ΅λλ€.v1μμμ λμΌν νλ‘μΈμ€λ₯Ό μ¬μ©νκ³ μμ§λ§ WebSocketLink APIμ μΌλΆλ‘ ν¬ν¨νμ§ μλ κ²μ΄ λ€μ ν΄μ»€μ²λΌ λκ»΄μ§λλ€.
μ΅μ κ°μ²΄μ μΆκ°νλ λͺ¨λ κ°μ μλ² μΈ‘μ
onOperation
μ½λ°±μμ μ¬μ©ν μ μμ΅λλ€.