A Story
Warning: Following fictional anectode may contain absurd amounts of animated GIFs (pronounced: 'jiffs')
And one unsung lady
(image via: luke o’sullivan)
Then
Now
(again)
And sometimes missing completely.
If only there were a library to cover up all the pain points of WebSockets and provide an easy-to-use cross-platform solution with intelligent fallbacks and helpful utilities...
for free.
Because budgets
Planning Budget: $12,490,000.32 Development Budget: $35 Software Licenses Budget: $0
And so the work continued...
... but smarter this time.
This solution makes heavy use of open source libraries. If you like creating solutions by yourself, from scratch, this is not for you.
Like jQuery For WebSockets
important
Your Silent Partner
The Bolt-On Accessory For Your App
The Redis is Silent
npm install socket.io
npm install socket.io-redis
var server = require('http').Server();
var io = require('socket.io')(server);
var ioredis = require('socket.io-redis');
io.adapter(ioredis({
host: '127.0.0.1',
port: 6379
}));
server.listen(3000);
Not Kidding. That's It.
socket-io-server.js
// Connect to Socket.IO
var socket = io('http://demoapp.dev:3000');
// Listen for the 'Thing::update' event
socket.on('Thing::update', function(thing){
// Parse the event data
thing = JSON.parse(thing);
// Update the data in the DOM
...
});
<script src="http://yoursocketserver.org/socket.io/socket.io.js"></script>
Include Client-Side Socket.IO Library
Write some JavaScript
public function updateThing(thingId):Void
{
// Create an instance of your Emitter
Emitter myEmitter = new SocketIO\Emitter(redisConnObj);
// Create some data to push to connected clients
Thing thisThing = ORM.Thing.get(thingId);
thisThing.name = "Make more moneys"
thisThing.importance = 9999;
// Data must be string or binary
String eventData = thisThing.toJSON();
// Name the event
String updateEventName = "Thing::update";
// Emit the event
myEmitter.emit(updateEventName, eventData);
}
your-app-update.class.module.java.py.rb
"Emit" and event + data from your app using your Emitter class/module
Socket.IO (and Redis) does stuff.
You do nothing
Listen for event & data in the browser with your own JS code.
myEmitter.emit( "AwesomeEvent", importantDatas );
socket.on( 'AwesomeEvent', function(importantData){} );
Requires some additional setup...
var server = require('http').Server();
var io = require('socket.io')(server);
var ioredis = require('socket.io-redis');
io.adapter(ioredis({
host: '127.0.0.1',
port: 6379
}));
io.on('connection', function(socket){
socket.on('AlertToggle::join', function(){
socket.join('ROOM::ExtraImportantUpdates');
});
socket.on('AlertToggle::leave', function(){
socket.leave('ROOM::ExtraImportantUpdates');
});
});
server.listen(3000);
socket-io-server.js
$(document).on('click', '.alert-toggle', function(e){
if(!gettingAlerts) {
// Send signal to join the room
socket.emit('AlertToggle::join');
$(this).text('Stop Alerts');
} else {
// Send signal to leave the room
socket.emit('AlertToggle::leave');
$(this).text('Get Alerts');
}
gettingAlerts != gettingAlerts;
});
public void function deleteThing() {
...
if ( thingToDelete.importance > 100 )
{
String updateRoom = "ROOM::ExtraImportantUpdates";
String deleteEventName = "Thing::delete::important";
myEmitter.in( updateRoom ).emit( deleteEventName, thingToDelete );
}
...
}
socket.on('Thing::delete::important', function(thing){
var thing = JSON.parse(thing);
$('#myModal').modal('show');
$('#modal-important-record').text(thing.name);
});
App Server Code
Browser Code - ONLY RUNS IF IN ROOM
From http://socket.io/docs/rooms-and-namespaces/
Socket.IO allows you to “namespace” your sockets, which essentially means assigning different endpoints or paths.
var nsp = io.of('/my-namespace');
nsp.on('connection', function(socket){
console.log('someone connected'):
});
nsp.emit('hi', 'everyone!');
var socket = io('http://yoursocketserver.com/my-namespace');
Socket.IO Server Code
Browser/Client Code
Browser/Client Code
$(document).on('click', function(){
socket.emit('document::clicked');
});
Socket.IO Server (socket-io-server.js)
var redis = require('redis');
var redisClient = redis.createClient();
...
io.on('connection', function(socket){
socket.on('document::clicked', function(){
redisClient.incr('analytics::counter', function(err,reply){
redisClient.get('analytics::counter',function(err,reply){
io.emit('Analytics::counter',reply);
});
});
});
});
Engine.IO
WebSocket Transport, low-level client & parser
What's New In Socket.IO 1.0 - Juriy Bura
7 Principles of Rich Web Applications - Guillermo Rauch
https://slides.com/eterps/time-for-real-time