javascript - Twilio 调用被不尊重 Twilio.Device.destroy() 的多个设备实例阻止

标签 javascript jquery twilio twilio-api twilio-click-to-call

我正在开发一个 Twilio 应用程序,用户在公共(public)终端上会看到一个数字列表。有些是 SIP,有些是传统的。最终用户可能会按下按钮调用列表中的一个人,进行对话,然后走开 - 然后另一个用户会走上前调用另一个人。
我遇到一个问题,Twilio.Device.destroy 没有消除所有正在使用的设备,并且示例中的第二个用户最终会调用第一个用户的目标。
首先是代码,然后是日志:
按钮 Hook :

$('.twilio-voice').click(function() {
    var toNum = this.value;
    console.log('To num in jq');
    console.log(toNum);
    makeVoiceCall(toNum);
});


makeVoiceCall 函数:

var makeVoiceCall = function(toNum) {
    console.log('To Num Is:');
    console.log(toNum);
    if(localStorage.token == undefined) {
        console.log("In If");
        getVoiceToken(toNum);
    } else {
        console.log("In Else");
        console.log(localStorage.token);
        Twilio.Device.setup(localStorage.token, {debug: true});
        Twilio.Device.ready(function(device){
            console.log('IN READY TO NUM IS');
            console.log(toNum);
            Twilio.Device.connect({"To": toNum});
        });
        Twilio.Device.error(function(error) {
            console.log(error.message);
            if(error.message == 'JWT Token Expired') {
                getVoiceToken(toNum);
            };
        });
    }
};


有一个事件监听器在 Twilio.Device.connect 上启动一个模式,该模式创建一个模式按钮,按下该按钮时,还有一个断开事件监听器,两者都调用挂断函数:

function hangup() {
    Twilio.Device.disconnectAll();
    Twilio.Device.destroy();
};


我尝试添加 Twilio.Device.destroy();在 makeVoiceCall 的开头,Twilio.Device.ready() 内;在 else 语句的顶部,它们似乎没有效果。如果我单击传统号码,然后单击 sip 号码,日志将如下所示。传统的号码会被叫两次。如果先调用 SIP 号码,则随后尝试使用传统号码也会调用该号码。在此示例中,加载页面时 localStorage 中已存在一个 token 。

To num in jq
ts:1214 +15555555555
ts:1178 To Num Is:
ts:1179 +15555555555
ts:1190 In Else
ts:1191 
[STACKOVERFLOW EDIT: console logged token removed]
twilio.min.js:71 Device.sounds is deprecated and will be removed in the next 
breaking release. Please use the new functionality available on 
Device.audio.
m.defaultWarnHandler @ twilio.min.js:71
m.deprecated @ twilio.min.js:71
(anonymous) @ twilio.min.js:72
l @ twilio.min.js:71
a @ twilio.min.js:39
setup @ twilio.min.js:59
makeVoiceCall @ ts:1192
(anonymous) @ ts:1215
dispatch @ jquery-2.1.3.min.js:3
r.handle @ jquery-2.1.3.min.js:3
twilio.min.js:70 [Device] Setting up PStream
twilio.min.js:70 [WSTransport] Opening socket
twilio.min.js:70 [WSTransport] attempting to connect
twilio.min.js:70 [WSTransport] Socket opened
twilio.min.js:70 [PStream] Setting token and publishing listen
twilio.min.js:70 [Device] Stream is ready
ts:1194 IN READY TO NUM IS
ts:1195 +15555555555
twilio.min.js:70 [Twilio.PeerConnection] signalingState is "have-local-offer"
twilio.min.js:70 [Twilio.PeerConnection] signalingState is "stable"
twilio.min.js:70 [Twilio.PeerConnection] iceConnectionState is "checking"
xb @ jquery-2.1.3.min.js:3
get @ jquery-2.1.3.min.js:3
css @ jquery-2.1.3.min.js:3
get @ jquery-2.1.3.min.js:3
cur @ jquery-2.1.3.min.js:3
init @ jquery-2.1.3.min.js:3
Kb @ jquery-2.1.3.min.js:3
createTween @ jquery-2.1.3.min.js:3
Rb.* @ jquery-2.1.3.min.js:3
Ub @ jquery-2.1.3.min.js:3
Vb @ jquery-2.1.3.min.js:3
Xb @ jquery-2.1.3.min.js:3
g @ jquery-2.1.3.min.js:3
dequeue @ jquery-2.1.3.min.js:3
(anonymous) @ jquery-2.1.3.min.js:3
each @ jquery-2.1.3.min.js:2
each @ jquery-2.1.3.min.js:2
queue @ jquery-2.1.3.min.js:3
animate @ jquery-2.1.3.min.js:3
n.fn.(anonymous function) @ jquery-2.1.3.min.js:3
addModal @ ts:974
(anonymous) @ ts:1024
a.emit @ twilio.min.js:162
(anonymous) @ twilio.min.js:48
c @ twilio.min.js:165
a.emit @ twilio.min.js:163
mediaStream.onopen @ twilio.min.js:21
a.version.pc.onsignalingstatechange @ twilio.min.js:119
twilio.min.js:70 [Twilio.PeerConnection] iceConnectionState is "completed"
twilio.min.js:70 [Connection] Disconnecting...
twilio.min.js:70 [PStream] Closing PStream
twilio.min.js:70 [WSTransport] Closing socket
twilio.min.js:70 [Twilio.PeerConnection] iceConnectionState is "closed"
twilio.min.js:70 [Twilio.PeerConnection] signalingState is "closed"
twilio.min.js:158 WebSocket connection to 'wss://chunderw-vpc-gll.twilio.com/signal' failed: Close received after close
l._connect @ twilio.min.js:158
l.open @ twilio.min.js:157
a @ twilio.min.js:78
a @ twilio.min.js:75
a._setupStream @ twilio.min.js:54
a.register @ twilio.min.js:50
a @ twilio.min.js:46
setup @ twilio.min.js:59
makeVoiceCall @ ts:1192
(anonymous) @ ts:1215
dispatch @ jquery-2.1.3.min.js:3
r.handle @ jquery-2.1.3.min.js:3
twilio.min.js:70 [WSTransport] Socket received error: undefined
twilio.min.js:70 [WSTransport] Socket closed
twilio.min.js:70 [Device] Stream is offline
ts:1213 To num in jq
ts:1214 sip:test@sipexample.info
ts:1178 To Num Is:
ts:1179 sip:test@sipexample.info
ts:1190 In Else
ts:1191 [STACKOVERFLOW EDIT: token console.logged]
twilio.min.js:70 [Device] Found existing Device; using new token but ignoring options
twilio.min.js:70 [Device] Setting up PStream
twilio.min.js:70 [WSTransport] Opening socket
twilio.min.js:70 [WSTransport] attempting to connect
twilio.min.js:70 [WSTransport] Socket opened
twilio.min.js:70 [PStream] Setting token and publishing listen
twilio.min.js:70 [Device] Stream is ready
[STACKOVERFLOW EDIT: HERE IS WHERE TWO DEVICES ARE CALLED BY ONE Twilio.Device.setup()]
ts:1194 IN READY TO NUM IS
ts:1195 +15555555555
ts:1194 IN READY TO NUM IS
ts:1195 sip:test@sipexample.info
twilio.min.js:51 Uncaught Error: A Connection is already active
    at a.connect (twilio.min.js:51)
    at Function.connect (twilio.min.js:60)
    at a.<anonymous> (ts:1196)
    at a.emit (twilio.min.js:163)
    at a.<anonymous> (twilio.min.js:55)
    at a.emit (twilio.min.js:163)
    at l.transport.onmessage (twilio.min.js:78)
    at WebSocket.c.onmessage (twilio.min.js:160)
a.connect @ twilio.min.js:51
connect @ twilio.min.js:60
(anonymous) @ ts:1196
a.emit @ twilio.min.js:163
(anonymous) @ twilio.min.js:55
a.emit @ twilio.min.js:163
transport.onmessage @ twilio.min.js:78
c.onmessage @ twilio.min.js:160
twilio.min.js:70 [Twilio.PeerConnection] signalingState is "have-local-offer"
twilio.min.js:70 [Twilio.PeerConnection] signalingState is "stable"
twilio.min.js:70 [Twilio.PeerConnection] iceConnectionState is "checking"
twilio.min.js:70 [Twilio.PeerConnection] iceConnectionState is "completed"
twilio.min.js:70 [Connection] Disconnecting...
twilio.min.js:70 [PStream] Closing PStream
twilio.min.js:70 [WSTransport] Closing socket
twilio.min.js:70 [Twilio.PeerConnection] iceConnectionState is "closed"
twilio.min.js:70 [Twilio.PeerConnection] signalingState is "closed"
twilio.min.js:158 WebSocket connection to 'wss://chunderw-vpc-gll.twilio.com/signal' failed: Close received after close
l._connect @ twilio.min.js:158
l.open @ twilio.min.js:157
a @ twilio.min.js:78
a @ twilio.min.js:75
a._setupStream @ twilio.min.js:54
a.register @ twilio.min.js:50
setup @ twilio.min.js:59
makeVoiceCall @ ts:1192
(anonymous) @ ts:1215
dispatch @ jquery-2.1.3.min.js:3
r.handle @ jquery-2.1.3.min.js:3
twilio.min.js:70 [WSTransport] Socket received error: undefined
twilio.min.js:70 [WSTransport] Socket closed
twilio.min.js:70 [Device] Stream is offline

正如您在日志的底部四分之一中看到的 - 由我添加的内容标记:[STACKOVERFLOW EDIT: HERE IS WHERE TWO DEVICES ARE CALLEDED BY ONE Twilio.Device.setup()], SIP 和传统号码都会在单个 Twilio.Device.setup 调用期间被调用,即使设备通过挂断功能被销毁(并且我已经尝试了其他点来放置 Twilio.Device.destroy)。因此,在第二次尝试时,只有原始调用的号码才能真正连接到。目前,我能想到的唯一解决方法是为列表中的每个人创建单独的函数(这是 DRY 的对立面,并为维护或扩展此代码增加了大量工作)或完成通话后重新加载页面(我的雇主不喜欢这样做)。
如果我可以在通话完成后简单地释放/销毁 Twilio 设备,那将对我有很大帮助。我尝试在我的 Twilio.Device.connect 调用下面放置一个 Twilio.Device.disconnect(function() { Twilio.Device.disconnectAll(); Twilio.Device.destroy();});准备好了,结果相同。任何有关销毁这些多个设备(或重复使用第一个设备)的帮助都是非常宝贵的。

最佳答案

这里是 Twilio 开发者布道者。

您不必在每次调用后销毁 Twilio.Device。这里实际发生的是,您正在注册多个处理程序,当设备变得准备就绪时,这些处理程序将被调用。

我建议稍微重新架构一下。加载页面后,设置 Twilio 设备。然后监听离线事件,以便您知道何时重新生成 token 并重新连接到服务。像这样的东西:

function makeVoiceCall(toNum) {
  Twilio.Device.connect({"To": toNum});
}

function setupDevice(token) {
  Twilio.Device.setup(token, { debug: true });
}

function getVoiceToken(callback) {
  $.post('/token', function(data) {
    localStorage.token = data.token;
    callback(token);
  })
}

function init() {
  if(localStorage.token == undefined) {
    getVoiceToken(function(token){ 
      setupDevice(token)
    });
  } else {
    setupDevice(localstorage.token)
  }

  // Ready will setup click handlers.
  Twilio.Device.ready(function() {
    $('.twilio-voice').click(function() {
      var toNum = this.value;
      makeVoiceCall(toNum);
    });
  });

  // offline will remove click handlers, get a new token and setup the device again
  Twilio.Device.offline(function() {
    // unregister click handlers for now
    $('.twilio-voice').off('click');
    getVoiceToken(function(token) {
      setupDevice(token);
    })
  })
}

window.addEventListener('load', init);

我在这里编写了一个新版本的 getVoiceToken ,以便它在回调中返回 token ,我认为这使事情更容易阅读。

请告诉我这是否有帮助。

关于javascript - Twilio 调用被不尊重 Twilio.Device.destroy() 的多个设备实例阻止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45869513/

相关文章:

javascript - ios - 将文本注入(inject) UIWebView 文本字段

javascript - 如何防止浏览器使用 javascript 存储页面状态更改?

javascript - 如果包含关键字,如何突出显示 anchor 中的文本?

javascript - 悬停时垂直对齐的扩展菜单项和出现的子菜单

php - Twilio 短信回复功能

Twilio session 与通话

javascript - 我可以选择哪个 AntD 图标与 allowClear = true 一起使用吗?

javascript - 如何使显示文本成为多语言?

javascript - 如何通过JS文件添加到表格的链接

javascript - Twilio 客户端 JS-SDK Websocket 不断重新连接