WebRTC + WebSocket

用JS享受視訊的美好

Presented by Shih-En Chou

WebSockets

WebSockets

在瀏覽器內
提供一個protocol讓Client與Server端做雙向溝通

支援度
Chrome Desktop 23+, Firefox 22+, Opera 18+, Chrome 29+, Opera Mobile 12+
This is a developing standard in webpages to get data from your webcam and your microphone.

為什麼Logo五彩繽紛?

WebSockets

Client opens connection with server

Client and server send data to each other as data becomes available on either side

Create Sockets(Client Side)


  var connection = new WebSocket('ws://subdomain.examnple.com/some-endpoint')
            

WebSocket events(Client Side) and Method


connection.onopen = function(e) {
  console.log("Connected");
};

connection.onmessage = function(e) {
  console.log( "Received: " + e.data);
};

connection.onclose = function(e) {
  console.log("Connection closed");
};

connection.send("這是伺服器正迫切需要的文字!");
                        

Cross-domain

WebSockets is cross-domain by default

Up to you to optionally restrict domain access on server via Origin header

Extensibility

Built-in method for defining WebSocket extensions via RFC

Current extensions include perframe-deflate and multiplexing

Proxies

Using ws in production can cause WebSockets communication to fail due to invisible proxies that can't do WebSockets

Using wss forces browser to issue HTTP_CONNECT statement to proxy server, which sets up tunnel

So use wss in production

Server-Side Support

Socket.IO

已經做出限定Event, 讓Message 根據Bind Event來傳遞訊息

WebRTC

WebRTC 是P2P

一群人在立法院也可以收看

Initialize Connection


pc = new RTCPeerConnection(configuration);

pc.onnegotiationneeded = function () {
    pc.createOffer(localDescCreated, logError);
}

                        

Build Connection



//offer
pc.setLocalDescription(desc, function () {
  socket.emit('sendrtc', JSON.stringify({
    'sdp': pc.localDescription
  }));

}, logError);

//answer
pc.setRemoteDescription(new RTCSessionDescription(message.sdp), 
	function () {
  // if we received an offer, we need to answer
  if (pc.remoteDescription.type == 'offer')
    pc.createAnswer(localDescCreated, logError);
}, logError);

//Candidate:
pc.addIceCandidate(new RTCIceCandidate(message.candidate));

                        

WebRTC 的痛苦點...

  1. Offer 和 Answer 原則上是不同session
  2. 建立聊天室, 總共有N*(N-1)/2 個 Connection
  3. RTCPeerConnection 貌似Chrome 不work
  4. 你需要一個 adapter

STUN Server

STUN: Session Traversal Utilities for NAT
Build your own stun server: http://www.stunprotocol.org/

那傳檔案呢

HTML5 有了Blob API

直接把WebSocket 與Blob 接起來就好了


                    var img = canvas_context.getImageData(0, 0, 400, 320);
var binary = new Uint8Array(img.data.length);
for (var i = 0; i < img.data.length; i++) {
  binary[i] = img.data[i];
}
connection.send(binary.buffer);


                    var file = document.querySelector('input[type="file"]').files[0];
connection.send(file);
WebSockets WebRTC
方便broadcast 1-to-1 Connection
傳文字, blob 傳stream
方便debug 不易找錯...

P2P 傳文字呢?

RTCDataChannel


offerer = new RTCPeerConnection(configuration);


var channel = offerer.createDataChannel('RTCDataChannel', {
    reliable: false
});
channel.onmessage = function (event) {
    console.debug(channelNameForConsoleOutput, 
    'received a message:', event.data);
};

channel.onopen = function () {
    channel.send('first text message over RTP data ports');
};

channel.send("Hello Server!");
                     

THE END

Follow me on Github@Shih-En Chou

Reference

https://www.websocket.org/quantum.html
http://www.webrtc.org/
http://os.alfajango.com/websockets-slides/
http://en.wikipedia.org/wiki/Session_Description_Protocol
http://dev.w3.org/2011/webrtc/editor/webrtc.html#peer-to-peer-data-api
https://www.webrtc-experiment.com/docs/rtc-datachannel-for-beginners.html