Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changeset/old-readers-battle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'@rocket.chat/core-typings': patch
'@rocket.chat/ui-voip': patch
'@rocket.chat/i18n': patch
'@rocket.chat/meteor': patch
---

Fixes an issue where Voice Calls were unable to gather Ice Servers
21 changes: 21 additions & 0 deletions apps/meteor/ee/server/settings/voip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ export function addSettings(): Promise<void> {
modules: ['teams-voip'],
},
async function () {
const enableQuery = { _id: 'VoIP_TeamCollab_Enabled', value: true };

await this.add('VoIP_TeamCollab_Enabled', false, {
type: 'boolean',
public: true,
Expand All @@ -19,30 +21,49 @@ export function addSettings(): Promise<void> {
type: 'string',
public: true,
invalidValue: '',
enableQuery,
});

await this.add('VoIP_TeamCollab_FreeSwitch_Port', 8021, {
type: 'int',
public: true,
invalidValue: 8021,
enableQuery,
});

await this.add('VoIP_TeamCollab_FreeSwitch_Password', '', {
type: 'password',
secret: true,
invalidValue: '',
enableQuery,
});

await this.add('VoIP_TeamCollab_FreeSwitch_Timeout', 3000, {
type: 'int',
public: true,
invalidValue: 3000,
enableQuery,
});

await this.add('VoIP_TeamCollab_FreeSwitch_WebSocket_Path', '', {
type: 'string',
public: true,
invalidValue: '',
enableQuery,
});

await this.add('VoIP_TeamCollab_Ice_Servers', 'stun:stun.l.google.com:19302', {
type: 'string',
public: true,
invalidValue: '',
enableQuery,
});

await this.add('VoIP_TeamCollab_Ice_Gathering_Timeout', 5000, {
type: 'int',
public: true,
invalidValue: 5000,
enableQuery,
});
},
);
Expand Down
6 changes: 6 additions & 0 deletions packages/core-typings/src/voip/VoIPUserConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ export interface VoIPUserConfiguration {
* @defaultValue undefined
*/
enableKeepAliveUsingOptionsForUnstableNetworks: boolean;

/**
* Time to wait for Ice Gathering to complete
* @defaultValue 5000
*/
iceGatheringTimeout?: number;
}

export interface IMediaStreamRenderer {
Expand Down
4 changes: 4 additions & 0 deletions packages/i18n/src/locales/en.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -6270,6 +6270,10 @@
"VoIP_TeamCollab_FreeSwitch_Timeout": "FreeSwitch Request Timeout",
"VoIP_TeamCollab_FreeSwitch_WebSocket_Path": "WebSocket Path",
"VoIP_TeamCollab_Beta_Alert": "This feature is currently in Beta, please report any issues to Rocket.Chat support",
"VoIP_TeamCollab_Ice_Servers": "Ice Servers",
"VoIP_TeamCollab_Ice_Servers_Description": "A list of Ice Servers (STUN and/or TURN), separated by comma. \n Username, password and port are allowed in the format `username:password@stun:host:port` or `username:password@turn:host:port`. \n Both username and password may be html-encoded.",
"VoIP_TeamCollab_Ice_Gathering_Timeout": "Ice Gathering Timeout",
"VoIP_TeamCollab_Ice_Gathering_Timeout_Description": "Time to wait for Ice Gathering to complete before sending. Low values may prevent Ice Servers from being used, while high values may delay the start of VoIP calls if an invalid Ice Server is specified.",
"VoIP_Toggle": "Enable/Disable VoIP",
"Chat_opened_by_visitor": "Chat opened by the visitor",
"Waiting_for_answer": "Waiting for answer",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { useMemo } from 'react';
import type { IceServer } from '../definitions';
import { parseStringToIceServers } from '../utils/parseStringToIceServers';

export const useWebRtcServers = (): IceServer[] => {
const servers = useSetting('WebRTC_Servers');
export const useIceServers = (): IceServer[] => {
const servers = useSetting('VoIP_TeamCollab_Ice_Servers');

return useMemo(() => {
if (typeof servers !== 'string' || !servers.trim()) {
Expand Down
8 changes: 5 additions & 3 deletions packages/ui-voip/src/hooks/useVoipClient.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useUser, useEndpoint } from '@rocket.chat/ui-contexts';
import { useUser, useEndpoint, useSetting } from '@rocket.chat/ui-contexts';
import { useQuery } from '@tanstack/react-query';
import { useEffect, useRef } from 'react';

import { useWebRtcServers } from './useWebRtcServers';
import { useIceServers } from './useIceServers';
import VoipClient from '../lib/VoipClient';

type VoipClientParams = {
Expand All @@ -20,8 +20,9 @@ export const useVoipClient = ({ enabled = true, autoRegister = true }: VoipClien
const voipClientRef = useRef<VoipClient | null>(null);

const getRegistrationInfo = useEndpoint('GET', '/v1/voip-freeswitch.extension.getRegistrationInfoByUserId');
const iceGatheringTimeout = useSetting('VoIP_TeamCollab_Ice_Gathering_Timeout', 5000);

const iceServers = useWebRtcServers();
const iceServers = useIceServers();

const { data: voipClient, error } = useQuery<VoipClient | null, Error>({
queryKey: ['voip-client', enabled, userId, iceServers],
Expand Down Expand Up @@ -59,6 +60,7 @@ export const useVoipClient = ({ enabled = true, autoRegister = true }: VoipClien
webSocketURI: websocketPath,
connectionRetryCount: Number(10), // TODO: get from settings
enableKeepAliveUsingOptionsForUnstableNetworks: true, // TODO: get from settings
iceGatheringTimeout,
};

const voipClient = await VoipClient.create(config);
Expand Down
4 changes: 2 additions & 2 deletions packages/ui-voip/src/lib/VoipClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class VoipClient extends Emitter<VoipEvents> {
}

public async init() {
const { authPassword, authUserName, sipRegistrarHostnameOrIP, iceServers, webSocketURI } = this.config;
const { authPassword, authUserName, sipRegistrarHostnameOrIP, iceServers, webSocketURI, iceGatheringTimeout } = this.config;

const transportOptions = {
server: webSocketURI,
Expand All @@ -64,7 +64,7 @@ class VoipClient extends Emitter<VoipEvents> {
};

const sdpFactoryOptions = {
iceGatheringTimeout: 10,
...(typeof iceGatheringTimeout === 'number' && { iceGatheringTimeout }),
peerConnectionConfiguration: { iceServers },
};

Expand Down
Loading