Sou um grande fã de websockets. Tenho vários artigos sobre o assunto (aqui, aqui). Nos últimos meses, eu tenho trabalhado em projetos com angularjs e por conta disso quero brincar um pouco com websockets (com socket.io) e angularjs.
Eu quero construir um serviço em angular.
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]; } }; });
E agora podemos construir o aplicativo
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(); }); });
E esse é o 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 {{answer}}!</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>
A ideia desse aplicativo é de observar a variável de um modelo (‘question’, neste exemplo) e toda vez que mudar vamos mandar o valor para o servidor websocket e vamos fazer algo (vamos converter a string para caixa alta em nosso exemplo).
Como você pode ler em um dos meus textos anteriores, não gosto de enviar mensagens do browser para o servidor websocket diretamente (devido a problemas de autenticação que eu comentei aqui). Eu prefiro usar um servidor (Silex, nesse exemplo).
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();
Você pode acessar o código na minha conta no GitHub.
***
Artigo traduzido pela Redação iMasters com autorização do autor. Publicado originalmente em http://gonzalo123.com/2014/08/25/playing-with-websockets-angularjs-and-socket-io/