问题
I'm trying to build a call centre app using the Twilio WebRTC client on on the "agent" side.
It's at the demo stage currently, but I've come across a major issue which appears to be a bug either in the browser's WebRTC stack, or Twilio's client code. If the permanently allows access to the microphone from the browser (which is the default "Allow" behaviour in Chrome, and a possibility in Firefox), then the first call comes through fine, but when a second call is routed to the client, answering it breaks everything.
In Chrome, for example (tested on PC and Mac, with the current latest version, 48), the first call that goes through works fine (I've already allowed the mic to be used for this host, and it's running on HTTPS as is required):
[Device] Setting up PStream
twilio.min.js:58 [WSTransport] Opening socket
twilio.min.js:58 [WSTransport] attempting to connect
twilio.min.js:58 [Device] Registering to eventStream with url: wss://matrix.twilio.com/2012-02-09/ACbf0c1cb8b610edf31aa7929d1105895a/32906…M5OSJ9.q_G8AEsidiWelamCLuEhKg7dL1hMtioZgK_gNsY61fs&feature=publishPresence
twilio.min.js:58 [Matrix] Attempting to connect to wss://matrix.twilio.com/2012-02-09/ACbf0c1cb8b610edf31aa7929d1105895a/32906…M5OSJ9.q_G8AEsidiWelamCLuEhKg7dL1hMtioZgK_gNsY61fs&feature=publishPresence...
twilio.min.js:58 [WSTransport] Socket opened
twilio.min.js:58 [PStream] Setting token and publishing listen
twilio.min.js:58 [Matrix] Socket opened... sending ready signal
twilio.min.js:58 [Device] Stream is ready
client:49 Ready
twilio.min.js:58 [Twilio.PeerConnection] signalingState is "have-remote-offer"
twilio.min.js:58 [Twilio.PeerConnection] signalingState is "stable"
client:64 Successfully established call
twilio.min.js:58 [Twilio.PeerConnection] iceConnectionState is "checking"
twilio.min.js:58 [Twilio.PeerConnection] iceConnectionState is "connected"
twilio.min.js:58 [Connection] Received HANGUP from gateway
twilio.min.js:58 [Connection] Disconnecting...
client:69 Call ended
twilio.min.js:58 [Twilio.PeerConnection] iceConnectionState is "closed"
twilio.min.js:58 [Twilio.PeerConnection] signalingState is "closed"
Then when I make the second call to it, initially the "incoming" handler is called OK and it alerts with the ring tone etc, but when I call Connection.accept(), the following happens:
twilio.min.js:58 [Twilio.PeerConnection] signalingState is "have-remote-offer"
twilio.min.js:58 [Twilio.PeerConnection] signalingState is "stable"
client:64 Successfully established call
twilio.min.js:58 [Connection] Received an error from MediaStream:
twilio.min.js:58 Object {info: Object}
client:60 Error: Error creating the answer: Failed to set local answer sdp: Called in wrong state: STATE_INPROGRESS
twilio.min.js:58 [Connection] Received HANGUP from gateway
twilio.min.js:58 [Connection] Received an error from the gateway:
twilio.min.js:58 Object {code: 31000, message: "Call is no longer valid", connection: a}
client:60 Error: Call is no longer valid
twilio.min.js:58 [Connection] Disconnecting...
twilio.min.js:58 [Twilio.PeerConnection] iceConnectionState is "closed"
twilio.min.js:58 [Twilio.PeerConnection] signalingState is "closed"
When this happens, the tab in Chrome has the red circle "recording light" on still, which when you hover over says "This tab is using your camera or microphone". The status of the Twilio.Device remains "busy", and the phone call that's dialling in is still ringing.
This occurs with the demo code that Twilio provides on their quickstart page, so I'm at a bit of a loss as to how to deal with?
In Chrome, it's hard to see what's happening as you can't turn on and off mic access easily. In Firefox, the same behaviour happens if you "always allow" the mic, but if you click the mic icon on the address bar and remove permission, then when you call again and it asks for it, so long as you say "accept once", all is well.
Clearly it's no good for a call centre to have to accept access every time they want to answer a call - any ideas how to fix it?
There's a possible workaround of dropping the Twilio connection and re-acquiring every time a call ends, but it's far from ideal (I haven't tested to see if it works, either).
Edit:
The support page tests show the following (all test pass OK):
User agent: Mozilla%2F5.0+%28Macintosh%3B+Intel+Mac+OS+X+10_11_2%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F48.0.2564.82+Safari%2F537.36
Javascript: OK (version 1.6)
Browser Version: OK (chrome 48.0.2564.82)
Adobe Flash Version: OK (Shockwave Flash 20.0 r0)
[Device] Setting up PStream
[WSTransport] Opening socket
[WSTransport] attempting to connect
[Device] Destroyed eventstream.
Microphone: OK ( )
[WSTransport] Socket opened
[PStream] Setting token and publishing listen
[Device] Stream is ready
Twilio Client: OK (Device.ready)
[Twilio.PeerConnection] signalingState is "have-local-offer"
[Twilio.PeerConnection] signalingState is "stable"
Twilio Client: OK (Device.connect)
[Twilio.PeerConnection] iceConnectionState is "checking"
[Twilio.PeerConnection] iceConnectionState is "completed"
[Twilio.PeerConnection] iceConnectionState is "completed"
But I think that's as expected - the problem occurs on the second time you try to connect to the client :(
UPDATE:
Having spoken with Twilio support quite a bit, it's a reproduceable bug in the client, so will have to wait until they fix it. A workaround of sorts is to auto-answer the call in the incoming event, and manage your call handling elsewhere.
回答1:
This sounds like a JS SDK error. Open chrome://webrtc-internals and keep it open while reproducing the error.
Check that your first call is established fine. You should see an internal tab with [someprocessid-1] that, when clicked, should show a series of events like setRemoteDescription, createAnswer, setLocalDescription on the left. The last thing there should be a iceConnectionStateChange.
Now make the second call. You should see a second tab [someprocessid-2] (click on it until it is green) that shows another series of events, setRemoteDescription and createAnswer. Usually that tab should also show a setLocalDescription but I suspect this happens on the wrong connection. Check the -1 tab for setLocalDescription followed by a setLocalDescriptionOnFailure.
If that happens, it is a timing bug in the SDK which is not dispatching the API calls to the correct RTCPeerConnection object.
chrome://webrtc-internals can also export dump files of those calls which are very useful for debugging issues like this.
回答2:
If you could share your code with us it would help. However, below is how I handle client calls.
I currently have a call center up and using the twilio client.
It sounds like while the call is disconnecting your not closing the call state in the browser
I am using socket.io too. I have a callback route which is called when a call disconnects.
Then I call
socket.on('callback', function(data){
if(data == agent){
inboundCallType = null;
inboundCall = undefined;
Twilio.Device.disconnectAll();
}
})
Basically on the server side I look up the call SID and find out what agent was on that call. Then I send the agents login name to the front end. Then the agent who was on the call gets the disconnectAll prompt. Setting inboundcalltype and inbound call to null are for custom variables I track
When a call is answered I set
inboundCall = Twilio.Device.connect(params);
If you look here you can see a full reference in PHP of how they set the client up and end calls with it. While it is in PHP the code for the client is in JavaScript.
https://www.twilio.com/docs/tutorials/walkthrough/browser-calls/php/laravel
回答3:
The answer is that it's a bug in the Twilio Client that they're working to fix - but it only happens if you use an answer() call after the incoming event - so if you auto answer the call, and do the management some other way, all is fine.
回答4:
Pete, Megan from Twilio again.
I assume you're working with this quickstart.
Unfortunately, this error you're receiving isn’t particularly useful alone as there are multiple places in the code that could raise that. It would be helpful to get more information such as whether or not the Client is receiving an incoming call or making an outgoing call? And though you wouldn't want to share them here, it would be helpful to have a look at call SIDs.
It could also be useful to know whether or not you're using a USB headset.
Given the exchange of account sensitive information, it is probably best to seek advice from help@twilio.com.
Hope this helps.
来源:https://stackoverflow.com/questions/34998896/twilio-webrtc-client-breaks-if-user-always-allows-microphone-access