【问题标题】:SIP integration with call conference in JSSIP 与 JS 中的呼叫会议集成
【发布时间】:2021-10-05 07:57:48
【问题描述】:

我正在开发一个将 React.js 集成为前端框架的 Electron 应用程序,它更像是一个调用应用程序。 在那个应用程序特定的用户可以有多个呼入、呼出、静音 |取消静音,保持 |挂断电话等 为了实现这个功能,我们拥有自己的 sip 服务器,并且为了集成该 SIP 服务器,我们在前端使用了一个名为 SIP.JS 的库。 SIP.JS 为我们提供了几乎所有预定义的功能来拨打电话、接听电话、静音、取消静音、盲转、有人转接等。 但是,在召开电话会议时,它没有适当的文档。 SIP.JS 向我们规定,我们可以使用FreeSWITCHASTERISK 来实现该功能,但是根据我们的具体要求,不需要集成额外的服务器。 电话会议我们也提到了rfc documentation,但没有这样的进展。

到目前为止,我们所做的是:

  1. 注册了userAgent
  2. 集成来电代码
  3. 集成拨出电话代码
  4. 实现多个会话处理,用于多个调用
  5. 静音 |取消静音,按住 |取消保留。
  6. DTMF 功能
  7. 盲转、参加转
  8. 响铃所有设备

在这种电话会议场景中,我想我们必须对传入和传出会话处理函数进行更改。

  1. 在上下文中注册和来电:
 const getUAConfig = async (_extension, _name) => {
    let alreadyLogin = '';
    try {
      alreadyLogin = 'yes';
      if (alreadyLogin == 'yes') {
        _displayname = _name;
        _sipUsername = _extension;
        _sipServer = 'SIP SERVER';
        _sipPassword = 'SIP PASSWORD';
        _wssServer = 'WSS SERVER;

        const uri = UserAgent.makeURI('sip:' + _sipUsername + '@' + _sipServer);
        const transportOptions = {
          wsServers: 'WSS SERVER',
          traceSip: true,
          maxReconnectionAttempts: 1,
        };

        const userAgentOptions = {
          uri: uri,
          transportOptions: transportOptions,
          userAgentString: 'App name',
          authorizationPassword: _sipPassword,
          sipExtension100rel: 'Supported',
          sipExtensionReplaces: 'Supported',
          register: true,
          contactTransport: 'wss',
          dtmfType: 'info',
          displayName: _name,
          sessionDescriptionHandlerFactoryOptions: {
            peerConnectionOptions: {
              rtcpMuxPolicy: 'negotiate',
              iceCheckingTimeout: 1000,
              iceTransportPolicy: 'all',
              iceServers: [{ urls: 'stun:stun.l.google.com:19302' }],
            },
          },
        };

        userAgent = await new UserAgent(userAgentOptions);
        const registerOptions = {
          extraContactHeaderParams: [],
        };
        registerer = await new Registerer(userAgent, registerOptions);

        registerer.stateChange.addListener((newState) => {
          
        });

        userAgent.start().then(async () => {
          console.log('Connected with WebSocket.');
          // Send REGISTER
          await registerer
            .register()
            .then((request) => {
              console.log('Successfully sent REGISTER, object is here');
              dispatch({
                type: USER_REGISTERED,
                payload: true,
              });
            })
            .catch((error) => {
              console.log('Failed to send REGISTER');
            });
        });
        return { userAgent, registerer };
      } else {
        return null;
      }
    } catch (error) {
      console.log(error.message + '');
      return null;
    }
  };
  1. 传出功能:
    const dilaerFun = (inputNumber, userAgentInfo) => {
    var session;
    var uri = UserAgent.makeURI(
      `URI which we wanna call (sip number)`
    );
    session = new Inviter(userAgentInfo, uri);
    session
      .invite()
      .then((request) => {
        console.log('Successfully sent INVITE');
        sessionInfoAdd(session);
        session.stateChange.addListener(async (state) => {
          switch (state) {
            case 'Established':
              setMissedStatus(null);
              console.log('established outgoing....');
              //outgoing call log-----
              const mediaElement = document.getElementById(
                `mediaElement${session._id}`
              );
              const remoteStream = new MediaStream();

              session.sessionDescriptionHandler.peerConnection
                .getReceivers()
                .forEach((receiver) => {
                  if (receiver.track) {
                    remoteStream.addTrack(receiver.track);
                  }
                });
              mediaElement.srcObject = remoteStream;
              mediaElement.play();
              break;
            case 'Terminated':
              console.log('terminated');
              dispatch({
                type: DEMO_STATE,
                payload: session._id,
              });
              break;
            default:
              break;
          }
        });
      })
      .catch((error) => {
        console.error(' Failed to INVITE');
        console.error(error.toString());
      });
  };

  1. 会话数组由以下人员维护:
  const sessionInfoAdd = (session) => {
    dispatch({
      type: SESSION_STORE,
      payload: session,
    });
  };
  1. 存储所有会话的变量是:
 sessionInfo:[]

注意:一旦应用程序启动,就会调用 getUAConfig()。 dialerFun() 当我们想拨打一个特定的号码时被调用。 sessionInfoAdd() 在 getUAConfig 和 dialerFun 中都被调用,因为它们是呼入和呼出的代码。 当 sessionInfoAdd() 被触发时,我们返回的特定会话被添加到 sessionInfo (Array) 中以维护会话。

【问题讨论】:

    标签: reactjs electron sip conference sipjs


    【解决方案1】:

    SIP.JS 只是一个库,因此您必须在 FreeSWITCH 或 Asterisk 上进行会议设置(我认为 FreeSWITCH 更好)

    这样做相当简单,在您的应用程序级别,您需要一种方法在检查访问 ID 和您要添加的任何身份验证等详细信息(如 PIN)后将呼叫传递给该框。

    完成后,您可以将其转发到专门为会议设置的分机,或者通过从应用发送到特定网关/拨号计划来进行动态会议设置。

    FreeSWITCH 软件有一个陡峭的学习曲线,但是当我做类似的事情时这对我很有帮助:https://freeswitch.org/confluence/display/FREESWITCH/mod_conference

    如果您愿意,也可以编写自己的 conf。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多