Vraag WebRTC videochat met Ajax in plaats van WebSocket: Mogelijk?


Ongeveer zes maanden geleden kon ik met succes mijn eigen WebSocket-serverscript in PHP coderen. Daardoor kon ik een WebRTC-videochatservice opzetten op mijn lokale host. Ik was best tevreden totdat ik me realiseerde dat ik voor de implementatie ervan een webserver nodig had die toegang gaf tot sockets.

Helaas is er geen gedeelde webhosting voor sockets en alle webservers die sockets aanbieden zijn duur. Hoewel het geen effectieve oplossing op grote schaal is, wil ik voor het opzetten van een demo om mensen te laten zien, de signaleringsmethode veranderen van WebSocket naar Ajax, zodat ik kan pronken met de WebRTC-videochatservice die ik heb gemaakt.

Daartoe heb ik de afgelopen dagen geprobeerd iets te coderen, maar het lukte me niet om de WebRTC-peers elkaars video te laten maken.

Op dit moment, wanneer een client verbinding maakt met het script, gebruik ik Ajax om een ​​verzoek naar een PHP-script te verzenden dat controleert of er nog andere actieve gebruikers in de DB zijn. Als dat niet het geval is, maakt het script vervolgens een aanbieding en plaatst de aanbieding in de database. Daarna peilt de client elke seconde een afzonderlijk PHP-script om te controleren of er een antwoord is van een andere client die verbinding maakt met het script.

Daarna maak ik vervolgens verbinding met het script van een andere client, die hetzelfde PHP-script en DB opvraagt, die vervolgens beseffen dat een actieve gebruiker (de eerste verbinding) al een aanbieding heeft gepost die de tweede client verwerft en instelt voor de afstandsbediening Beschrijving. De tweede client maakt vervolgens een antwoord, dat in de database wordt geplaatst.

Op dit punt detecteert de eerste client (die de database elke seconde peilt) dat een antwoord aanwezig is en stelt dat antwoord in als de beschrijving op afstand voor de eerste client. Helaas, zelfs na het succesvol doen van dit alles, komt de video van de andere klant niet tevoorschijn.

Dus hier is waar ik verward ben en heb drie (meervoudige) vragen:

1) Ik dacht dat nadat beide clients hun lokale beschrijving hadden ingesteld en vervolgens die lokale beschrijving naar de andere client en de andere clientset met beschrijving verzonden als de externe beschrijving die de onaddstream-gebeurtenis had moeten afgeven, zodat ik de afstandsbediening kon weergeven video. Dit gebeurt echter niet. Dit werkte prima voordat ik WebSocket gebruikte, maar het werkt helemaal niet met puur Ajax. Is er iets in het bijzonder dat ik mis? Is de WebRTC-specificatie de afgelopen zes maanden radicaal veranderd? Ik heb geprobeerd de WebRTC-specificaties te bekijken, maar ik zie geen grote veranderingen.

2) Nadat ik gefrustreerd raakte door het niet krijgen van dingen om met Ajax te werken, ging ik terug naar mijn WebSocket-versie en laadde het op mijn lokale host. Ik heb de code helemaal niet veranderd sinds ik hem voor het laatst gebruikte (wat zes maanden geleden prima werkte), maar nu, wanneer ik het probeer te gebruiken, werkt het soms, en soms niet. Soms krijg ik fouten in verband met het niet kunnen instellen van de lokale en / of externe beschrijvingen. Wat is hier aan de hand? Zijn er wijzigingen in de specificaties aangebracht waardoor dit zou kunnen gebeuren? In verband daarmee, hoewel ik de afstandsbedieningsvideo's niet kan laten verschijnen met de Ajax-versie, heb ik veel dingen gadegeslagen op de console, en het lijkt ook op de Ajax-versie, soms op de lokale en externe beschrijvingen voor beide clients zijn met succes ingesteld en soms treden er fouten op wanneer ik de lokale / externe beschrijvingen om welke reden dan ook probeer in te stellen, hoewel ik telkens zonder wijzigingen hetzelfde script gebruik. Ik gebruik de nieuwste versie van Chrome en ik begin me af te vragen of er een fout in zit of zoiets.

3) Is de gebeurtenishandler onicecandidate vereist om een ​​verbinding tot stand te brengen? Mijn aanname was dat peers een verband konden leggen met eenvoudigweg een geldige aanbieding en antwoord, en dat de onicecandidate gebeurtenis gebruikt werd om alternatieve routes, enz. Aan te bieden, die tot een betere verbinding zouden kunnen leiden (maar niet vereist zijn). Heb ik het fout? Als de onicandidaat-info vereist is, hoe raadt u aan dit met Ajax als signaalmethode te doen?

Ik weet dat dit veel informatie en veel vragen is, maar alle informatie / inzicht die iemand kan bieden, wordt zeer op prijs gesteld. Ik heb de afgelopen dagen met mijn hoofd tegen mijn bureau gebotst en geprobeerd dit uit te zoeken, en niets is logisch.


10
2018-06-18 05:39


oorsprong


antwoorden:


Mijn eerste advies over je app. werken / niet sporadisch werken is kijken naar de huidige online werkende implementaties. Er zijn veel WebRTC-demo's op de Internets.

AJAX

Over AJAX: waarom zou het niet werken? Ik ben momenteel bezig met precies hetzelfde als jij en het werkt goed elke keer (Ik kan de bron voorlopig niet onthullen). Cliënten zijn constant bezig met het afvragen van de server en kunnen op die manier SDP-beschrijvingen / ICE-kandidaten naar een specifieke andere klant sturen. De server fungeert als een eenvoudige brug (dit is de basis van signalering).

Of het nu WebSocket, AJAX of IPoACzolang je de andere cliënt alles wat hij nodig heeft (en op het juiste moment hierover later meer) overdraagt, zou het moeten werken. Ik heb zelfs een demo gemaakt waarin je handmatig de SDP-beschrijving en ICE-kandidaten kopieert en plakt met behulp van tekstgebieden en klik op knoppen om verder te gaan in het signaleringsproces en dat werkte natuurlijk ook goed.

ICE-kandidaten

Nu: ja, je hebt ICE-kandidaten nodig. Bekijk een voorbeeld SDP-aanbieding stuk dat ik net heb gegenereerd met createOffer op Chromium 27:

v=0
o=- 3866099361 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE audio video
a=msid-semantic: WMS 9kTlKaNe1exIs6JgEFYfXlu6E5f4B5R3I2D8
m=audio 1 RTP/SAVPF 111 103 104 0 8 107 106 105 13 126
c=IN IP4 0.0.0.0
a=rtcp:1 IN IP4 0.0.0.0
a=ice-ufrag:l8Qu31Vu4VG5YApS
a=ice-pwd:TpyQ5iESUH4HvYGE4ay8JUhe
a=ice-options:google-ice
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=sendrecv
a=mid:audio
a=rtcp-mux
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:bC5YSe2xCmui0wSxUHWKIi9INbZ2y0VrO1swoZbl
a=rtpmap:111 opus/48000/2
a=fmtp:111 minptime=10
a=rtpmap:103 ISAC/16000
a=rtpmap:104 ISAC/32000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:107 CN/48000
a=rtpmap:106 CN/32000
a=rtpmap:105 CN/16000
a=rtpmap:13 CN/8000
a=rtpmap:126 telephone-event/8000
a=maxptime:60
a=ssrc:1976175890 cname:/+lKYsttecoiyiu5
a=ssrc:1976175890 msid:9kTlKaNe1exIs6JgEFYfXlu6E5f4B5R3I2D8 9kTlKaNe1exIs6JgEFYfXlu6E5f4B5R3I2D8a0
a=ssrc:1976175890 mslabel:9kTlKaNe1exIs6JgEFYfXlu6E5f4B5R3I2D8
a=ssrc:1976175890 label:9kTlKaNe1exIs6JgEFYfXlu6E5f4B5R3I2D8a0
m=video 1 RTP/SAVPF 100 116 117
c=IN IP4 0.0.0.0
a=rtcp:1 IN IP4 0.0.0.0
a=ice-ufrag:l8Qu31Vu4VG5YApS
a=ice-pwd:TpyQ5iESUH4HvYGE4ay8JUhe
a=ice-options:google-ice
a=extmap:2 urn:ietf:params:rtp-hdrext:toffset
a=sendrecv
a=mid:video
a=rtcp-mux
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:bC5YSe2xCmui0wSxUHWKIi9INbZ2y0VrO1swoZbl
a=rtpmap:100 VP8/90000
a=rtcp-fb:100 ccm fir
a=rtcp-fb:100 nack 
a=rtpmap:116 red/90000
a=rtpmap:117 ulpfec/90000
a=ssrc:3452335690 cname:/+lKYsttecoiyiu5
a=ssrc:3452335690 msid:9kTlKaNe1exIs6JgEFYfXlu6E5f4B5R3I2D8 9kTlKaNe1exIs6JgEFYfXlu6E5f4B5R3I2D8v0
a=ssrc:3452335690 mslabel:9kTlKaNe1exIs6JgEFYfXlu6E5f4B5R3I2D8
a=ssrc:3452335690 label:9kTlKaNe1exIs6JgEFYfXlu6E5f4B5R3I2D8v0

Ziet u iets dat een andere klant kan helpen verbinding te maken met mijn machine? Ik denk het niet. Het doel van al dit ICE-mechanisme is om verbindingskandidaten te verzamelen (zoals lokale 192.168.1.15, "openbare" (de publieke IP toegewezen door uw ISP) met behulp van STUN als u achter een willekeurige NAT zit die niet symmetrisch is, of DRAAIEN voor symmetrische NAT's).

Na ontvangst van die ICE-kandidaten, bestelt de andere peer ze met behulp van een aantal vooraf gedefinieerde statistieken voor het stellen van prioriteiten en geeft vervolgens verbindingstests uit om een ​​goede kandidaat te vinden. Dus deel ze alsjeblieft: de andere peer heeft ze nodig (en jij hebt die ook nodig).

Dus hier zijn enkele van mijn ICE-kandidaten:

a=candidate:303249700 1 udp 2113937151 192.168.50.238 43806 typ host generation 0
a=candidate:303249700 2 udp 2113937151 192.168.50.238 43806 typ host generation 0
a=candidate:1552991700 1 tcp 1509957375 192.168.50.238 35630 typ host generation 0

Nu zijn die concrete (zij het alleen lokaal, omdat ik de RTC-peerverbinding met een willekeurige STUN-URL niet heb geconfigureerd) manieren voor een andere peer om verbinding te maken met mijn machine.

WebRTC-signaleringstips

Er zijn een paar interessante tips op de bodem van deze pagina. Ik kon je op dit moment niet vertellen waarom je die moest volgen of waarom ze in de eerste plaats bestonden, maar ik volgde ze en had geen signaleringproblemen. Daar zijn ze:

  1. Voor de antwoordgever: voeg nooit ICE-kandidaten toe totdat die peer een SDP voor antwoorden genereert / creëert
  2. Stop met het toevoegen van ICE-kandidaten wanneer de stream op afstand begint te stromen
  3. Maak geen peer-verbinding voor een antwoordapparaat totdat u SDP-aanbieding ontvangt

U kunt dat alles aan de clientzijde beheren door een of andere WebRTC-machine met beperkte status te hebben. Zie de pagina waarnaar wordt verwezen om te begrijpen waarmee hij bedoelt externe stream begint te stromen.

Probeer ICE-kandidaten te delen en voeg ze aan de andere kant toe en volg ten minste de tips # 1 en # 3 en uw applicatie zou opnieuw moeten werken.

Signalering van communicatie

U vroeg hoe een ICE-kandidaat van een peer naar een andere kan worden overgedragen in het geval dat ICE-kandidaten belangrijk zijn om te delen (wat ze zijn). Om dingen te delen met AJAX, wat die dingen dan ook zijn, kunt u postvakken gebruiken. Ik geloof dat je dit al doet door de klant in de database te plaatsen.

Wanneer een peer iets naar een andere moet verzenden, verzend het dan zo snel mogelijk (met AJAX). Plaats deze "mail" op de server in de mailbox van de bestemmingsclient. Wanneer een peer (periodiek) polls van de server voor nieuwe e-mails, geef het allemaal zijn nieuwe e-mails.

Wanneer een SDP-aanbieding wordt aangemaakt, worden ICE-kandidaten snel gegenereerd. Al die ICE-kandidaten en de SDP-beschrijving komen waarschijnlijk binnen enkele milliseconden in de doel-mailbox terecht. Er zijn goede kansen dat de bestemmings-peer alles in één keer zal vragen. Zelfs als een ICE-kandidaat laat arriveert, zal zijn volgende polling het krijgen.


12
2018-06-18 15:17



Dit beantwoordt niet echt uw vragen, maar voor een signalerende server die u misschien wilt bekijken Socket.io (op knooppunt). Ik heb een codelab geschreven waarin uitgelegd wordt hoe je dit opzet:bitbucket.org/webrtc/codelab. Het is heel eenvoudig - het complete voorbeeld is hier: de signalisatie-servercode is ongeveer 50 regels.

SimpleWebRTC loopt het Signalmaster server, die Socket.io gebruikt.

(Robert Nyman schreef een goed blogpost dit uitleggen.)

Een andere optie is om XHR te gebruiken met de Google Channel API, volgens de apprtc.appspot.com voorbeeld: code hier.


3
2018-06-20 12:51



Elke manier om berichten te verzenden zou op dezelfde manier moeten werken. Het helpt misschien om in gedachten te houden dat slechts ongeveer 4 standaardberichten zijn die u wilt uitwisselen:

  1. melding dat een peer is toegetreden (of vertrokken)
  2. een aanbiedingsbericht ==> SetRemoteDescription ermee, maak dan een antwoord en verstuur het
  3. een antwoordbericht ===> SetRemoteDescription ermee
  4. een ijskandidaat gestuurd door de andere peer ==> oproep addIceCandidate ermee

Het ijskandidaat-ding is het vreemde deel. Het kandidaat-object bevat ook vreemde tekens, dus wanneer u het verzendt, codeert URI dit. In Coffeescript ziet de mijn er ongeveer zo uit:

peer_connection.onicecandidate = (e) ->
   send { 
          line_index: e.candidate.sdpMLineIndex
          candidate: encodeURIComponent(e.candidate.candidate) }

Het antwoord van eepp is goed, maar het bevat een aantal adviezen waarvan ik denk dat het niet juist is. In het bijzonder zijn deze 3 tips volgens mij allemaal onjuist:

  • Voor de antwoordgever: voeg nooit ICE-kandidaten toe tot die peer   genereert / creëert antwoord-SDP
  • Stop met het toevoegen van ICE-kandidaten op afstand   stream begint te stromen
  • Maak geen peer-verbinding voor antwoordapparaat tot   je krijgt een aanbod SDP

Hier is een reeks gebeurtenissen die ik vandaag (februari 2014) in Chrome heb uitgevoerd. Dit is voor een vereenvoudigd geval waarbij peer 1 video naar peer 2 streamt.

  1. Stel een manier in voor de peers om berichten uit te wisselen. (De variatie in hoe mensen dit bereiken, maakt verschillende WebRTC-codevoorbeelden zo onvergelijkelijk, helaas. Maar probeer mentaal en in uw code-organisatie deze logica van de rest te scheiden.)
  2. Stel aan beide zijden berichtbehandelaars in voor de belangrijke signalisatieberichten. Je kunt ze instellen en ze achterlaten. Er zijn 4 kernboodschappen om te verwerken en verzenden:
    • andere peers zijn toegetreden
    • een ijskandidaat verzonden vanaf de andere kant ==> bellen addIceCandidate ermee
    • een aanbiedingsbericht ==> SetRemoteDescription ermee, maak dan een antwoord en verstuur het
    • een antwoordbericht ===> SetRemoteDescription ermee
  3. Maak aan beide zijden een nieuw peerconnection-object en voeg event-handlers eraan toe voor belangrijke evenementen: onicecandidate, onremovestream, onaddstream, enz.
    • ijskandidaat ===> stuur het naar de andere kant
    • stream toegevoegd ===> bevestig het aan een video-element zodat je het kunt zien
  4. Wanneer beide peers aanwezig zijn en alle handlers op hun plaats zitten, krijgt peer 1 een trigger-bericht van een of andere soort om video-opname te starten (met behulp van de getUserMedia call)
  5. Een keer getUserMedia slaagt, we hebben een stream. telefoontje addStream op het peerverbindingsobject van de peer 1.
  6. Dan - en alleen dan - maakt peer 1 een aanbod
  7. Vanwege de handlers die we in stap 2 hebben opgezet, krijgt peer 2 dit en stuurt hij een antwoord
  8. Gelijktijdig hiermee (en enigszins obscuur) begint het peer-verbindingsobject ijskandidaten te produceren. Ze worden heen en weer gestuurd tussen de twee peers en verwerkt (stappen 2 & 3 hierboven)
  9. Streaming begint op zichzelf, ondoorzichtig, als gevolg van 2 voorwaarden:
    • aanbod / antwoord uitwisseling
    • ijskandidaten ontvangen, ingewisseld en toegevoegd

Ik heb geen manier gevonden om video toe te voegen na stap 9. Als ik iets wil veranderen, ga ik terug naar stap 3.


2
2018-02-06 19:05