feat: pass down options/settings for ws

This commit is contained in:
Siddharth Gelera
2025-09-15 15:12:38 +05:30
parent e08341d704
commit c473755593
8 changed files with 35 additions and 103 deletions

View File

@@ -24,17 +24,7 @@ const WSSettingsPane = ({ item, collection }) => {
const dispatch = useDispatch();
const { storedTheme, theme } = useTheme();
const { keepAlive, connectionTimeout, keepAliveInterval } = getPropertyFromDraftOrRequest('settings', item);
const onToggleKeepAlive = () => {
dispatch(
updateItemSettings({
collectionUid: collection.uid,
itemUid: item.uid,
settings: { keepAlive: !keepAlive }
})
);
};
const { connectionTimeout, keepAliveInterval } = getPropertyFromDraftOrRequest('settings', item);
const onChangeConnectionTimeout = (val) => {
dispatch(
@@ -67,9 +57,7 @@ const WSSettingsPane = ({ item, collection }) => {
content={
<div>
<p>
<span>
Timeout in milliseconds
</span>
<span>Timeout in milliseconds</span>
</p>
</div>
}
@@ -98,9 +86,7 @@ const WSSettingsPane = ({ item, collection }) => {
Keep the websocket alive by sending ping requests to the server at every interval (in millseconds)
</span>
</p>
<p className="mt-2">
0 (zero) = off
</p>
<p className="mt-2">0 (zero) = off</p>
</div>
}
/>
@@ -116,76 +102,6 @@ const WSSettingsPane = ({ item, collection }) => {
</div>
</div>
</section>
{/* Variation 2 */}
{/* <Accordion>
<Accordion.Item className="!border-0">
<Accordion.Header
style={{
paddingLeft: 0,
paddingRight: 0
}}
>
<div className="flex justify-between">
<label className="font-medium">Keep Alive</label>
<ToggleSelector
checked={keepAlive}
onChange={(e) => {
e.preventDefault();
e.stopPropagation();
onToggleKeepAlive();
}}
size="medium"
/>
</div>
</Accordion.Header>
<Accordion.Content>
<div>
<label className="flex font-medium mb-2">Keep Alive Interval (ms)</label>
<div className="flex-1 w-1/2 single-line-editor-wrapper">
<SingleLineEditor
value={keepAliveInterval}
theme={storedTheme}
onChange={(newValue) => onChangeKeepAliveInterval(newValue)}
collection={collection}
/>
</div>
</div>
</Accordion.Content>
</Accordion.Item>
</Accordion> */}
{/* Variation 3 */}
{/* <section>
<div className="flex justify-between">
<label className="font-medium">Keep Alive</label>
<ToggleSelector
checked={keepAlive}
onChange={(e) => {
onToggleKeepAlive();
}}
size="medium"
/>
</div>
{keepAlive ? (
<>
<div className="border-t border-neutral-200 my-2"></div>
<div className="p-2">
<div>
<label className="flex font-medium mb-2">Keep Alive Interval (ms)</label>
<div className="flex-1 w-1/2 single-line-editor-wrapper">
<SingleLineEditor
value={keepAliveInterval}
theme={storedTheme}
onChange={(newValue) => onChangeKeepAliveInterval(newValue)}
collection={collection}
/>
</div>
</div>
</div>
</>
) : null}
</section> */}
</StyledWrapper>
);
};

View File

@@ -20,6 +20,10 @@ const StyledWrapper = styled.div`
}
}
.method-ws {
color: ${(props) => props.theme.request.ws};
}
.connection-status-strip {
animation: pulse 1.5s ease-in-out infinite;
background-color: ${(props) => props.theme.colors.text.green};

View File

@@ -82,8 +82,10 @@ const WsQueryUrl = ({ item, collection, handleRun }) => {
return (
<StyledWrapper>
<div className="flex items-center h-full">
<div className="flex items-center input-container flex-1 w-full input-container h-full relative">
<IconWebSocket size={20} strokeWidth={2} className="ml-2 mr-4" />
<div className="flex items-center input-container flex-1 w-full input-container pr-2 h-full relative">
<div className="flex items-center justify-center w-16">
<span className="text-xs font-bold method-ws">WS</span>
</div>
<SingleLineEditor
value={url}
onSave={(finalValue) => onSave(finalValue)}

View File

@@ -252,13 +252,15 @@ export const startWsConnection = async (item, collection, environment, runtimeVa
return new Promise((resolve, reject) => {
const { ipcRenderer } = window;
const request = item.draft ? item.draft : item;
const settings = item.draft ? item.draft.settings : item.settings
ipcRenderer
.invoke('ws:start-connection', {
request,
collection,
environment,
runtimeVariables
runtimeVariables,
settings
})
.then(() => {
resolve();

View File

@@ -277,7 +277,7 @@ const registerWsEventHandlers = (window) => {
});
// Start a new WebSocket connection
ipcMain.handle('ws:start-connection', async (event, { request, collection, environment, runtimeVariables }) => {
ipcMain.handle('ws:start-connection', async (event, { request, collection, environment, runtimeVariables,settings }) => {
try {
const requestCopy = cloneDeep(request);
const preparedRequest = await prepareWsRequest(requestCopy, collection, environment, runtimeVariables, {});
@@ -295,8 +295,9 @@ const registerWsEventHandlers = (window) => {
request: preparedRequest,
collection,
options: {
timeout: 30000,
keepAlive: true
timeout: settings.connectionTimeout,
keepAlive: settings.keepAliveInterval > 0 ? true : false,
keepAliveInterval: settings.keepAliveInterval
}
});

View File

@@ -427,7 +427,7 @@ const sem = grammar.createSemantics().addAttribute('ast', {
const getNumFromRecord = createGetNumFromRecord(settings);
const keepAliveInterval = getNumFromRecord('keepAliveInterval', {
fallback: 10000
fallback: 0
});
const connectionTimeout = getNumFromRecord('connectionTimeout', {
fallback: 250
@@ -436,7 +436,6 @@ const sem = grammar.createSemantics().addAttribute('ast', {
return {
settings: {
encodeUrl: typeof settings.encodeUrl === 'boolean' ? settings.encodeUrl : settings.encodeUrl === 'true',
keepAlive: typeof settings.keepAlive === 'boolean' ? settings.keepAlive : settings.keepAlive === 'true',
keepAliveInterval,
connectionTimeout
}

View File

@@ -82,6 +82,7 @@ const getParsedWsUrlObject = (url) => {
class WsClient {
constructor(eventCallback) {
this.activeConnections = new Map();
this.connectionKeepAlive = new Map();
this.eventCallback = eventCallback;
}
@@ -94,7 +95,7 @@ class WsClient {
*/
async startConnection({ request, collection, options = {} }) {
const { url, headers = [] } = request;
const { timeout = 30000, keepAlive = true } = options;
const { timeout = 30000, keepAlive = false, keepAliveInterval = 10_000 } = options;
const parsedUrl = getParsedWsUrlObject(url);
const processedHeaders = processWsHeaders(headers);
@@ -122,6 +123,14 @@ class WsClient {
headers: processedHeaders,
timestamp: Date.now()
});
if (keepAlive) {
const handle = setInterval(() => {
wsConnection.isAlive = false;
wsConnection.ping();
}, keepAliveInterval);
this.connectionKeepAlive.set(requestId, handle);
}
} catch (error) {
console.error('Error creating WebSocket connection:', error);
this.eventCallback('ws:error', requestId, collectionUid, {
@@ -304,6 +313,10 @@ class WsClient {
* @private
*/
#removeConnection(requestId) {
if (this.connectionKeepAlive.has(requestId)) {
clearInterval(this.connectionKeepAlive.get(requestId));
this.connectionKeepAlive.delete(requestId)
}
if (this.activeConnections.has(requestId)) {
this.activeConnections.delete(requestId);

View File

@@ -420,14 +420,9 @@ const wsRequestSchema = Yup.object({
const wsSettingsSchema = Yup.object({
settings: Yup.object({
connectionTimeout: Yup.number()
.default(1000)
.min(250),
keepAlive: Yup.boolean().default(false),
.default(500),
keepAliveInterval: Yup.number()
.default(10000)
.min(500)
// max 2 minutes
.max(2 * 60 * 1000),
.default(0)
}).noUnknown(true)
.strict()
.nullable()