RTCPeerConnection API является ядром однорангового соединения между каждым из браузеров. Для создания объектов RTCPeerConnection просто напишите
var pc = RTCPeerConnection(config);
где аргумент config содержит хотя бы ключ, iceServers. Это массив объектов URL, содержащих информацию о серверах STUN и TURN, используемых при поиске кандидатов на ICE. Вы можете найти список доступных общедоступных серверов STUN на code.google.com.
В зависимости от того, являетесь ли вы абонентом или вызываемым абонентом, объект RTCPeerConnection используется немного по-разному на каждой стороне соединения.
Вот пример потока пользователя —
-
Зарегистрируйте обработчик onicecandidate . Он отправляет кандидатов ICE другому партнеру по мере их поступления.
-
Зарегистрируйте обработчик onaddstream . Он управляет отображением видеопотока после его получения от удаленного узла.
-
Зарегистрируйте обработчик сообщений . Ваш сервер сигнализации также должен иметь обработчик для сообщений, полученных от другого партнера. Если сообщение содержит объект RTCSessionDescription , его следует добавить в объект RTCPeerConnection с помощью метода setRemoteDescription () . Если сообщение содержит объект RTCIceCandidate , его следует добавить в объект RTCPeerConnection с помощью метода addIceCandidate () .
-
Используйте getUserMedia (), чтобы настроить локальный поток мультимедиа и добавить его в объект RTCPeerConnection с помощью метода addStream () .
-
Начать процесс предложения / ответа. Это единственный шаг, когда поток звонящего отличается от потока звонящего. Вызывающая сторона начинает согласование с помощью метода createOffer () и регистрирует обратный вызов, который получает объект RTCSessionDescription . Затем этот обратный вызов должен добавить этот объект RTCSessionDescription к вашему объекту RTCPeerConnection с помощью setLocalDescription () . И, наконец, вызывающая сторона должна отправить эту RTCSessionDescription удаленному узлу с помощью сервера сигнализации. Вызываемый, с другой стороны, регистрирует тот же обратный вызов, но в методе createAnswer () . Обратите внимание, что поток вызываемого абонента инициируется только после получения предложения от вызывающего абонента.
Зарегистрируйте обработчик onicecandidate . Он отправляет кандидатов ICE другому партнеру по мере их поступления.
Зарегистрируйте обработчик onaddstream . Он управляет отображением видеопотока после его получения от удаленного узла.
Зарегистрируйте обработчик сообщений . Ваш сервер сигнализации также должен иметь обработчик для сообщений, полученных от другого партнера. Если сообщение содержит объект RTCSessionDescription , его следует добавить в объект RTCPeerConnection с помощью метода setRemoteDescription () . Если сообщение содержит объект RTCIceCandidate , его следует добавить в объект RTCPeerConnection с помощью метода addIceCandidate () .
Используйте getUserMedia (), чтобы настроить локальный поток мультимедиа и добавить его в объект RTCPeerConnection с помощью метода addStream () .
Начать процесс предложения / ответа. Это единственный шаг, когда поток звонящего отличается от потока звонящего. Вызывающая сторона начинает согласование с помощью метода createOffer () и регистрирует обратный вызов, который получает объект RTCSessionDescription . Затем этот обратный вызов должен добавить этот объект RTCSessionDescription к вашему объекту RTCPeerConnection с помощью setLocalDescription () . И, наконец, вызывающая сторона должна отправить эту RTCSessionDescription удаленному узлу с помощью сервера сигнализации. Вызываемый, с другой стороны, регистрирует тот же обратный вызов, но в методе createAnswer () . Обратите внимание, что поток вызываемого абонента инициируется только после получения предложения от вызывающего абонента.
RTCPeerConnection API
свойства
-
RTCPeerConnection.iceConnectionState (только для чтения) — возвращает перечисление RTCIceConnectionState, которое описывает состояние соединения. Событие iceconnectionstatechange вызывается при изменении этого значения. Возможные значения —
-
новый — агент ICE ждет удаленных кандидатов или собирает адреса
-
проверка — у агента ICE есть удаленные кандидаты, но он еще не нашел соединение
-
подключен — агент ICE обнаружил пригодное для использования соединение, но все еще проверяет более удаленного кандидата на лучшее соединение.
-
завершено — агент ICE нашел работоспособное соединение и прекратил тестирование удаленных кандидатов.
-
ошибка — агент ICE проверил все удаленные кандидаты, но не нашел соответствия хотя бы для одного компонента.
-
отключен — хотя бы один компонент больше не работает.
-
закрыт — агент ICE закрыт.
-
-
RTCPeerConnection.iceGatheringState (только для чтения) — возвращает перечисление RTCIceGatheringState, которое описывает состояние сбора ICE для соединения.
-
новый — объект был только что создан.
-
сбор — агент ICE находится в процессе сбора кандидатов
-
завершить ICE агент завершил сбор.
-
-
RTCPeerConnection.localDescription (только для чтения) — возвращает описание RTCSessionDescription, описывающее локальный сеанс. Он может быть нулевым, если он еще не установлен.
-
RTCPeerConnection.peerIdentity (только для чтения) — возвращает RTCIdentityAssertion. Он состоит из idp (доменного имени) и имени, представляющего личность удаленного партнера.
-
RTCPeerConnection.remoteDescription (только для чтения) — возвращает описание RTCSessionDescription, описывающее удаленный сеанс. Он может быть нулевым, если он еще не установлен.
-
RTCPeerConnection.signalingState (только для чтения) — возвращает перечисление RTCSignalingState, которое описывает состояние сигнализации локального соединения. Это состояние описывает предложение SDP. Событие signalingstatechange вызывается при изменении этого значения. Возможные значения —
-
стабильный — начальное состояние. В настоящее время обмен предложениями и ответами SDP не осуществляется.
-
have-local-offer — локальная сторона соединения локально применила предложение SDP.
-
have-remote-offer — удаленная сторона соединения локально применила предложение SDP.
-
have-local-pranswer — удаленное предложение SDP было применено, а локальный pranswer SDP.
-
have-remote-pranswer — применен локальный SDP, а удаленный SDP.
-
закрыто — соединение закрыто.
-
RTCPeerConnection.iceConnectionState (только для чтения) — возвращает перечисление RTCIceConnectionState, которое описывает состояние соединения. Событие iceconnectionstatechange вызывается при изменении этого значения. Возможные значения —
новый — агент ICE ждет удаленных кандидатов или собирает адреса
проверка — у агента ICE есть удаленные кандидаты, но он еще не нашел соединение
подключен — агент ICE обнаружил пригодное для использования соединение, но все еще проверяет более удаленного кандидата на лучшее соединение.
завершено — агент ICE нашел работоспособное соединение и прекратил тестирование удаленных кандидатов.
ошибка — агент ICE проверил все удаленные кандидаты, но не нашел соответствия хотя бы для одного компонента.
отключен — хотя бы один компонент больше не работает.
закрыт — агент ICE закрыт.
RTCPeerConnection.iceGatheringState (только для чтения) — возвращает перечисление RTCIceGatheringState, которое описывает состояние сбора ICE для соединения.
новый — объект был только что создан.
сбор — агент ICE находится в процессе сбора кандидатов
завершить ICE агент завершил сбор.
RTCPeerConnection.localDescription (только для чтения) — возвращает описание RTCSessionDescription, описывающее локальный сеанс. Он может быть нулевым, если он еще не установлен.
RTCPeerConnection.peerIdentity (только для чтения) — возвращает RTCIdentityAssertion. Он состоит из idp (доменного имени) и имени, представляющего личность удаленного партнера.
RTCPeerConnection.remoteDescription (только для чтения) — возвращает описание RTCSessionDescription, описывающее удаленный сеанс. Он может быть нулевым, если он еще не установлен.
RTCPeerConnection.signalingState (только для чтения) — возвращает перечисление RTCSignalingState, которое описывает состояние сигнализации локального соединения. Это состояние описывает предложение SDP. Событие signalingstatechange вызывается при изменении этого значения. Возможные значения —
стабильный — начальное состояние. В настоящее время обмен предложениями и ответами SDP не осуществляется.
have-local-offer — локальная сторона соединения локально применила предложение SDP.
have-remote-offer — удаленная сторона соединения локально применила предложение SDP.
have-local-pranswer — удаленное предложение SDP было применено, а локальный pranswer SDP.
have-remote-pranswer — применен локальный SDP, а удаленный SDP.
закрыто — соединение закрыто.
Обработчики событий
S.No. | Обработчики событий и описание |
---|---|
1 |
RTCPeerConnection.onaddstream Этот обработчик вызывается при возникновении события addstream. Это событие отправляется, когда MediaStream добавляется к этому соединению удаленным узлом. |
2 |
RTCPeerConnection.ondatachannel Этот обработчик вызывается при запуске события канала данных. Это событие отправляется, когда RTCDataChannel добавляется к этому соединению. |
3 |
RTCPeerConnection.onicecandidate Этот обработчик вызывается при запуске события icecandidate. Это событие отправляется, когда объект RTCIceCandidate добавляется в сценарий. |
4 |
RTCPeerConnection.oniceconnectionstatechange Этот обработчик вызывается при запуске события iceconnectionstatechange. Это событие отправляется при изменении значения iceConnectionState. |
5 |
RTCPeerConnection.onidentityresult Этот обработчик вызывается при возникновении события identityresult. Это событие отправляется, когда создается удостоверение личности во время создания предложения или ответа через getIdentityAssertion (). |
6 |
RTCPeerConnection.onidpassertionerror Этот обработчик вызывается при возникновении события idpassertionerror. Это событие отправляется, когда IdP (поставщик идентификаторов) обнаруживает ошибку при создании подтверждения личности. |
7 |
RTCPeerConnection.onidpvalidation Этот обработчик вызывается при возникновении события idpvalidationerror. Это событие отправляется, когда IdP (Identitry Provider) обнаруживает ошибку при проверке подтверждения личности. |
8 |
RTCPeerConnection.onnegotiationneeded Этот обработчик вызывается при возникновении события с необходимостью согласования. Это событие отправляется браузером, чтобы сообщить, что переговоры потребуются в какой-то момент в будущем. |
9 |
RTCPeerConnection.onpeeridentity Этот обработчик вызывается, когда происходит событие peeridentity. Это событие отправляется, когда в этом соединении установлена и проверена идентификация однорангового узла. |
10 |
RTCPeerConnection.onremovestream Этот обработчик вызывается при возникновении события signalingstatechange. Это событие отправляется при изменении значения signalingState. |
11 |
RTCPeerConnection.onsignalingstatechange Этот обработчик вызывается при возникновении события removestream. Это событие отправляется, когда MediaStream удаляется из этого соединения. |
RTCPeerConnection.onaddstream
Этот обработчик вызывается при возникновении события addstream. Это событие отправляется, когда MediaStream добавляется к этому соединению удаленным узлом.
RTCPeerConnection.ondatachannel
Этот обработчик вызывается при запуске события канала данных. Это событие отправляется, когда RTCDataChannel добавляется к этому соединению.
RTCPeerConnection.onicecandidate
Этот обработчик вызывается при запуске события icecandidate. Это событие отправляется, когда объект RTCIceCandidate добавляется в сценарий.
RTCPeerConnection.oniceconnectionstatechange
Этот обработчик вызывается при запуске события iceconnectionstatechange. Это событие отправляется при изменении значения iceConnectionState.
RTCPeerConnection.onidentityresult
Этот обработчик вызывается при возникновении события identityresult. Это событие отправляется, когда создается удостоверение личности во время создания предложения или ответа через getIdentityAssertion ().
RTCPeerConnection.onidpassertionerror
Этот обработчик вызывается при возникновении события idpassertionerror. Это событие отправляется, когда IdP (поставщик идентификаторов) обнаруживает ошибку при создании подтверждения личности.
RTCPeerConnection.onidpvalidation
Этот обработчик вызывается при возникновении события idpvalidationerror. Это событие отправляется, когда IdP (Identitry Provider) обнаруживает ошибку при проверке подтверждения личности.
RTCPeerConnection.onnegotiationneeded
Этот обработчик вызывается при возникновении события с необходимостью согласования. Это событие отправляется браузером, чтобы сообщить, что переговоры потребуются в какой-то момент в будущем.
RTCPeerConnection.onpeeridentity
Этот обработчик вызывается, когда происходит событие peeridentity. Это событие отправляется, когда в этом соединении установлена и проверена идентификация однорангового узла.
RTCPeerConnection.onremovestream
Этот обработчик вызывается при возникновении события signalingstatechange. Это событие отправляется при изменении значения signalingState.
RTCPeerConnection.onsignalingstatechange
Этот обработчик вызывается при возникновении события removestream. Это событие отправляется, когда MediaStream удаляется из этого соединения.
методы
S.No. | Методы и описание |
---|---|
1 |
RTCPeerConnection () Возвращает новый объект RTCPeerConnection. |
2 |
RTCPeerConnection.createOffer () Создает предложение (запрос) на поиск удаленного партнера. Двумя первыми параметрами этого метода являются обратные вызовы успешности и ошибок. Необязательный третий параметр — это параметры, такие как включение аудио или видео потоков. |
3 |
RTCPeerConnection.createAnswer () Создает ответ на предложение, полученное удаленным узлом в процессе согласования предложения / ответа. Двумя первыми параметрами этого метода являются обратные вызовы успешности и ошибок. Необязательный третий параметр — это варианты ответа, который будет создан. |
4 |
RTCPeerConnection.setLocalDescription () Изменяет описание локального соединения. Описание определяет свойства соединения. Соединение должно поддерживать как старые, так и новые описания. Метод принимает три параметра: объект RTCSessionDescription, обратный вызов, если изменение описания выполнено успешно, обратный вызов, если изменение описания не удается. |
5 |
RTCPeerConnection.setRemoteDescription () Изменяет описание удаленного соединения. Описание определяет свойства соединения. Соединение должно поддерживать как старые, так и новые описания. Метод принимает три параметра: объект RTCSessionDescription, обратный вызов, если изменение описания выполнено успешно, обратный вызов, если изменение описания не удается. |
6 |
RTCPeerConnection.updateIce () Обновляет процесс агента ICE для проверки связи с удаленными кандидатами и сбора локальных кандидатов. |
7 |
RTCPeerConnection.addIceCandidate () Предоставляет удаленного кандидата агенту ICE. |
8 |
RTCPeerConnection.getConfiguration () Возвращает объект RTCConfiguration. Он представляет конфигурацию объекта RTCPeerConnection. |
9 |
RTCPeerConnection.getLocalStreams () Возвращает массив локального соединения MediaStream. |
10 |
RTCPeerConnection.getRemoteStreams () Возвращает массив удаленного соединения MediaStream. |
11 |
RTCPeerConnection.getStreamById () Возвращает локальный или удаленный MediaStream по заданному идентификатору. |
12 |
RTCPeerConnection.addStream () Добавляет MediaStream в качестве локального источника видео или аудио. |
13 |
RTCPeerConnection.removeStream () Удаляет MediaStream как локальный источник видео или аудио. |
14 |
RTCPeerConnection.close () Закрывает соединение. |
15 |
RTCPeerConnection.createDataChannel () Создает новый RTCDataChannel. |
16 |
RTCPeerConnection.createDTMFSender () Создает новый RTCDTMFSender, связанный с конкретным MediaStreamTrack. Позволяет отправлять DTMF (двухтональные многочастотные) телефонные сигналы по соединению. |
17 |
RTCPeerConnection.getStats () Создает новый RTCStatsReport, который содержит статистику, касающуюся соединения. |
18 |
RTCPeerConnection.setIdentityProvider () Устанавливает IdP. Принимает три параметра — имя, протокол, используемый для связи, и необязательное имя пользователя. |
19 |
RTCPeerConnection.getIdentityAssertion () Собирает утверждение личности. Не ожидается, чтобы иметь дело с этим методом в приложении. Таким образом, вы можете назвать это явно, только чтобы предвидеть необходимость. |
RTCPeerConnection ()
Возвращает новый объект RTCPeerConnection.
RTCPeerConnection.createOffer ()
Создает предложение (запрос) на поиск удаленного партнера. Двумя первыми параметрами этого метода являются обратные вызовы успешности и ошибок. Необязательный третий параметр — это параметры, такие как включение аудио или видео потоков.
RTCPeerConnection.createAnswer ()
Создает ответ на предложение, полученное удаленным узлом в процессе согласования предложения / ответа. Двумя первыми параметрами этого метода являются обратные вызовы успешности и ошибок. Необязательный третий параметр — это варианты ответа, который будет создан.
RTCPeerConnection.setLocalDescription ()
Изменяет описание локального соединения. Описание определяет свойства соединения. Соединение должно поддерживать как старые, так и новые описания. Метод принимает три параметра: объект RTCSessionDescription, обратный вызов, если изменение описания выполнено успешно, обратный вызов, если изменение описания не удается.
RTCPeerConnection.setRemoteDescription ()
Изменяет описание удаленного соединения. Описание определяет свойства соединения. Соединение должно поддерживать как старые, так и новые описания. Метод принимает три параметра: объект RTCSessionDescription, обратный вызов, если изменение описания выполнено успешно, обратный вызов, если изменение описания не удается.
RTCPeerConnection.updateIce ()
Обновляет процесс агента ICE для проверки связи с удаленными кандидатами и сбора локальных кандидатов.
RTCPeerConnection.addIceCandidate ()
Предоставляет удаленного кандидата агенту ICE.
RTCPeerConnection.getConfiguration ()
Возвращает объект RTCConfiguration. Он представляет конфигурацию объекта RTCPeerConnection.
RTCPeerConnection.getLocalStreams ()
Возвращает массив локального соединения MediaStream.
RTCPeerConnection.getRemoteStreams ()
Возвращает массив удаленного соединения MediaStream.
RTCPeerConnection.getStreamById ()
Возвращает локальный или удаленный MediaStream по заданному идентификатору.
RTCPeerConnection.addStream ()
Добавляет MediaStream в качестве локального источника видео или аудио.
RTCPeerConnection.removeStream ()
Удаляет MediaStream как локальный источник видео или аудио.
RTCPeerConnection.close ()
Закрывает соединение.
RTCPeerConnection.createDataChannel ()
Создает новый RTCDataChannel.
RTCPeerConnection.createDTMFSender ()
Создает новый RTCDTMFSender, связанный с конкретным MediaStreamTrack. Позволяет отправлять DTMF (двухтональные многочастотные) телефонные сигналы по соединению.
RTCPeerConnection.getStats ()
Создает новый RTCStatsReport, который содержит статистику, касающуюся соединения.
RTCPeerConnection.setIdentityProvider ()
Устанавливает IdP. Принимает три параметра — имя, протокол, используемый для связи, и необязательное имя пользователя.
RTCPeerConnection.getIdentityAssertion ()
Собирает утверждение личности. Не ожидается, чтобы иметь дело с этим методом в приложении. Таким образом, вы можете назвать это явно, только чтобы предвидеть необходимость.
Установление соединения
Теперь давайте создадим пример приложения. Во-первых, запустите сервер сигнализации, который мы создали в руководстве «Сервер сигнализации», через «сервер узла».
На странице будет два текстовых ввода: один для логина и один для имени пользователя, к которому мы хотим подключиться. Создайте файл index.html и добавьте следующий код —
<html lang = "en"> <head> <meta charset = "utf-8" /> </head> <body> <div> <input type = "text" id = "loginInput" /> <button id = "loginBtn">Login</button> </div> <div> <input type = "text" id = "otherUsernameInput" /> <button id = "connectToOtherUsernameBtn">Establish connection</button> </div> <script src = "client2.js"></script> </body> </html>
Вы можете видеть, что мы добавили ввод текста для входа в систему, кнопку входа в систему, ввод текста для имени другого однорангового пользователя и кнопку подключения к нему. Теперь создайте файл client.js и добавьте следующий код —
var connection = new WebSocket('ws://localhost:9090'); var name = ""; var loginInput = document.querySelector('#loginInput'); var loginBtn = document.querySelector('#loginBtn'); var otherUsernameInput = document.querySelector('#otherUsernameInput'); var connectToOtherUsernameBtn = document.querySelector('#connectToOtherUsernameBtn'); var connectedUser, myConnection; //when a user clicks the login button loginBtn.addEventListener("click", function(event){ name = loginInput.value; if(name.length > 0){ send({ type: "login", name: name }); } }); //handle messages from the server connection.onmessage = function (message) { console.log("Got message", message.data); var data = JSON.parse(message.data); switch(data.type) { case "login": onLogin(data.success); break; case "offer": onOffer(data.offer, data.name); break; case "answer": onAnswer(data.answer); break; case "candidate": onCandidate(data.candidate); break; default: break; } }; //when a user logs in function onLogin(success) { if (success === false) { alert("oops...try a different username"); } else { //creating our RTCPeerConnection object var configuration = { "iceServers": [{ "url": "stun:stun.1.google.com:19302" }] }; myConnection = new webkitRTCPeerConnection(configuration); console.log("RTCPeerConnection object was created"); console.log(myConnection); //setup ice handling //when the browser finds an ice candidate we send it to another peer myConnection.onicecandidate = function (event) { if (event.candidate) { send({ type: "candidate", candidate: event.candidate }); } }; } }; connection.onopen = function () { console.log("Connected"); }; connection.onerror = function (err) { console.log("Got error", err); }; // Alias for sending messages in JSON format function send(message) { if (connectedUser) { message.name = connectedUser; } connection.send(JSON.stringify(message)); };
Вы можете видеть, что мы устанавливаем сокет-соединение с нашим сигнальным сервером. Когда пользователь нажимает кнопку входа в систему, приложение отправляет свое имя пользователя на сервер. Если вход выполнен успешно, приложение создает объект RTCPeerConnection и настраивает обработчик onicecandidate, который отправляет все найденные icecandidates другому партнеру. Теперь откройте страницу и попробуйте войти. Вы должны увидеть следующий вывод консоли —
Следующим шагом является создание предложения для другого партнера. Добавьте следующий код в ваш файл client.js —
//setup a peer connection with another user connectToOtherUsernameBtn.addEventListener("click", function () { var otherUsername = otherUsernameInput.value; connectedUser = otherUsername; if (otherUsername.length > 0) { //make an offer myConnection.createOffer(function (offer) { console.log(); send({ type: "offer", offer: offer }); myConnection.setLocalDescription(offer); }, function (error) { alert("An error has occurred."); }); } }); //when somebody wants to call us function onOffer(offer, name) { connectedUser = name; myConnection.setRemoteDescription(new RTCSessionDescription(offer)); myConnection.createAnswer(function (answer) { myConnection.setLocalDescription(answer); send({ type: "answer", answer: answer }); }, function (error) { alert("oops...error"); }); } //when another user answers to our offer function onAnswer(answer) { myConnection.setRemoteDescription(new RTCSessionDescription(answer)); } //when we got ice candidate from another user function onCandidate(candidate) { myConnection.addIceCandidate(new RTCIceCandidate(candidate)); }
Вы можете видеть, что когда пользователь нажимает кнопку «Установить соединение», приложение делает предложение SDP другому партнеру. Мы также устанавливаем обработчики onAnswer и onCandidate . Перезагрузите страницу, откройте ее на двух вкладках, войдите с двумя пользователями и попытайтесь установить связь между ними. Вы должны увидеть следующий вывод консоли —
Теперь одноранговое соединение установлено. В следующих уроках мы добавим видео и аудио потоки, а также поддержку текстового чата.