Спілкування в режимі реального часу

24 грудня 2014 22:11 comandante 1018 0

Socket.io - це дійсно крута річ, вона дає вам можливість обмінюватися даними між клієнтами в режимі реального часу. Реалізуючи її разом з AngularJS, ви можете легко оновлювати вікно перегляду користувача. Перед тим, як заглибитись у код, давайте розглянемо всі налаштування.


 

Налаштування

  • Нам потрібно створити нову директорію. Назвемо її socket-chat.

mkdir socket-chat

 

  • Заходимо.

cd socket-chat

 

  • Створюємо app.js файл, де ми будемо зберігати логіку нашого серевера.

touch app.js

 

  • Поки ми тут, створимо package.json файл.

touch package.json

 

  • Нам потрібна директорія для фронт-енду.

mkdir public

 

  • Заходимо.

cd public

 

  • Створюємо index.html.

touch index.html

 

  • Нам також потрібні дві різні директорії тут, одна для нашого JS і одна для CSS.

mkdir js
mkdir css

 

  • Створюємо файл під назвою main.js у нашій JS директорії.

touch main.js

 

  • Переходимо до CSS директорії і створюємо файл style.css.

touch style.css


 

Бек-енд

Ми збираємося запустити простий node.js сервер з допомогою фреймворка express.js. Якщо у вас немає бажання писати бек-енд, то заспокойтесь, там всього-на-всього 25 рядків.

По-перше, ми повинні налаштувати наші залежності. Відкриваємо каталог socket-chat у вашому улюбленому текстовому редакторі. Відкрийте package.json і вставте наступний код.

{
  "name": "angular-socket-chat",
  "description": "AngularJS Realtime Chat",
  "version": "0.0.1-1",
  "private": true,
  "dependencies": {
    "express": "3.x",
    "socket.io": "0.9.x"
  },
  "scripts": {
    "start": "app.js"
  },
  "engines": {
    "node": "0.8.x"
  }
}

 

Звідси ми повертаємося до командного рядку і виконуємо:

npm install

 

Це автоматично встановить всі наші залежності. Тепер повернемося в наш редактор, відкриємо app.js та вставимо цей код.

var express = require('express'),  
    app = express(),
    server = require('http').createServer(app),
    io = require('socket.io').listen(server);
app.configure(function() {  
    app.use(express.static(__dirname + '/public'));
});
io.sockets.on('connection', function(socket) {  
    socket.broadcast.emit('user:connect', 'A user has connected');
    socket.on('msg:send', function(msg) {
        socket.broadcast.emit('user:notTyping');
        socket.broadcast.emit('msg:sent', msg);
        socket.emit('msg:sent', msg);
    });
    socket.on('user:typing', function(data) {
        socket.broadcast.emit('user:typed', data)
    });
    socket.on('user:stoppedTyping', function() {
        socket.broadcast.emit('user:notTyping');
    });
});
server.listen(1337);  

 

Це ініціалізує наш сервер за адресою localhost:1337. Також зверніть увагу на змінну io, яка створює socket.io на стороні сервера. Також, зверніть увагу на виклик io.sockets.on, ми приймаємо два параметри зв'язку подій і зворотного виклику, які передаються в socket. Всередині функції ми маємо доступ до socket, де ми кажемо socket.io прослуховувати події, які запускаються на стороні клієнта і, в свою чергу, ми можемо генерувати події для клієнта.

 

 

Фронт-енд

HTML є досить простим, не будемо вдаватися у деталі. Просто знайте, що це йде у index.html.

<!DOCTYPE html>  
<html ng-app="app">  
<head>  
    <title>Socket Chat</title>
    <script src="/socket.io/socket.io.js"></script>
    <script src="http://code.jquery.com/jquery-1.8.3.js"></script>
    <script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js"></script>
    <script src="/js/main.js"></script>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
    <link rel="stylesheet" href="/css/app.css">
</head>  
<body ng-controller="MainCtrl">  
    <ul>
        <li ng-repeat="msg in msgs">{{ msg }}</li>
    </ul>
    <form id="send" class="form">
        <div class="form-group">
            <input type="text" ng-model="message" />
            <button type="submit" ng-click="send()" class="btn btn-primary">Send</button>
        </div>
    </form>
</body>  
</html>  

 

Наші стилі виглядатимуть так:

form {  
  position: fixed;
  bottom: 0;
  left: 0;
}
input {  
  width: 600px;
}

 

Тепер найцікавіше, Angular. Ми будемо працювати з js/main.js. По-перше, ми створюємо екземпляр нашої програми.

var app = angular.module('app', []);  


Далі - сервіс, створений BTFord. Це оберне наші методи socket.io в Angular.

app.factory('socket', function($rootScope) {  
    var socket = io.connect();
    return {
        on: function(eventName, callback) {
            socket.on(eventName, function() {
                var args = arguments;
                $rootScope.$apply(function() {
                    callback.apply(socket, args);
                });
            });
        },
        emit: function(eventName, data, callback) {
            socket.emit(eventName, data, function() {
                var args = arguments;
                $rootScope.$apply(function() {
                    if(callback) {
                        callback.apply(socket, args);
                    }
                });
            });
        }
    };
});

 

Наш контролер. Ми прив'язуємо наші слухачі і події з бек-енду до перегляду.

app.controller('MainCtrl', function($scope, socket) {  
    socket.on('user:connect', function(data) {
        $scope.msgs.push(data);
    });
    $scope.msgs = [];
    $scope.message = '';
    var submitted = false;
    $scope.send = function() {
        socket.emit('msg:send', $scope.message);
        $scope.message = '';
        submitted = true;
        typing = false;
    }
    socket.on('msg:sent', function(msg) {
        $scope.msgs.push(msg);
    });
    var typing = false;
    $scope.$watch('message', function(newVal, oldVal) {
        if(newVal.length >= 1) {
            submitted = false;
        }
        if(newVal.length > 1 && !typing && !submitted) {
            typing = true;
            socket.emit('user:typing', 'A user is typing');
        }
        if(newVal.length < 1 && typing && !submitted) {
            socket.emit('user:stoppedTyping');
            typing = false;
        }
    });
    socket.on('user:typed', function(data) {
        $scope.msgs.push(data);
    });
    socket.on('user:notTyping', function() {
        $scope.msgs.pop();
    });
});

 

Ви можете бачити, що ми слухаємо наші події і віддаємо дані пов'язані з тими подіями в масив повідомлень. Ми також віддаємо певні події на сервер, які повідомляють про те, що були внесені зміни і потрібно виконати  відповідні оновлення на стороні клієнта.


 

Висновок

Socket.io - це дуже потужний інструмент для створення додатків, починаючи від спілкування у реальному часі до push-повідомлень. Не дивлячись на це, він досить простий у реалізації для базових задач.

 

Джерело перекладу

1018 5

Схожі матеріали:

Коментарі:

Авторизуйтесь, щоб залишити коментар.