The Real-Time Web is rapidly growing and as a consequence an increasing number of applications require soft-real time interactions with the server-side as well as with peer web applications. In addition, real-time web technologies are experiencing swift adoption in traditional systems as a means of providing portable and ubiquitously accessible thin client applications.
In spite of this trend, few high level communication frameworks exist that allow efficient and timely data exchange between web applications as well as with the server-side and the back-end system. Vortex Web is one of the first technologies to bring the powerful OMG Data Distribution Service (DDS) abstractions to the world of HTML5 / JavaScript applications. With Vortex Web, HTML5 / JavaScript applications can seamlessly and efficiently share data in a timely manner amongst themselves as well as with any other kind of device or system that supports the standard DDS Interoperability wire protocol (DDSI).
This presentation will (1) introduce the key abstractions provided by Vortex Web, (2) provide an overview of its architecture and explain how Vortex Web uses Web Sockets and Web Workers to provide low latency and high throughput, and (3) get you started developing real-time web applications.
4. CopyrightPrismTech,2014
One Standard, One set of Tools, One Goal — Ubiquitous Data Sharing
The Vortex Platform
VORTEX
Web
VORTEX
Lite
VORTEX
Gateway
VORTEX
Cloud
Private
Clouds
VORTEX
Tools
• Insight
• Record/Replay
• Tuner
• Tester
• Configurator
OpenSplice
Enterprise
VORTEX
Café
6. CopyrightPrismTech,2014
• A JavaScript DDS API to provide HTML5/
JavaScript applications with a high-level
communication abstraction
• Vortex Web exploits HTML5 features, such as web-
sockets and web-workers, to provide time and
space efficient Web-App to Cloud communication
Vortex Web
DDS#API JavaScript
Browser#/#Node.js
CoffeeScript
7. CopyrightPrismTech,2014
Client Side (dds.js): JavaScript/
CoffeeScript framework that
provides DDS abstractions
Server Side (vortex-web): A
Router that transparently
bridges data between matching
DDS entities, e.g. Browser-2-
Browser, DDS-2-Browser and
Browser-2-DDS
Vortex Web
TopicA
TopicB
TopicC
TopicD
QoS
QoS
QoS
QoS
Data
Reader
Data
Reader
Data
Writer
Data
Writer
dds.js
dds.js
dds.js
v-web
v-web
8. CopyrightPrismTech,2014
Vortex-Web takes advantage of HTML5 WebSockets as well as Web Workers
WebSockets are used for both the control as well as the data plane
Web Workers are used to decouple I/O from processing (recall that a JS context is
single-threaded)
Client-Side Architecture
10. CopyrightPrismTech,2014
Vortex-Web can be deployed to simply provide access to a “regular” DDS system
or to extend Vortex-Cloud with JavaScript support
In general, you should think of Vortex-Web as an add-on to either a regular or a
Vortex-Cloud DDS system
Vortex-Web takes advantage of DDS to support fault-tolerance and load-
balancin.
Vortex Web Deployment
11. CopyrightPrismTech,2014
Multiple instances can be deployed
on a single system to provide fault-
tolerance as well as to help in
partitioning the load
The switch-over between instances
is dealt-with by the dds.js library
Traditional System Deployment
TopicA
TopicB
TopicC
TopicD
QoS
QoS
QoS
QoS
Data
Reader
Data
Reader
Data
Writer
Data
Writer
dds.js
dds.js
dds.js
v-web
v-web
12. CopyrightPrismTech,2014
Multiple instances can be deployed on
the same IaaS platform sa Vortex-
Cloud provide fault-tolerance as well
as to help in partitioning the front-end
load
The switch-over between instances is
dealt-with by the dds.js library
Cloud Based Deployment
VORTEX
Cloud
IaaSserver-‐side
dds.js
dds.js
dds.js
18. CopyrightPrismTech,2014
A DataReader can be bound to a user provided function that will handle
incoming data or to a cache
Notice, that as you are in control of how data-readers are bound to cache you
can be very creative
Binding a DataReader
20. CopyrightPrismTech,2014
Binding to a Cache
// Binding!
bindCell = dds.bind((s) -> s.x + “-” + s.y)!
ccache = new DataCache(historyDepth)!
bindCell(ccache, cdr)!
!
// Working with the Cache: Compute number of active cells!
!
activeCells = ccache.map((c) -> if (c.pressure > p0) then 1 else 0).fold(0)((a, c) ->
a + c)!
!
!
cache = new DataCache(historyDepth)!
bind(keyMapper)(dr, cache)
CoffeeScript
Example:
21. CopyrightPrismTech,2014
DataCache Operations
# Writes a data sample into the cache corresponding to the key k !
write: (k, data)!
!
# Returns a list representing the content of the cache ordered by key.!
read()!
!
# Returns a list representing the last sample for each key!
readLast()!
!
# Returns a list representing the content of the cache ordered by key. !
# The data is actually removed from the cache.!
take()!
!
# Returns a list representing the last sample for each key!
# The data is actually removed from the cache.!
takeLast()
22. CopyrightPrismTech,2014
DataCache Operations
# Returns a list representing the content of the cache that matches for given predicate.!
# The data is actually removed from the cache.!
takeWithFilter(p)!
!
# Returns Some(v) if a value associated to the key k exists. Otherwise it returns None!
get: (k)!
!
# Returns Some(v) if a value associated to the key k exists. Otherwise it returns f()!
getOrElse(k, f)!
!
# Clear the content of the cache.!
clear()!
23. CopyrightPrismTech,2014
DataCache Operations
# Returns a new DataCache whose content is obtained by applying the function!
# f to each element of the cache!
map(f)!
!
# Executes the function f on each element of the cache!
forEach(f)!
!
# Executes the function f only on the first n samples associated with a key!
forEachN(f, n)!
!
# Returns the element of the cache that match the predicate p!
filter(p)!
!
# Returns the element of the cache that do not match the predicate p!
filterNot(p)
24. CopyrightPrismTech,2014
DataCache Operations
# Folds the content of the data cache using z as “zero” for the folding function f!
# For instance, assuming that the operator “+” is defined for the elements of !
# the cache, then you could compute the sum of all elements doing:!
# c.fold(0)((a, v) -> a + v)!
# the product by: !
# c.fold(1)((a, v) -> a * v)!
# a comma separated string representation of the content:!
# c.fold(“”)(a, v) -> a + “, “ + v!
fold(z)(f) !
!
# Register a listener l to be notified whenever data which matches a !
# predicate p is written into the cache. If no predicate is provided !
# then the listeners is always notified upon data insertion.!
addListener(l, p)!
!
26. CopyrightPrismTech,2014
Let’s see the steps required
to build a Web Chat that
may look like this
But before let’s play with it
a bit
Web Chat
http://bit.ly/vortex-web-chat
27. CopyrightPrismTech,2014
The Chat CoffeeScript
#
Create
useful
alias
for
coffez
and
jQuery
root
=
this
z_
=
coffez
$
=
jQuery
!
server
=
“ws://demo-‐eu.prismtech.com:9999"
!
#
The
post
type
used
by
the
chat
application
class
Post
constructor:
(@name,
@msg)
-‐>
!
#
Create
the
runtime
runtime
=
new
dds.runtime.Runtime()
!
#
Define
the
Post
topic
used
to
send
and
receive
chat
posts
postTopic
=
new
dds.Topic(0,
"Post")
!
#
Define
the
QoS
for
the
DataReader/Writer
drQos
=
new
dds.DataReaderQos(dds.Reliability.Reliable)
dwQos
=
new
dds.DataWriterQos(dds.Reliability.Reliable)
28. CopyrightPrismTech,2014
The Chat CoffeeScriptpostReader
=
z_.None
postWriter
=
z_.None
!
avatar
=
"avatar"
+
Math.floor((Math.random()
*
10000)
+
1);
!
#
Add
post
to
the
chat
and
format
it
to
show
it
is
from
me
createMyPost
=
(post)
-‐>
...
!
#
Add
post
to
the
chat
and
format
it
to
show
it
is
from
others
createOtherPost
=
(post)
-‐>
...
!
#
Add
post
to
the
chat
and
format
it
to
show
it
is
from
others
processPost
=
()
-‐>
msg
=
$("#ChatMessage").val()
post
=
new
Post(avatar,
msg)
#
Publish
the
post
(notice
that
postWriter
is
an
Option
Monad)
#
Take
a
look
at
(http://en.wikibooks.org/wiki/Haskell/Understanding_monads/Maybe)
#
or
(http://www.scala-‐lang.org/api/2.11.0/index.html#scala.Option)
postWriter.map((dw)
-‐>
dw.write(post))
$("#ChatMessageList").append(createMyPost(post))
$("#ChatMessage").val("")
!
29. CopyrightPrismTech,2014
The Chat CoffeeScript
#
Deal
with
click
and
keys
events…
!
$("#ChatMessage").keyup(
(e)
-‐>
if(e.keyCode
is
13)
then
processPost()
)
!
!
$("#SendMsgButton").click(
(evt)
-‐>
console.log("Send
Button
has
been
clicked")
processPost()
)
!
$("#SelectAvatarButton").click(
(evt)
-‐>
s
=
$("#AvatarName").val()
if
(s
isnt
"")
avatar
=
s
)
30. CopyrightPrismTech,2014
The Chat CoffeeScript
#
Handle
the
runtime
onconnect
event
runtime.onconnect
=
()
-‐>
#
Create
DataReader
and
DataWriter
for
our
posts
dr
=
new
dds.DataReader(runtime,
postTopic,
drQos)
dw
=
new
dds.DataWriter(runtime,
postTopic,
dwQos)
!
#
Register
a
listener
with
the
data
reader
to
post
messages
#
in
our
chat
dr.addListener(
(post)
-‐>
if
(post.name
isnt
avatar)
$("#ChatMessageList").append(createOtherPost(post)))
postReader
=
z_.Some(dr)
postWriter
=
z_.Some(dw)
!
connectRuntime
=
()
-‐>
$("#AvatarName").val(avatar)
runtime.connect(server,
"uid:pwd")
!
$(document).ready(()
-‐>
connectRuntime())
31. CopyrightPrismTech,2014
Only ~10 lines code for implementing the communication required by a chat
application!
Content filtering could be used to further simplify the application and reduce
number of lines of code, i.e. avoid the check on the origin of the message to
avoid duplicate posts
In Summary
32. CopyrightPrismTech,2014
Vortex-Web makes is very simple to develop peer-to-peer real-time web
applications
Through the Vortex Platform, Vortex-Web application can share data seamlessly
with any device!
Concluding Remarks
33. CopyrightPrismTech,2014
Vortex v1.0 will be available in June 2014
Starting from May will be providing a series of webcasts to get you
started in building IoT and I2 applications with Vortex
What’s Next?