Realtime приложение с помощью Socket.IO

Владимир Рочев

Веб-разработчик

Realtime приложение с помощью Socket.IO
Socket.IO — лучший модуль под Node.JS для взаимодействия пользователя с сервером на обычной странице веб-сайта. В этом посте я хочу продемонстрировать пример того, как несколько пользователей могут получать извещения от сервера, например, по нажатию кнопки в режиме реального времени. Но это лишь малая часть того, что можно делать с помощью WebSocket’ов как технологии в общем, так и модуля для Node.JS Socket.IO в частности.

Требования

Сегодня нам понадобятся:

Сервер

Для начала определимся с тем, какие файлы будут у нас:

  • app.js — исходный код сервера
  • page.html — непосредственно страница клиента
  • index.html — симуляция нескольких пользователей на одной странице

Нам нужно создать директорию, в которой будут располагаться файлы сервера. Допустим, это /src/nodejs/example/:

mkdir -p /src/nodejs/example/ && cd %_

Далее установим модули Socket.IO и Express с помощью npm:

npm install socket.io express

Модуль Socket.IO служит для установления связи с сервером, а Express будет отдавать статичные страницы.

Теперь рассмотрим непосредственно код сервера app.js:

var app = require('express')(),
	server = require('http').createServer(app),
	io = require('socket.io').listen(server);

server.listen(80);

io.set('log level', 1);

app.get('/example', function (req, res) {
	res.sendfile(__dirname + '/index.html');
});
app.get('/example/page', function (req, res) {
	res.sendfile(__dirname + '/page.html');
});

app.get('*', function(req, res){
	res.send('Not found', 404);
});

var userID = 0;

io.sockets.on('connection', function (socket) {
	var username = "User" + (++userID);

	socket.emit('login', username);
	socket.broadcast.emit('message',
		'Пользователь ' + username + ' соединился'
	);

	socket.on('btn1', function() {
		socket.broadcast.emit('message',
			'Пользователь ' + username + ' нажал первую кнопку.'
		);
	});

	socket.on('btn2', function() {
		socket.broadcast.emit('message',
			'Пользователь ' + username + ' нажал вторую кнопку.'
		);
	});

	socket.on('btn3', function() {
		socket.broadcast.emit('message',
			'Пользователь ' + username + ' нажал третью кнопку.'
		);
	});

	socket.on('disconnect', function() {
		socket.broadcast.emit('message',
			'Пользователь ' + username + ' завершил работу'
		);
	});
});

Первые три строки инициализируют модули, так что пока можно просто их скопировать.

server.listen(80) заставляет сервер слушать на 80 порту.

Строкой io.set('log level', 1) мы говорим серверу логировать только предупреждения (WARN) и ошибки (ERROR). По умолчанию в консоль пишется вся отладочная информация.

Блоки apt.get(...) используются для роутинга и отдают статичные страницы.

Далее большой блок io.sockets.on('connection',...) задаёт действие на событие подключения к серверу пользователя, в котором создаётся переменная имени пользователя, отправляется пользователю сообщение и задаются для конкретного пользователя действия на события уже с его стороны.

socket.emit('login', username); — отправляет сообщение пользователю с идентификатором login и строкой, в которой содержится его имя. Помимо строки можно передавать как примитивные типы, так и объекты.

socket.broadcast.emit('message',...); транслирует сообщение всем, кроме текущего пользователя, в нашем случае отправляет сообщение о том, что новый пользователь соединился.

По событию нажатия первой кнопки вызывается блок socket.on('btn1',...);, в котором транслируются пользователям, кроме текущего, сообщение о том, что пользователь нажал кнопку. Об этом чуть позже.

И, наконец, блок socket.on('disconnect',...); вызывается, когда пользователь отключается.

Клиент

Код страницы page.html, отдаваемой клиенту, выглядит следующим образом

<!DOCTYPE html>
<html>
  <head>
    <script src="http://yandex.st/jquery/2.1.1/jquery.min.js"></script>
    <script src="/socket.io/socket.io.js"></script>
    <script>
      $(document).ready(function() {
        var socket = io.connect();
        
        socket.on("login", function(username) {
          $("#username").html("Здравствуйте, <b>" + username + "</b>!");
          $("#btn1").removeAttr('disabled');
          $("#btn2").removeAttr('disabled');
          $("#btn3").removeAttr('disabled');
          $("#exit").removeAttr('disabled');
        });

        socket.on("message", function (data) {
          $("#events").append("<div>"+data+"</div>");
        });

        $("#btn1").click(function() {
          socket.emit("btn1");
          $("#events").append("<div>Вы нажали первую кнопку</div>");
        });
        $("#btn2").click(function() {
          socket.emit("btn2");
          $("#events").append("<div>Вы нажали вторую кнопку</div>");
        });
        $("#btn3").click(function() {
          socket.emit("btn3");
          $("#events").append("<div>Вы нажали третью кнопку</div>");
        });
        $("#exit").click(function() {
          window.location = "about:blank";
        });
      });
    </script>
    <style type="text/css">
      * {
        text-align: center;
      }
      div {
        margin-bottom: 4px;
      }
      button[disabled] {
        color: gray;
      }
    </style>
    <title>Socket.IO Demo</title>
  </head>
  <body>
    <div id="username">Соединение...</div>
    <div>
      <button id="btn1" disabled>Кнопка 1</button>
      <button id="btn2" disabled>Кнопка 2</button>
      <button id="btn3" disabled>Кнопка 3</button>
    </div>
    <div>
      <button id="exit" disabled>Завершить работу</button>
    </div>
    <div id="events"></div>
  </body>
</html>

Здесь мы подключаем JS-библиотеку Socket.IO:

<script src="/socket.io/socket.io.js"></script>

Соединяемся с сервером:

var socket = io.connect();

Вешаем события на login и message

socket.on("login", function(username) {...});
socket.on("message", function (data) {...});

И по нажатию кнопки отправляем сообщение на сервер:

$("#btn1").click(function() {
  socket.emit("btn1");
  $("#events").append("<div>Вы нажали первую кнопку</div>");
});

Также для удобства создадим третью страницу, в которой будет симуляция сразу трёх пользователей:

<!DOCTYPE html>
<html>
  <head>
    <title>Socket.IO</title>
  </head>
  <frameset rows="*" cols="33%,33%,33%">
    <frame src="/example/page">
    <frame src="/example/page">
    <frame src="/example/page">
  </frameset>
</html>

Вот и всё. Запускаем сервер командой:

node app.js

Похожие посты

Мы подобрали посты, которые могут быть вам интересны

Комментарии

Тут без вас никак. Поделитесь с нами вашими мыслями

Горячие вакансии