Soket.io . Приложения реального времени.

Как я и обещал, на этот раз я хочу рассказать вам об очень интересном протоколе под названием socket.io. С помощью этого протокола возможно с лёгкостью создавать кросбраузерные real-time приложения. Кросбраузерность в socket.io достигается за счёт использования различных транспортов передачи информации на сервер и с сервера в браузер.
Причём технология выбирается совершенно прозрачно и для клиента, и для сервера.

Транспорты выбираются в следующей последовательности:

  • WebSocket,
  • Adobe Flash Socket,
  • AJAX multipart streaming,
  • AJAX long polling,
  • Iframe(только в IE),
  • JSONP Polling,
Если браузер поддерживает WebSockets, будут использоваться именно они. Для других браузеров будет обеспечен fallback до флешовых сокетов, а если и этих нет — до обычного XHR с long polling.

Socket.io поддерживает следующие браузеры:

Десктопные
  • Internet Explorer 5.5+
  • Safari 3+
  • Google Chrome 4+
  • Firefox 3+
  • Opera 10.61+

Мобильные
  • iPhone Safari
  • iPad Safari
  • iPad Safari
  • Android WebKit
  • WebOs WebKit


Плюс над всем этим великолепием сделан удобный API для клиента и сервера для Node.js (впрочем сервер тут можно реализовать на любом языке).

Socket.IO делает больше, чем WebSocket, даже если WebSocket выбран в качестве транспорта и пользователь просматривает веб-сайт с ультра современным браузером. Некоторые функции, такие как сердцебиение(heartbeats), тайм-ауты и отсоединение(disconnection) являются жизненно важными для приложений реального времени, но не предусмотренных WebSocket API прямо из коробки.

В этом протоколе существуют несколько зарегистрированных событий: 'connection', 'message' и 'disconnect'. Соответственно они срабатывают при подключении, посылке сообщения и отключении узеров. Но так же есть возможность создания любых собственных событий и набрасывании на них обработчиков.

Это напоминает JQuery-вское решение о создании многофункциональных и простых $.ajax API.

Небольшой тривиальный «Hello world» пример общения клиента и сервера.
Клиентская сторона:

<script src="/socket.io.js"></script>
<script>
  var socket = io.connect('http://localhost');
  socket.on('news', function (data) {
    console.log(data);
    socket.emit('my other event', { my: 'data' });
  });
</script>


Сначала мы инициализируем соединение с сервером. Потом вешаем обработчик на событие «news» и создаём новое событие «my other event», которое посылается на сервер.

Серверная часть (Nodejs):

var io = require('socket.io').listen(80);

io.sockets.on('connection', function (socket) {
  socket.emit('news', { hello: 'world' });
  socket.on('my other event', function (data) {
    console.log(data);
  });
});

Я думаю, что вы уже установили себе nodejs. Первым делом нам нужно установить модуль 'socket.io'.
Сделать это можно с помощью комманды

npm install sockeet.io

Или установить из оффициального репозитория

Что тут происходит? Сначала мы подгружаем только что установленный модуль и начинаем слушать 80 порт. Потом вешаем обработчик на событие 'connection'. Оно выбрасывается при каждом подключении нового пользователя. Внутри него мы выбрасываем событие 'news' и вешаем обработчик на 'my other event'.

В результате на клиентской стороне вы увидите приветствие, а на серверной стороне в консоле
пропишется сообщение 'data'.

Иногда требуется создать несколько подлючений к серверу, которые бы обслуживали свои части приложения. Но мы знаем, что браузеры способны открывать ограниченное число одновременных подключений. С помощью soket.io это возможно реализовать в одном подключении с помощью встроенного механизма namespace-ов.

Серверная часть:

var io = require('socket.io').listen(80);

var chat = io
  .of('/chat');
  .on('connection', function (socket) {
    socket.emit('a message', { that: 'only', '/chat': 'will get' });
    chat.emit('a message', { everyone: 'in', '/chat': 'will get' });
  });

var news = io
  .of('/news');
  .on('connection', function (socket) {
    socket.emit('item', { news: 'item' });
  });

Клиентская часть:

<script>
  var chat = io.connect('http://localhost/chat')
    , news = io.connect('http://localhost/news');

  chat.on('connect', function () {
    chat.emit('hi!');
  });

  news.on('news', function () {
    news.emit('woot');
  });
</script>


Так же реализована поддержка нестабильных (volatile) сообщений. Их можно использовать в тех местах, где доставка сообщений не должна гарантироваться на 100%. Например у пользователя очень слабый канал и вы можете проигнорировать для них какие либо сообщения, то в таком случае нужно пользоваться именно volatile.

Серверная часть:

var io = require('socket.io').listen(80);

io.sockets.on('connection', function (socket) {
  var tweets = setInterval(function () {
    getBieberTweet(function (tweet) {
      socket.volatile.emit('bieber tweet', tweet);
    });
  }, 100);

  socket.on('disconnect', function () {
    clearInterval(tweets);
  });
});

Клиентская же часть остаётся точно такой же, как и при посылке обычных сообщений.

В новой версии этого протокола реализовали поддержку acknowledgements (подтверждений, но я бы их назвал обратными вызовами) и broadcasting messages (вещательных сообщений. отправляются всем подключённым клиентам).

Реализация acknowledgements.Серверная часть:

var io = require('socket.io').listen(80);

io.sockets.on('connection', function (socket) {
  socket.on('ferret', function (name, fn) {
    fn('woot');
  });
});


Клиентская часть:

<script>
  var socket = io.connect(); // TIP: .connect with no args does auto-discovery
  socket.on('connection', function () {
    socket.emit('ferret', 'tobi', function (data) {
      console.log(data); // 'woot'
    });
  });
</script>


Из примера видно, что при генерации события 'ferret' мы можем передать третьим параметром анонимную функцию в которую будет возвращен ответ с сервера.Точно такую же операцию можно реализовать и в обратном направлении.

Реализация broadcasting messages. Серверная часть:

var io = require('socket.io').listen(80);

io.sockets.on('connection', function (socket) {
  socket.broadcast.emit('user connected');
  socket.broadcast.json.send({ a: 'message' });
});

Клиентская же часть остаётся точно такой же, как и при посылке обычных сообщений.

Чтобы дать вам пощупать данную технологию залил на сервак примитивный чат, написанный на nodejs и socket.io. Просмотреть пример можете тут. Исходный код.

Заключение.

Я постарался как можно подробно рассказать вам о всех прелестях этой технологии.
Полную документацию вы можете прочитать на оффициальном сайте проекта, или на оффициальном репозитории.

Как появится свободное время напишу другие обещанные статьи. Джу ваших отзывов.

P.S.

Не бойтесь изучать новые технологии. Кибер мир не стоит на месте и мы должны идти с ним в ногу.

Комментарии (1)

RSS свернуть / развернуть
+
0
Жду пост о playframework)
avatar

Mecid

  • 21 июля 2011, 21:52

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.