I’m a big fan of websockets. I’ve got various post about them (here, here). Last months I’m working with angularjs projects and because of that I wanna play a little bit with websockets (with socket.io) and angularjs.
I want to build one angular service.
angular.module('io.service', []).
factory('io', function ($http) {
var socket,
apiServer,
ioEvent,
watches = {};
return {
init: function (conf) {
apiServer = conf.apiServer;
ioEvent = conf.ioEvent;
socket = io.connect(conf.ioServer);
socket.on(ioEvent, function (data) {
return watches.hasOwnProperty(data.item) ? watches[data.item](data) : null;
});
},
emit: function (arguments) {
return $http.get(apiServer + '/request', {params: arguments});
},
watch: function (item, closure) {
watches[item] = closure;
},
unWatch: function (item) {
delete watches[item];
}
};
});
And now we can build the application
angular.module('myApp', ['io.service']).
run(function (io) {
io.init({
ioServer: 'http://localhost:3000',
apiServer: 'http://localhost:8080/api',
ioEvent: 'io.response'
});
}).
controller('MainController', function ($scope, io) {
$scope.$watch('question', function (newValue, oldValue) {
if (newValue != oldValue) {
io.emit({item: 'question', newValue: newValue, oldValue: oldValue});
}
});
io.watch('answer', function (data) {
$scope.answer = data.value;
$scope.$apply();
});
});
And this’s the html
<!doctype html>
<html>
<head>
<title>ws experiment</title>
</head>
<body ng-app="myApp">
<div ng-controller="MainController">
<input type="text" ng-model="question">
<hr>
<h1>Hello !</h1>
</div>
<script src="assets/angular/angular.min.js"></script>
<script src="//localhost:3000/socket.io/socket.io.js"></script>
<script src="js/io.js"></script>
<script src="js/app.js"></script>
</body>
</html>
The idea of the application is to watch one model’s variable (‘question’ in this example) and each time it changes we will send the value to the websocket server and we’ll so something (we will convert the string to upper case in our example)
As you can read in one of my previous post I don’t like to send messages from the web browser to the websocket server directly (due do to authentication issues commented here). I prefer to use one server (a Silex server in this example)
include __DIR__ . '/../../vendor/autoload.php';
use Silex\Application;
use Symfony\Component\HttpFoundation\Request;
$app = new Application(['debug' => true]);
$app->register(new G\Io\EmitterServiceProvider());
$app->get('/request', function (Application $app, Request $request) {
$params = [
'item' => $request->get('item'),
'newValue' => strtoupper($request->get('newValue')),
'oldValue' => $request->get('oldValue'),
];
try {
$app['io.emit']($params);
$params['status'] = true;
} catch (\Exception $e) {
$params['status'] = false;
}
return $app->json($params);
});
$app->run();
You can see the code within my github account.