Содержание

Слайд 2

В предыдущей лекции

Были рассмотрены принципы работы Event loop в Node.js
Переменные, объявленные

В предыдущей лекции Были рассмотрены принципы работы Event loop в Node.js Переменные,
на верхнем уровне, автоматически не становятся глобальными.
Были рассмотрены процессы и работа с ними, отправка сообщений, порождение дочерних процессов с помощью методов exec, spawn, fork.
Бинарные данные хранятся в экземплярах класса Buffer, с ним ассоциирована область памяти, выделенная вне стандартной кучи V8.
Для работы с таймерами используются методы SetTimer, ClearTimer, SetInterval, ClearInterval.
За события в Node.js отвечает специальный модуль – events.
EventEmitter - это основной объект, реализующий работу обработчиков событий в Node.js. Любой объект, являющийся источником событий, наследует от класса EventEmitter.
На базовом уровне рассмотрена работа с модулями.

Слайд 3

В этой лекции

Работа с файлами
Создаем ТСР-сервер
WebSockets

В этой лекции Работа с файлами Создаем ТСР-сервер WebSockets

Слайд 4

Работа с файлами

Модуль FileSystem входит в дистрибутив Node.js, и, честно говоря,

Работа с файлами Модуль FileSystem входит в дистрибутив Node.js, и, честно говоря,
мы его уже использовали для чтения html-контента. Естественно, этим его функции не ограничиваются; лучше всего показать eгo работу на примере конкретной задачи. Причем важной. Скажем, нужно составить список всех композиций в формате mрЗ на винчестере с указанием их местоположения. Наверняка вам нечто подобное уже приходилось писать на С или, скажем, на Perl. Теперь oчepeдь JavaScript, и мы сейчас убедимся, что этот язык справится с данной задачей ничуть не хуже.

Слайд 5

Рекурсивный обход каталогов

var base = 'D:\\Development\\SDAssembla';
var fs = require('fs');
function readDir(base)

Рекурсивный обход каталогов var base = 'D:\\Development\\SDAssembla'; var fs = require('fs'); function
{
fs.readdir(base, function (err, files) {
files.forEach(function (item) {
fs.stat(base + '\\' + item, function (err, state) {
if (state.isDirectory()) {
console.log(item);
localBase = base + '/' + item;
readDir(localBase);
}
else {
console.log(" " + item);
}
});
});
});
}
readDir(base);

Слайд 6

fs.readdir(), fs.stat().

Для чтения каталога используется метод fs.readdir(), имеющий аналоги во многих языках

fs.readdir(), fs.stat(). Для чтения каталога используется метод fs.readdir(), имеющий аналоги во многих
программирования.
Для определения, является ли полученный файл директорией, используется объект fs.Stats, возвращаемый методом fs.stat(). Это объект, содержащий различную информацию о найденном файле.

Слайд 7

fs.Stats

stats.isFile() - проверяет, является ли объект файлом;
stats.isDirectory() -

fs.Stats stats.isFile() - проверяет, является ли объект файлом; stats.isDirectory() - проверяет, является
проверяет, является ли объект директорией;
stats.isBlockDevice() -проверяет, является ли объект файлом устройства блочного ввода/вывода;
stats.isCharacterDevice() - проверяет, является ли объект файлом устройства посимвольного ввода/вывода;
stats.isSymbolicLink() -проверяет, является ли объект символической ссылкой (при этом для получения stat должен быть использован специальный метод - fs.lstat() );
stats.isFIFO() - проверяет, является ли объект FJFО-файлом (именованным каналом);
stats.isSocket() -проверяет, является ли объект сокетом. Этого арсенала должно хватить, чтобы получить информацию для

Слайд 8

Результаты работы предыдущей программы

Все это замечательно, но вот вывод предыдущей программы

Результаты работы предыдущей программы Все это замечательно, но вот вывод предыдущей программы
нас может не устроить.
Это слабо упорядоченная смесь названий файлов и директорий, ориентироваться в которой просто нельзя. Почему это случилось? Дело в том, что методы fs.readdir() и fs.stat() асинхронны и совсем не обязаны выдавать результат в строгой очередности.
Для целого ряда задач (например, нам бы понадобилось массово переименовать файлы или просканировать их содержимое) такой подход не только уместен, но и наиболее эффективен.
Многие ключевые методы модуля fs имеют свои синхронные аналоги. В том числе fs.readdir() и fs.stat().

Слайд 9

Синхронная версия

var fs = require('fs');
var base = 'D:\\Development\\SDAssembla\\securedating';
String.prototype.repeat = function (num)

Синхронная версия var fs = require('fs'); var base = 'D:\\Development\\SDAssembla\\securedating'; String.prototype.repeat =
{ return new Array(num + 1).join(this); }
function readDir(base, indent) {
files = fs.readdirSync(base)
files.forEach(function (item) {
state = fs.statSync(base + '\\' + item);
if (state.isDirectory()) {
console.log("\n" + " ".repeat(indent * 2) + item + "\n");
localBase = base + '/' + item;
readDir(localBase, indent + 1);
}
else {
console.log(" ".repeat(indent * 2) + item);
}
});
}
readDir(base, 0);

Слайд 10

Файлы по папкам в алфавитном порядке

var fs = require('fs');
var path = require('path');
var

Файлы по папкам в алфавитном порядке var fs = require('fs'); var path
base = 'D:\\Development\\SDAssembla\\site_pics'; // тут хранятся файлы
var collection = 'D:\\Development\\SDAssembla\\sorted'; //тут будет упорядоченная коллекция
function collect(base) {
fs.readdir(base, function (err, files) {
files.forEach(function (item) {
console.log(item.charAt(0));
var fileName = collection + '\\' + item.charAt(0);
if (fs.existsSync(fileName)) {
copyRecursive(base + "\\" + item, fileName + "\\" + item);
} else {
fs.mkdir(fileName, function () {
copyRecursive(base + "\\" + item, fileName + "\\" + item);
});
}
});
});
}

Слайд 11

Файлы по папкам в алфавитном порядке

Тут мы пользуемся синхронной версией метода (fs.existsSync()

Файлы по папкам в алфавитном порядке Тут мы пользуемся синхронной версией метода
), проверяющего существование объекта файловой системы ( есть и асинхронный).
Метод fs.mkdir() предсказуемо создает директорию, а вот с методом copyRecursive() сложнее.
Такого в документации нет. В составе fs вообще нет аналога posix команды сору().

Слайд 12

СopyRecursive

var copyRecursive = function (src, dest) {
var exists = fs.existsSync(src);
var

СopyRecursive var copyRecursive = function (src, dest) { var exists = fs.existsSync(src);
stats = fs.statSync(src);
var isDirectory = exists && stats.isDirectory();
if (isDirectory) {
fs.mkdirSync(dest);
fs.readdirSync(src).forEach(function (childitemName) {
copyRecursive(path.join(src, childitemName), path.join(dest, childitemName));
});
}
else {
fs.linkSync(src, dest);
collect(base);
}
}
collect(base);

Слайд 13

fs.mkdirSync(), fs.linkSync()

Что тут нового? В самом приеме рекурсивного обхода ресурсов файловой системы

fs.mkdirSync(), fs.linkSync() Что тут нового? В самом приеме рекурсивного обхода ресурсов файловой
точно нет никаких инноваций.
А вот на что стоит обратить внимание, так это на метод создания директории (fs.mkdirSync(), он тоже имеет синхронную форму) и метод fs.linkSync(), создающий, по идее, жесткую ссылку на файл, но в данной ситуации это соответствует процедуре копирования.

Слайд 14

Удаление файлов

var fs = require('fs');
var path = require('path');
var collection = 'D:\\Development\\SDAssembla\\sorted';
fs.rmdir(collection,

Удаление файлов var fs = require('fs'); var path = require('path'); var collection
function (error) {
if (error) { console.error(error.message); }
});
Все правильно, директория не пуста. Тут тоже придется прибегнуть к рекурсии:

Слайд 15

Удаление файлов

var fs = require('fs');
var collection = 'D:\\Development\\SDAssembla\\sorted';
function removeDir(path){
if (fs.existsSync(path)){
fs.readdirSync(path).forEach(

Удаление файлов var fs = require('fs'); var collection = 'D:\\Development\\SDAssembla\\sorted'; function removeDir(path){
function(file) {
var f = path + "\\" + file;
var stats = fs.statSync(f);
if (stats.isDirectory())
{
removeDir(f);
}
else
{
fs.unlinkSync(f)
};
console.log(f + "is removed");
});
fs.rmdirSync(path);
console.log(path + " is removed");
}
}
removeDir(collection);

Слайд 16

Path Resolve

Самый, наверное, интересный метод из небольшого арсенала модуля path это path.resolve(),

Path Resolve Самый, наверное, интересный метод из небольшого арсенала модуля path это
разрешающий (преобразующий) заданный путь в абсолютный:
var path = require('path');
var resolved = path.resolve('./CouponCodeUpdate.txt');
console.log(resolved);

Слайд 17

Path Relative

Метод path.relative(), преобразует заданный путь в относительный (дополняет метод Resolve)
var path

Path Relative Метод path.relative(), преобразует заданный путь в относительный (дополняет метод Resolve)
= require('path');
var resolved = path.relative('C:\\zzz\\test\\aaa', 'C:\\zzz\\impl\\bbb');
console.log(resolved);

Слайд 18

Path.normalize

Метод path.normalize() «приводит пути в порядок», то есть удаляет из них все,

Path.normalize Метод path.normalize() «приводит пути в порядок», то есть удаляет из них
что там быть не должно, но появилось, например, из-за специфичного формата ввода (сочетания символов .. , ., или //):
var path = require('path');
var myPath = '/foo/bar///baz/asdf/quux/ ';
myPath = path.normalize(myPath);
console.log(myPath);

Слайд 19

Path.join

Метод path.join() позволяет соединять пути в файловой системе
var path = require('path');
var myPath

Path.join Метод path.join() позволяет соединять пути в файловой системе var path =
= path.join('/foo', 'bar', 'baz/asdf', 'q');
console.log(myPath);

Слайд 20

Разные полезные мелочи

path.extname() – определяем расширение файла.
path.sep - определяем специфичный

Разные полезные мелочи path.extname() – определяем расширение файла. path.sep - определяем специфичный
для платформы разделитель в пути к файлу расширение файла.
path.delimiter - определяем специфичный для платформы разделитель путей.

Слайд 21

Разные полезные мелочи

path.dirname() - определяем имя директории, содержащей файл:
path.basename() -

Разные полезные мелочи path.dirname() - определяем имя директории, содержащей файл: path.basename() - определяем базовое имя файла
определяем базовое имя файла

Слайд 22

__dirname и __filename

две глобальные переменные платформы Node.js –
__dirname и __filename.
Первая

__dirname и __filename две глобальные переменные платформы Node.js – __dirname и __filename.
хранит имя текущей директории, вторая - текущего файла.
var path = require('path');
console.log(__dirname);
console.log(__filename);

Слайд 23

Перемещение по файловой системе

Перемещаться по файловой системе (то есть менять рабочую папку)

Перемещение по файловой системе Перемещаться по файловой системе (то есть менять рабочую
модуль fs не поможет. Это операция «ядерного уровня», она доступна через процессы.
Например, так можно узнать текущую рабочую директорию: console.log("The current working directory is " + process.cwd());

Слайд 24

Перемещение по файловой системе

Так её можно поменять:
console.log("The current directory is " +

Перемещение по файловой системе Так её можно поменять: console.log("The current directory is
process.cwd());
try {
process.chdir("D:\\Development");
console.log("The new current directory is " + process.cwd());
}
catch (exception) {
console.error("chdir error: " + exception.message);
}

Слайд 25

Работа с файлами

var fs = require('fs');
var path = "D:\\Development\\Test\\notes.txt";
fs.open(path, "r+", function (error,

Работа с файлами var fs = require('fs'); var path = "D:\\Development\\Test\\notes.txt"; fs.open(path,
fd) {
if (error) {
console.error("open error: " + error.message);
}
else {
console.log("Successfully opened " + path);
fs.close(fd, function (error) {
if (error) {
console.error("close error: " + error.message);
}
else {
console.log("Successfully closed " + path);
}
});
}
});

Слайд 26

fs.open

Метод fs.open() в качестве первого параметра принимает имя файла, последним служит функция

fs.open Метод fs.open() в качестве первого параметра принимает имя файла, последним служит
обратного вызова, а вторым - флаг режима открытия, который в Node.js имеет свои особенности.
Ниже приведены его возможные значения:
r - открыть для чтения. Генерирует исключение при отсутствии файла;
r+ -открыть для чтения и записи. Генерирует исключение при отсутствии файла;
rs -открыть для чтения в синхронном режиме;
rs+ -открыть для чтения и записи в синхронном режиме;
w - открыть для записи. Если файл не существует, он будет создан. Если файл существует, его содержимое будет очищено;
w+ - открыть для чтения и записи. Если файл не существует, он будет создан. Если файл существует, его содержимое будет очищено;
а -открыть для записи в конец файла. Если файл не существует, он будет создан;
а+ -открыть для чтения и записи в конец файла. Если файл не существует, он будет создан.

Слайд 27

Чтение на низком уровне

var fs = require('fs');
var path = "D:\\Development\\Test\\notes.txt";
fs.open(path, "r+", function

Чтение на низком уровне var fs = require('fs'); var path = "D:\\Development\\Test\\notes.txt";
(error, fd) {
if (error) {
console.error("open error: " + error.message);
}
else {
console.log("Successfully opened " + path);
fs.stat(path, function (error, stats) {
var buffer = new Buffer(stats.size);
fs.read(fd, buffer, 0, buffer.length, null, function (error, bytesRead, buffer)
{
var data = buffer.toString("utf8");
console.log(data);
});
});
}
});

Слайд 28

Чтение на низком уровне

Метод fs.read(), получая в качестве аргумента дескриптор файла, читает

Чтение на низком уровне Метод fs.read(), получая в качестве аргумента дескриптор файла,
данные из него, “как есть”, то еcть, в общем случае, в виде бинарных данных.
Для того, чтобы их получить,
мы сначала создаем буфер (для того, чтобы определиться с его размером, нам опять потребовался объект fs.stat() ),
читаем в него данные и преобразуем их в строковой формат перед выводом в консоль. Второй аргумент функции обратного вызова метода fs.read() - это количество прочитанных байт.

Слайд 29

Запись на низком уровне

Запись в файл происходит по той же схеме (сделаем

Запись на низком уровне Запись в файл происходит по той же схеме
программу которая записывает в файл логи обращения к ней):
var logltem = "Note created " + Date.now() + " ";
buffer = new Buffer(logltem);
fs.write(fd, buffer, 0, buffer.length, null, function (error, bytesWritten, buffer)
{
if (error) { console.error(error.message); }
else {
console.log("Written " + bytesWritten + " bytes.");
}
});

Слайд 30

ReadFile

На предыдущем слайде мы создаем свой буфер из заданной строки и пишем

ReadFile На предыдущем слайде мы создаем свой буфер из заданной строки и
его в файл. Все очень просто и универсально, но, честно говоря, не совсем удобно. По крайней мере, для текстовых данных. Модуль fs располагает более высокоуровневыми методами:
var fs = require('fs');
var path = "D:\\Development\\Test\\notes.txt";
fs.readFile(path, "utf8", function (error, data) {
if (error) {
console.error(error.message);
}
else {
console.log(data);
}
});

Слайд 31

WriteFile

Это все - не надо заботиться о получении файлового дескриптора и подготовке

WriteFile Это все - не надо заботиться о получении файлового дескриптора и
буфера - все это уже инкапсулировано в методы readFile, writeFile
var fs = require('fs');
var path = "D:\\Development\\Test\\notes.txt";
var logltem = "Note created " + Date.now() + "\n";
fs.writeFile(path, logltem, function (error) {
if (error) { console.error(error.message) }
else {
console.log("Successfull write " + path)
}
});
Можно также использовать метод
fs. appendFile

Слайд 32

Watching Files

Это, наверное, самая интересная возможность модуля fs. С помощью метода fs.watch()

Watching Files Это, наверное, самая интересная возможность модуля fs. С помощью метода
мы можем отслеживать состояние файлов. Например, нашего файла логов
var fs = require("fs");
var path = "D:\\Development\\Test\\notes.txt";
fs.watch(path, { persistent: true }, function (event, filename) {
console.log(event)
if (event === "rename") {
console.log("The file was renamed/deleted. ");
}
else if (event === "change") {
console.log("The file was changed.");
}
});

Слайд 33

Watching Files

Node.js для получения данных использует именно системные средства. В операционной системе

Watching Files Node.js для получения данных использует именно системные средства. В операционной
Linux это подсистема ядра inotify, в BSD и OS Х -интерфейс уведомления о событиях kqueue, в семействе Windows применяется вызов функции ReadDirectoryChangesW

Слайд 34

Потоки

var fs = require("fs");
var path = "D:\\Development\\Test\\fluid.blend";
var stream = fs.createReadStream(path);
stream.on('readable', function ()
{

Потоки var fs = require("fs"); var path = "D:\\Development\\Test\\fluid.blend"; var stream =
console.log('read');
});
stream.on('end', function () {
console.log('end');
});
stream.on('data', function (chunk) {
console.log('got %d bytes of data', chunk.length);
});

Слайд 35

Потоки

Поток можно в любой момент закрыть, вызвав метод stream. close():
stream.on('data', function

Потоки Поток можно в любой момент закрыть, вызвав метод stream. close(): stream.on('data',
(chunk) {
if (chunk.length < 10) {
stream.close();
}
console.log('got %d bytes of data', chunk.length);
});

Слайд 36

Stream.pause() & Stream.resume

для более гибкой работы с потоком присутствуют методы stream.pause() и

Stream.pause() & Stream.resume для более гибкой работы с потоком присутствуют методы stream.pause()
stream.resume():
stream.on('data', function (chunk) {
stream.pause();
console.log("stream paused");
setTimeout(function () {
console.log("stream resumed");
stream.resume();
}, 1000);
console.log('got %d bytes of data',
chunk.length);
});

Слайд 37

Веб-сервер на потоках

Освоив потоки, мы теперь можем более рационально переписать веб-сервер

Веб-сервер на потоках Освоив потоки, мы теперь можем более рационально переписать веб-сервер
из лекции №4. В чем его нерациональность? Ну хотя бы в том, что при запросе браузером очень больших файлов (а такая ситуация вполне обычна) мы вынуждены до отдачи данных целиком считывать его в память, что недопустимо для сколько-либо серьезно нагруженного веб-сервера:
/* fs.readfile(pathname, 'utf8',
function (err, data) {
if (err) {
console.log('Could not find or open file' + pathname + ' for reading\n')
}
else {
console.log(pathname + " " + mimeType);
response.write(data);
response.end();
}
}); */

Слайд 38

Веб-сервер на потоках

var http = require('http');
var url = require('url');
var fs =

Веб-сервер на потоках var http = require('http'); var url = require('url'); var
require('fs');
var port = 2222;
http.createServer(function (req, res) {
var pathname = url.parse(req.url).pathname;
if (pathname == '/') { pathname = '/index.html'; }
pathname = pathname.substring(1, pathname.length);
var stream = fs.createReadStream(pathname, { encoding: 'utf8' });
stream.on('readable', function () {
var data = stream.read();
if (data) {
res.write(data.toString());
}
});
stream.on('end', function () {
res.end();
});
}).listen(port);

Слайд 39

stream.pipe()

В таком виде все работает, причем корректно, но на самом деле

stream.pipe() В таком виде все работает, причем корректно, но на самом деле
это только полдела. Даже меньше. Мы действительно читаем данные из входящего потока, но затем перед записью в исходящий поток сохраняем их в переменную. Данная проблема решается следующим образом
stream.on('readable', function () {
//var data = stream.read();
//if (data) {
// res.write(data.toString());
//}
stream.pipe(res);
});

Слайд 40

Создаем ТСР-сервер

На платформе Node.js он реализован в модуле net, входящем в

Создаем ТСР-сервер На платформе Node.js он реализован в модуле net, входящем в
ядро системы. Построить ТСР-сервер - задача довольно тривиальная. В отличие от НТТР-сервера, функция обратного вызова, являющаяся аргументом при создании ТСР-сервера, принимает только один аргумент -экземпляр соединения. Он же сокет.

Слайд 41

Создаем ТСР-сервер

var net = require('net');
var server = net.createServer(function (socket)
{
console.log('Соединение с

Создаем ТСР-сервер var net = require('net'); var server = net.createServer(function (socket) {
' + socket.remoteAddress + ":" + socket.remotePort);
}).listen(8080);
console.log('listening on port 8080');
И стучимся браузером по адресу http://localhost:8080. В самом браузере, естественно, ничего не отобразится, зато в консоли появится запись

Слайд 42

Cокет

О сокетах. А что это, собственно, вообще такое? Если у вас такого

Cокет О сокетах. А что это, собственно, вообще такое? Если у вас
вопроса не возникает, с чистой совестью пропускайте следующую пару абзацев.
В общем случае сокет - это абстрактный объект, представляющий собой программный интерфейс для обеспечения обмена данными между процессами, вообще, любыми программными процессами. Попросту, сокет - это место встречи, пересечения, обмена данными, о котором договорились два процесса, столкнувшихся с необходимостью взаимодействовать.
По выполняемым ролям сокеты делятся на клиентские и серверные. Каждый процесс операционной системы может создать слушающий (серверный) сокет и привязать его к какому-нибудь локальному адресу (собственно, пара адресов - адрес компьютера в сети, локальный адрес - и определяют сокет как точку обмена данными). Слушающий процесс обычно находится в цикле ожидания, то есть просыпается при появлении нового соединения. Клиентские сокеты используют различные клиентские приложения (например, браузер ). Обычно клиент явно подсоединяется к слушателю, после чего любое чтение или запись через его файловый дескриптор будет передавать данные между ним и сервером.

Слайд 43

Socket.write

var net = require('net');
var server = net.createServer(function (socket)
{
console.log('Соединение с ' +

Socket.write var net = require('net'); var server = net.createServer(function (socket) { console.log('Соединение
socket.remoteAddress + ":" + socket.remotePort);
socket.write('Hello TCP!');
socket.end();
}).listen(8080);
console.log('listening on port 8080');

Слайд 44

Socket.end()

Cтрокой socket.end() мы закрываем сокет; если бы мы этого не сделали, то

Socket.end() Cтрокой socket.end() мы закрываем сокет; если бы мы этого не сделали,
браузер продолжил бы чтение из сокета, и переданное сообщение не задержалось бы на экране.
Продемонстрировать непрерывную работу сокета можно следующим кодом:

Слайд 45

Непрерывная работа сокета

var net = require('net');
var server = net.createServer(function (socket)
{
console.log('Соединение с

Непрерывная работа сокета var net = require('net'); var server = net.createServer(function (socket)
' + socket.remoteAddress + ":" + socket.remotePort);
socket.write('Hello TCP!');
var i = 0;
while (socket) {
i++;
var m = '' + i;
socket.write(m);
}
socket.end();
}).listen(8080);
console.log('listening on port 8080');

Слайд 47

Socket.on('data‘)

Заставим наш сокет слушать пару событий
var net = require('net');
var server = net.createServer(function

Socket.on('data‘) Заставим наш сокет слушать пару событий var net = require('net'); var
(socket) {
socket.on('data', function (data) {
console.log(data.toString());
socket.write("Received data: " + data);
socket.end();
});
socket.on('close', function () {
console.log("closed");
});
}).listen(8080);
console.log('listening on port 8080');

Слайд 49

Клиент ТСР-сервера

var net = require('net');
var clientSocket = new net.Socket();
clientSocket.setEncoding('utf8');
clientSocket.connect('8080', 'localhost', function ()

Клиент ТСР-сервера var net = require('net'); var clientSocket = new net.Socket(); clientSocket.setEncoding('utf8');
{
console.log('connected to server');
clientSocket.write('Hello');
});
clientSocket.on('data', function (data) {
console.log(data);
});
clientSocket.on('close', function ()
{
console.log('Соединение закрыто');
});

Слайд 50

Socket & Buffer

При логировании полученных данных мы явным образом привели их значение

Socket & Buffer При логировании полученных данных мы явным образом привели их
к строковому виду. Зачем? Да вот как раз для этого случая! Дело в том, что данные, которыми сейчас обмениваются сокеты, представлены отнюдь не в текстовом формате. В этом нетрудно убедиться, убрав приведение типов
Да, это буфер.

socket.on('data', function (data) {
console.log(data /*.toString()*/);

Слайд 51

Ввод данных

clientSocket.connect('8080', 'localhost', function () {
console.log('connected to server');
clientSocket.write('Hello', function ()

Ввод данных clientSocket.connect('8080', 'localhost', function () { console.log('connected to server'); clientSocket.write('Hello', function
{
process.stdin.resume();
process.stdin.on('data', function (data) {
clientSocket.write(data);
});
});
});

Слайд 52

TCP-чат

var net = require('net');
var clients = [];
var server = net.createServer(function (socket)
{
clients[clients.length++]

TCP-чат var net = require('net'); var clients = []; var server =
= socket;
console.log('Соединение с ' + socket.remoteAddress + ' ' + socket.remotePort);
socket.on('data', function (data) {
console.log(data);
clients.forEach(function (client) {
client.write(data);
});
});
socket.on('close', function () {
console.log("closed");
});
}).listen(8080);
console.log('listening on port 8080');

Чуть-чуть изменив код сервера, мы можем даже организовать нечто вроде ТСР-чата

Слайд 53

UDP Сервер

Продемонстрируем работу протокола, создав простой сервер, принимающий UDР-пакеты.
Обратите внимание, с объектом

UDP Сервер Продемонстрируем работу протокола, создав простой сервер, принимающий UDР-пакеты. Обратите внимание,
соединения мы не работаем, его просто нет.
var dgram = require('dgram');
var udpServer = dgram.createSocket("udp4");
udpServer.bind(8082);
udpServer.on("message", function (msg, info) {
console.log("Message: " + msg + " from " + info.address + ":" + info.port);
});

Слайд 54

UDP клиент

var dgram = require('dgram');
var client = dgram.createSocket("udp4");
process.stdin.resume();
process.stdin.on('data', function (data)

UDP клиент var dgram = require('dgram'); var client = dgram.createSocket("udp4"); process.stdin.resume(); process.stdin.on('data',
{
client.send(data, 0, data.length, 8082, "localhost", function (err, bytes) {
if (err) console.log('еrоr: ' + err);
else console.log('ОК');
});
});

Обратите внимание: проверяется только успех или неуспех отправки данных, получение отследить не представляется возможным. Зато тут же мы можем продемонстрировать преимущество протокола. Можно сколько угодно останавливать и запускать сервер - клиент останется в рабочем состоянии, и в моменты работы сервера данные будут доставлены.

Слайд 56

HTTP - клиент

А зачем? Зачем создавать НТТР-клиента, если НТТР-клиент - это браузер?

HTTP - клиент А зачем? Зачем создавать НТТР-клиента, если НТТР-клиент - это
Все просто - иногда необходимо сделать запрос по этому протоколу непосредственно из нашего приложения. Примеров можно привести много - запрос курсов валют, биржевых котировок от веб-сервисов, общающихся по этому протоколу, проведение онлайн-платежей, взаимодействие с платежными системами и тому подобные вполне распространенные случаи.

Слайд 57

HTTP - клиент

var https = require('https');
var param = {
hostname: 'api.privatbank.ua', path:

HTTP - клиент var https = require('https'); var param = { hostname:
'/p24api/pubinfo?exchange&coursid=3', port: 443, method: 'GET'
}
var req = https.request(param, function (res) {
console.log('STATUS: ' + res.statusCode);
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log('BODY: ' + chunk);
});
});
req.on('error', function (e) { console.log('problem with request: ' + e.message); });
req.end();

Слайд 58

HTTP - клиент

HTTP - клиент

Слайд 59

Модуль WS

Для того чтобы начать работать с веб-сокетами, нужны всего две вещи

Модуль WS Для того чтобы начать работать с веб-сокетами, нужны всего две
- браузер, поддерживающий WebSocket, и сервер, реализующий эту технологию.
На стороне браузера все просто - WebSockets API входит в семейство JаvаSсriрt-интерфейсов, условно объединенных под названием HTML5, и поддерживается большинством современных версий браузеров.
Серверная составляющая WebSockets присутствует в node «ИЗ коробки». Ну, почти так - все, что нужно сделать, - доставить соответствующий модуль: npm install ws

Слайд 60

WebSocket Server

var webSocketServer = new require('ws');
var webSocketServer = new webSocketServer.Server({ port: 8080

WebSocket Server var webSocketServer = new require('ws'); var webSocketServer = new webSocketServer.Server({
});
webSocketServer.on('connection', function (ws) { console.log("Hoвoe соединение"); })

Слайд 61

WebSocket Client









index


Слайд 62

WebSocket Server

Это прекрасно, но пока полнодуплексного соединения, мягко говоря, не наблюдается. Что

WebSocket Server Это прекрасно, но пока полнодуплексного соединения, мягко говоря, не наблюдается.
естественно -взаимодействия по направлению от сервера к клиенту у нас пока не происходит. Изменим код сервера:
var webSocketServer = new require('ws');
var wss = new webSocketServer.Server({ port: 8080 });
var clients = [];
wss.on('connection', function (ws) {
var id = clients.length;
clients[id] = ws;
console.log("Hoвoe соединение № " + id);
clients[id].send("Приветствуем! ваш идентификатор " + id);
for (var key in clients) {
if (key != id) {
clients[key].send("K нам присоединился» " + id);
}
}
console.log(clients);
});

Слайд 63

WebSocket Client

На клиенте напишем код для приема сообщений:
onload = function

WebSocket Client На клиенте напишем код для приема сообщений: onload = function
()
{
var ws = new WebSocket("ws://localhost:8080");
ws.onmessage = function (event) { alert(event.data); }
}

Слайд 64

Реализация WebSocket-чaтa

Сначала сделаем простую форму для отправки сообщений и jаvаSсriрt-обработчик



Реализация WebSocket-чaтa Сначала сделаем простую форму для отправки сообщений и jаvаSсriрt-обработчик onload












Слайд 65

Реализация WebSocket-чaтa
var webSocketServer = new require('ws');
var wss = new webSocketServer.Server({ port:

Реализация WebSocket-чaтa var webSocketServer = new require('ws'); var wss = new webSocketServer.Server({
8080 });
var clients = [];
wss.on('connection', function (ws) {
var id = clients.length;
clients[id] = ws;
console.log("Hoвoe соединение № " + id);
clients[id].send("Приветствуем! ваш идентификатор " + id);
for (var key in clients) {
if (key != id) {
clients[key].send("K нам присоединился» " + id); }
}
console.log(clients);
});
wss.on('message', function (message) {
console.log('noлyчeнo сообщение' + message);
for (var key in clients) {
if (key != id) {
clients[key].send(message);
}
}
});

Слайд 66

Выводы

В этой лекции была рассмотрена работа с файловой системой. Были изучены процедуры

Выводы В этой лекции была рассмотрена работа с файловой системой. Были изучены
обхода каталогов, чтения, записи на низком и на высокому уровнях, копирования и удаления файлов.
Также была изучена процедура для отслеживания состояния файлов.
Рассмотрены примеры работы с потоками ввода-вывода.
Был созданы ТСР-сервер и клиент, UPD-сервер и клиент, WebSocket-сервер и клиент.
Имя файла: Node.-js.pptx
Количество просмотров: 343
Количество скачиваний: 1