Требования
Сегодня нам понадобятся:
- Debian 7
- Node.JS (установку можно посмотреть в моём предыдущем посте)
- vim
Сервер
Для начала определимся с тем, какие файлы будут у нас:
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