To resolve the issue, connection keep-alive must be implemented:
- Add httpAgents.js with the following content to the application:
const http = require("http");
const https = require("https");
const keepAliveConfig = {
maxSockets: 200,
maxFreeSockets: 20,
timeout: 240 * 1000,
freeSocketTimeout: 240 * 1000,
};
const httpAgent = new keepAlive(keepAliveConfig);
const httpsAgent = new keepAlive.HttpsAgent(keepAliveConfig);
module.exports = {
setUpDefaultAgents: (serverBundle) => {
http.globalAgent = httpAgent;
https.globalAgent = httpsAgent;
if (serverBundle.setUpDefaultAgents) {
serverBundle.setUpDefaultAgents(httpAgent, httpsAgent);
}
},
/**
* Enable connection pooling. Adds `connection: keep-alive` header
* @param {string} url api host
*/
getAgent: (url) => {
if (!url) {
throw new Error("[KEEP-ALIVE-CONFIG] SITECORE_API_HOST value is required, but was undefined")
}
if (!url.indexOf("http://")) return httpAgent;
if (!url.indexOf("https://")) return httpsAgent;
throw new Error(
"[KEEP-ALIVE-CONFIG] Unexpected SITECORE_API_HOST value, expected http:// or https://, but was " +
url
);
},
};
…
- Make changes to config.js of the proxy application:
…
const NodeCache = require('node-cache');
const httpAgents = require("./httpAgents");
…
const serverBundle = require(bundlePath);
httpAgents.setUpDefaultAgents(serverBundle);
…
proxyOptions: {
// Enable connection pooling
agent: httpAgents.getAgent(apiHost),
// Setting this to false will disable SSL certificate validation
// when proxying to a SSL Sitecore instance.
// This is a major security issue, so NEVER EVER set this to false
// outside local development. Use a real CA-issued certificate.
secure: true,
headers: {
"accept-encoding": "gzip, deflate"
},
xfwd: true
},
…
return fetch(
`${config.apiHost}/sitecore/api/jss/dictionary/${appName}/${language}?sc_apikey=${
config.apiKey
}`,
{
headers: {
connection: "keep-alive",
},
}
)
- Make changes to the server.js of your application:
…
import Helmet from 'react-helmet';
import axios from "axios";
import http from "http";
import https from "https";
…
// Setup Http/Https agents for keep-alive. Used in headless-proxy
export const setUpDefaultAgents = (httpAgent, httpsAgent) => {
axios.defaults.httpAgent = httpAgent;
axios.defaults.httpsAgent = httpsAgent;
http.globalAgent = httpAgent;
https.globalAgent = httpsAgent;
};
- Make changes to the GraphQLClientFactory.js:
const link = createPersistedQueryLink().concat(
new BatchHttpLink({
uri: endpoint,
credentials: 'include',
headers: {
connection: "keep-alive"
}
})
Note that currently there is a limitation for usage of "proxyOptions.onProxyReq". Using "onProxyReq" with "keep-alive" can cause the server to crash. You can add custom middleware where you can modify the request before proxying to contain the values you wish to proxy:
server.use((req, res, next) => {
// set dynamic headers here
next();
});
For more details, refer to the following useful links: