Audio latency spikes then connection dies when calling Cognigy from AppFoundry widget. The socket closes with code 1006 right after the POST to /nlp/interact. Here is the setup:
const ws = new WebSocket(`wss://${host}/ws`);
ws.onopen = () => fetch('/cognigy/endpoint'); // drops here
No error logs in console. Just silent disconnect.
Socket 1006 is usually a timeout, not a protocol error. You’re blocking the main thread with that fetch call, so the heartbeat stops. Switch to an async worker thread for the NLP request to keep the WebSocket alive.
is spot on about the main thread blocking, but in the Embeddable Client App SDK context, it’s rarely just about “moving it to a worker” in the traditional browser sense. The SDK’s event loop handles the WebSocket heartbeat, and if you’re doing a synchronous-looking fetch or a heavy blocking operation in your widget’s render cycle, you starve that loop.
The issue with ws.onopen = () => fetch(...) is that you’re chaining the network request directly to the socket open event without awaiting or detaching it. If that fetch hangs or the Cognigy endpoint is slow, the JavaScript execution context pauses, and the SDK’s internal ping/pong mechanism misses its window. Code 1006 is the browser saying “the connection died unexpectedly,” which is exactly what happens when the heartbeat drops.
Here’s how I usually structure this in a React-based widget to keep the socket breathing:
// Don't block the onopen handler
ws.onopen = () => {
console.log('Socket connected');
// Fire and forget, but handle errors gracefully
fetchNlpData().catch(err => {
console.error('NLP fetch failed, socket still alive:', err);
});
};
async function fetchNlpData() {
try {
const response = await fetch('/cognigy/endpoint', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ input: "test" })
});
// Process response
const data = await response.json();
updateWidgetState(data);
} catch (error) {
// Ensure the socket isn't closed here
if (ws.readyState === WebSocket.OPEN) {
console.log('Socket intact after error');
}
}
}
You’ll want to ensure the fetch doesn’t throw an unhandled exception that might crash your widget’s lifecycle. Also, check if you’re sending large payloads; sometimes the NLP call itself is timing out, not the socket. Keep the fetch lean.
That fetch call is blocking the event loop. Wrap it in a promise or move it to a web worker so the WebSocket heartbeat doesn’t time out.
ws.onopen = () => {
Promise.resolve().then(() => fetch('/cognigy/endpoint'));
};