using groovy to empower webrtc network systems
TRANSCRIPT
Using Groovy to empower WebRTC Network Systems
Antón R. Yuste
@antonmry
Agenda● What is (and isn't WebRTC) ● Developing your own WebRTC service● Groovy & Network Systems● TADHack 2015
Once upon a time...
Forever
There was a time...● Where we use to see video by using plug-ins and external software ● Instant Messaging was delivered using the same concepts and Voice = Telephony● Suddenly everything changed
WebRTC @ Glance
WebRTC offers real time communication natively from a web browser
WebRTC @ Glance
WebRTC capable browser share, including
Mobile, Tablet and desktop
61 %
WebRTC @ Glance
WebRTC is a “MediaEngine” with
javascript API API
WebRTC @ Glance
WebRTC is a technology, NOT a solution,
AND open source projects too
So, what is WebRTC?
● A built-in application program interface that enables browser-to-browser applications for:
● voice calling
● video chat
● peer to peer of any data
● Media engine in the browser, accessed by JavaScript, downloaded from web-server.● Collaborative W3C and IETF standardization
The WebRTC tree
IMS, LTE
WWW
VoIP
So, what is WebRTC - Technically Speaking?
PEER CONNECTION
(AUDIO, VIDEO, DATA)
WEB SERVER
(WEBRTC CONTROL)
GATEWAY
PEER CONNECTION
(AUDIO, VIDEO, DATA)
PEER CONNECTION
(AUDIO, VIDEO, DATA)
WEB SERVER
(WEBRTC CONTROL)
What isn't WebRTC - Technically Speaking?
● No MTI coded media● No defined signaling mechanism
It's a Standard Specification and an
opensource project
Signaling – The Two Approach
SIP over WebSockets JSON over WebSockets
Why JSON, XMPP, * and not SIP? ● Much more easy ● There are more developers ● Language of the web● And it’s natively supported by browser● Drives more SIP into the network
WebRTC Browser Support: Desktop
WebRTC Regional Browser Support: Desktop
A new Sheriff in town ● August 20, 2014. Microsoft published a blog post publicly supporting the ORCT draft.
Browser support
WebRTC Browser Support: Mobile
Consideration
● Lack of WebRTC Support: ● SDK/library for Windows Phone and IOS devices
● Hardware support for Mobile Phone ● Software encoding & decoding will kill your battery for VP8
● New device will benefits from power processor● Snapdragon 800 4 ● nVidia Tegra 4
Where we are now?
Is WebRTC ready?
… and more!
Major WebRTC Standard APIs
Acquire audio/video
Communicate Media
Communicate Data
MediaStream/getUserMedia
RTCPeerConnection
RTCDataChannel
MediaStream
● Represents a stream of audio/video (stream from camera/mike)● Multiple Tracks ● Use navigator.getUserMedia()
MediaStream
var constraints = {video: true};function successCallback(stream) { var video = document.querySelector("video"); video.src = window.URL.createObjectURL(stream);}function errorCallback(error) { console.log("navigator.getUserMedia error: ", error);}navigator.getUserMedia(constraints, successCallback, errorCallback);
RTCPeerConnection
● Centre of WebRTC Standard API.
● Peer to Peer Communication● Codec, Security, bandwidth etc.
RTCPeerConnection
pc = new RTCPeerConnection(null);pc.onaddstream = gotRemoteStream;pc.addStream(localStream);pc.createOffer(gotOffer);
function gotOffer(desc) { pc.setLocalDescription(desc); sendOffer(desc);}
function gotAnswer(desc) { pc.setRemoteDescription(desc);}
function gotRemoteStream(e) { attachMediaStream(remoteVideo, e.stream);}
RTCDataChannel
● Arbitrary Data● File● Text● Games
● API Similar to WebSockets● Peer to Peer Data● Use SCTP
RTCDataChannel
var pc = new webkitRTCPeerConnection(servers, {optional: [{RtpDataChannels: true}]});
pc.ondatachannel = function(event) { receiveChannel = event.channel; receiveChannel.onmessage = function(event){ document.querySelector("div#receive").innerHTML = event.data; };};
sendChannel = pc.createDataChannel("sendDataChannel", {reliable: false});
document.querySelector("button#send").onclick = function (){ var data = document.querySelector("textarea#send").value; sendChannel.send(data);};
WebRTC Signaling
HTML App
Browser
HTML App
Browser
Session Description Protocol
Signaling? Signaling?
Media(RTCP/RTP)
Caller Callee
Session Description Protocol
WebRTC Offer/Answer Model
HTML App
Browser
HTML App
Browser
How ? How ?
Caller Callee
offer answer
ICE/STUN
Caller Calleemedia media
STUN
ICE/TURN
Caller Callee
media
STUN STUN
TURN TURN
The entire exchange in a complicated diagram
How to start using WebRTC API ?
Prerequisites
● Java 7● Maven 3.2+● Git● Your favorite IDE● Chrome browser● Internet Connection
Practice
git clone https://github.com/antonmry/SpringIOWebRTCSampleApp.git
ant jetty:run
Follow the mantra…● Java is Groovy, Groovy is Java.● Flat learning curve for Java developers, start with straight Java syntax then move on to a groovier syntax as you feel comfortable.● Almost 98% Java code is Groovy code, meaning you can in most changes rename *.java to *.groovy and it will work.
Template Engine maps messages in both
directions between applications and network
JSON TemplateEngine
SIP message
Application Network
Call
Flow
detail
Components and developer extension points
Template Engine configuration
PackageCriteria
Scripttemplate
Scripttemplate
Scripttemplate
Template Library
Criteria
Criteria
The Console Window
Package configuration
Inbound INVITE request
criteria
Inbound INVITE Request Template
TemplateContext passed as an argument
Using Script Library method
Creating a future task executed on successful ME response
Script Library
Groovy method specified in Inbound INVITE request template script
Groovy tips and tricks● Use “def” to declare variables and make them local: def b = "foo“.● Simplification of a getter method notation: def factory = context.webFactory // instead of context.getWebFactory()● Safe navigation operator (?.): def errorCode = context.webMessage?.header?.error_code● Check for a null object: if (context.webMessage?.payload?.sdp)
Groovy tips and tricks● Compile static @groovy.transform.CompileStatic (no dynamic types, compiles better and faster)● Iterators● ’as’ keyword● Closures● array and list operators * and *. – called ”spread” and ”spread-dot”● GPath – similar to xpath but runs on objects not xml
Groovy scripts troubleshooting● Add println statements and see output in the system out, e.g.: println “from=" + from● Use log4j and see output in wsc.log file, e.g. org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(getClass()) logger.info(“groovy info: from=“ + from)● When an exception is thrown within a Groovy script, a stack trace will be logged in the wsc.log file.
Groovy scripts troubleshooting
Groovy scripts troubleshooting
Caused by: groovy.lang.MissingPropertyException: No such property: sipReq for class: Script2 at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:50) at org.codehaus.groovy.runtime.callsite.PogoGetPropertySite.getProperty(PogoGetPropertySite.java:49) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGroovyObjectGetProperty(AbstractCallSite.java:231) at Script2.pkg_register_dir_FROM_APP_typ_request_verb_connect_netsvc_default(Script2.groovy:705) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90) at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1085) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:952) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:909) at groovy.lang.Closure.call(Closure.java:411) at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.callGlobal(GroovyScriptEngineImpl.java:411) at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.callGlobal(GroovyScriptEngineImpl.java:405) at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.invokeImpl(GroovyScriptEngineImpl.java:394) ...
Groovy scripts validation
Example SIP Request Variable// Create REGISTER requestdef from = getFromAddress(context)def to = getToAddress(context)def sipReq = context.sipFactory.createSipRequest("REGISTER", from, to) // Set request URIsipReq.requestURI = context.sipFactory.createSipAddress(Constants.PROXY_SIP_URI).URI // Set contact userif (from.URI?.user) { sipReq.setContactUser(from.URI.user)} // Set sip.instance to allow container to use SIP Outbound// for routing purposes as defined in RFC 5626def sipInstance = "\"<urn:uuid:" + java.util.UUID.randomUUID() + ">\""sipReq.setSipContactParameter("+sip.instance", sipInstance)sipReq.setSipContactParameter("reg-id", "1")context.subSessionStore.put("sip.instance", sipInstance)sipReq.send()
GRUUs
A GRUU (Globally Routable User-Agent URI) is a SIP URI which
has a few properties.
?
Example SIP Request Variable
sipReq.setHeader("Supported", "gruu")// P-Charging-Vector exampledef icidValue = context.uniqueIddef myIp = java.net.InetAddress.localHost.hostAddresssipReq.setHeader("P-Charging-Vector", "icid-value=" + icidValue +";icid-generated-at=" + myIp)
Protecting System Performance
by Removing SIP Messages
if (sipResponse.status < 200) { // Ignore provisional responses} else if (sipResponse.status < 300) // Proceed with processing}{...}
Removing a SIP Header in a
Message
sipReq.removeHeader("headername")
Conditionally Passing SIP Headers
in Messages
def myWebParameter = context.webMessage?.header.?myParameterif (myWebParameter) { sipRequest.setHeader("MyHeader", myWebParameter)}
REST● Asynchronous and synchronous callback responses● Support for HTTP and HTTPS● Support for all standard REST methods● Support for REST calls during message processing or WebSocket connection establishment
Defining a REST URL Endpoint Constantpublic static final MY_REST_URL = "http://server:port/rest_endpoint"
Referencing the URL Constantdef restRequest = context.restClient.createRequest(Constants.MY_REST_URL...);
Creating a REST Request
def myRestRequest = context.restClient.createRequest(Constants.MY_REST_URL, "PUT");
Configuring a REST Request Object
myRestRequest.setAccept(APPLICATION_JSON);myRestRequest.setAcceptLanguage("en-us", "de-de", "fr-fr");myRestRequest.addHeader("My Key", "My Value");
Sending the REST Request
def xml = { mkp.xmlDeclaration() fish { name("salmon") price("10") }};
def myRestFuture = myRestRequest.send(xml, APPLICATION_XML);
Sending the REST Request
context.getTaskBuilder("processResponse").withArg("myRestFuture", restFuture) .onSuccess(restFuture).build();
context.getTaskBuilder("processResponse").withArg("myRestFuture", restFuture) .onError(restFuture).build();
REST Response Handler
void processResponse(TemplateContext context) { def result = context.taskArgs.restFuture.get() if (result.status == 200) { def fish = result.value() if (fish.name.text() == "salmon") { // Continue processing... } } else { // Handle any errors... }}
REST Authentication
def myRestAuthRequest = context.restClient.createRequest(Constants.MY_REST_URL, "PUT", true);def username = "myuserid";def password = [231, 245, 675, 232, 123] as byte[];myRestAuthRequest.setCredentials(username, password);
tadhack.optaresolutions.com
Add easily
telecom services
to your APPs
Industry-
standard SIP
servlet 2.0,
media control
and Java EE
Example SIP POJO (JSR-359)
@SipServletpublic class FooPOJO {
@Invite public void incomingCall(SipServletRequest request) { //... }
@Bye public void disconnectCall(SipServletResponse response) { //... }
}
WebRTC
Summary● WebRTC is a great option to implement or add Real Time Communication services.● Groovy is very good in network systems: it provides flexibility, easy to use and good performance● If you like communications & developing, don't miss TADHack 2015.
Q & A
Thanks!
@antonmry
www.
serviceandnetworkevolution.com