Главная страница
Навигация по странице:

  • Свойства http.METHODS

  • Методы http.createServer()

  • Классы Модуль HTTP предоставляет 5 классов — ​Agent​, ​ClientRequest​, ​Server​, ​ServerResponse​ и IncomingMessage​. Рассмотрим их. http.Agent

  • Работа с потоками в Node.js

  • О сильных сторонах использования потоков

  • Протоколы http и WebSocket Часть 9 работа с файловой системой Часть 10 стандартные модули, потоки, базы данных, node env


    Скачать 1.79 Mb.
    НазваниеПротоколы http и WebSocket Часть 9 работа с файловой системой Часть 10 стандартные модули, потоки, базы данных, node env
    Дата03.03.2019
    Размер1.79 Mb.
    Формат файлаpdf
    Имя файлаee86eb4f-db9f-48d3-8094-c76e14414678.pdf
    ТипПротокол
    #69437
    страница8 из 9
    1   2   3   4   5   6   7   8   9
    Часть 10: стандартные модули, потоки, базы данных, NODE_ENV
    Модуль Node.js os
    Модуль ​os​ даёт доступ ко многим функциям, которые можно использовать для получения информации об операционной системе и об аппаратном обеспечении компьютера, на котором работает Node.js. Это стандартный модуль, устанавливать его не надо, для работы с ним из кода его достаточно подключить: const os = require('os')
    Здесь имеются несколько полезных свойств, которые, в частности, могут пригодиться при работе с файлами.
    Так, свойство ​os.EOL​ позволяет узнать используемый в системе разделитель строк (признак конца строки). В Linux и macOS это ​\n​, в Windows — ​\r\n​.
    Надо отметить, что упоминая тут «Linux и macOS», мы говорим о POSIX-совместимых платформах.
    Ради краткости изложения менее популярные платформы мы тут не упоминаем.
    Свойство ​os.constants.signals​ даёт сведения о константах, используемых для обработки сигналов процессов наподобие ​SIGHUP​, ​SIGKILL​, и так далее. ​
    Здесь​
    можно найти подробности о них.
    Свойство ​os.constants.errno​ содержит константы, используемые для сообщений об ошибках — наподобие ​EADDRINUSE​, ​EOVERFLOW​.
    Теперь рассмотрим основные методы модуля ​os​.
    os.arch()
    Этот метод возвращает строку, идентифицирующую архитектуру системы, например — ​arm​, ​x64​, arm64​.
    os.cpus()
    Возвращает информацию о процессорах, доступных в системе. Например, эти сведения могут выглядеть так:
    [ { model: 'Intel(R) Core(TM)2 Duo CPU P8600 @ 2.40GHz', speed: 2400, times:
    { user: 281685380, nice: 0, sys: 187986530,
    idle: 685833750, irq: 0 } },
    { model: 'Intel(R) Core(TM)2 Duo CPU P8600 @ 2.40GHz', speed: 2400, times:
    { user: 282348700, nice: 0, sys: 161800480, idle: 703509470, irq: 0 } } ]
    os.endianness()
    Возвращает ​BE​ или ​LE​ в зависимости от того, какой ​
    порядок байтов​
    (Big Engian или Little Endian) был использован для компиляции бинарного файла Node.js.
    os.freemem()
    Возвращает количество свободной системной памяти в байтах.
    os.homedir()
    Возвращает путь к домашней директории текущего пользователя. Например — ​'/Users/flavio'​.
    os.hostname()
    Возвращает имя хоста.
    os.loadavg()
    Возвращает, в виде массива, данные о средних значениях нагрузки, вычисленные операционной системой. Эта информация имеет смысл только в Linux и macOS. Выглядеть она может так:
    [ 3.68798828125, 4.00244140625, 11.1181640625 ]
    os.networkInterfaces()
    Возвращает сведения о сетевых интерфейсах, доступных в системе. Например:
    { lo0:
    [ { address: '127.0.0.1', netmask: '255.0.0.0', family: 'IPv4', mac: 'fe:82:00:00:00:00', internal: true },
    { address: '::1', netmask: 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', family: 'IPv6',
    mac: 'fe:82:00:00:00:00', scopeid: 0, internal: true },
    { address: 'fe80::1', netmask: 'ffff:ffff:ffff:ffff::', family: 'IPv6', mac: 'fe:82:00:00:00:00', scopeid: 1, internal: true } ], en1:
    [ { address: 'fe82::9b:8282:d7e6:496e', netmask: 'ffff:ffff:ffff:ffff::', family: 'IPv6', mac: '06:00:00:02:0e:00', scopeid: 5, internal: false },
    { address: '192.168.1.38', netmask: '255.255.255.0', family: 'IPv4', mac: '06:00:00:02:0e:00', internal: false } ], utun0:
    [ { address: 'fe80::2513:72bc:f405:61d0', netmask: 'ffff:ffff:ffff:ffff::', family: 'IPv6', mac: 'fe:80:00:20:00:00', scopeid: 8, internal: false } ] }
    os.platform()
    Возвращает сведения о платформе, для которой был скомпилирован Node.js. Вот некоторые из возможных возвращаемых значений:
    ● darwin

    ● freebsd
    ● linux
    ● openbsd
    ● win32
    os.release()
    Возвращает строку, идентифицирующую номер релиза операционной системы.
    os.tmpdir()
    Возвращает путь к заданной в системе директории для хранения временных файлов.
    os.totalmem()
    Возвращает общее количество системной памяти в байтах.
    os.type()
    Возвращает сведения, позволяющие идентифицировать операционную систему. Например:
    ● Linux​ — Linux.
    ● Darwin​ — macOS.
    ● Windows_NT​ — Windows.
    os.uptime()
    Возвращает время работы системы в секундах с последней перезагрузки.
    Модуль Node.js events
    Модуль ​events​ предоставляет нам класс ​EventEmitter​, который предназначен для работы с событиями на платформе Node.js. Мы уже немного говорили об этом модуле в ​
    седьмой​
    части этой серии материалов. ​
    Вот​
    документация к нему. Здесь рассмотрим API этого модуля. Напомним, что для использования его в коде нужно, как это обычно бывает со стандартными модулями, его подключить.
    После этого надо создать новый объект ​EventEmitter​. Выглядит это так: const EventEmitter = require('events') const door = new EventEmitter()
    Объект класса ​EventEmitter​ пользуется стандартными механизмами, в частности — следующими событиями:
    ● newListener​ — это событие вызывается при добавлении обработчика событий.
    ● removeListener​ — вызывается при удалении обработчика.
    Рассмотрим наиболее полезные методы объектов класса ​EventEmitter​ (подобный объект в названиях методов обозначен как ​emitter​).
    emitter.addListener()
    Псевдоним для метода ​emitter.on()​.
    emitter.emit()
    Генерирует событие. Синхронно вызывает все обработчики события в том порядке, в котором они были зарегистрированы.
    emitter.eventNames()
    Возвращает массив, который содержит зарегистрированные события.

    emitter.getMaxListeners()
    Возвращает максимальное число обработчиков, которые можно добавить к объекту класса
    EventEmitter​. По умолчанию это 10. При необходимости этот параметр можно увеличить или уменьшить с использованием метода ​setMaxListeners()​.
    emitter.listenerCount()
    Возвращает количество обработчиков события, имя которого передаётся данному методу в качестве параметра: door.listenerCount('open')
    emitter.listeners()
    Возвращает массив обработчиков события для соответствующего события, имя которого передано этому методу: door.listeners('open')
    emitter.off()
    Псевдоним для метода ​emitter.removeListener()​, появившийся в Node 10.
    emitter.on()
    Регистрируеn коллбэк, который вызывается при генерировании события. Вот как им пользоваться: door.on('open', () => { console.log('Door was opened')
    })
    emitter.once()
    Регистрирует коллбэк, который вызывается только один раз — при первом возникновении события, для обработки которого зарегистрирован этот коллбэк. Например: const EventEmitter = require('events') const ee = new EventEmitter() ee.once('my-event', () => {
    //вызвать этот коллбэк один раз при первом возникновении события
    })
    emitter.prependListener()
    При регистрации обработчика с использованием методов ​on()​ или ​addListener()​ этот обработчик добавляется в конец очереди обработчиков и вызывается для обработки соответствующего события последним. При использовании метода ​prependListener()​ обработчик добавляется в начало очереди, что приводит к тому, что он будет вызываться для обработки события первым.
    emitter.prependOnceListener()
    Этот метод похож на предыдущий. А именно, когда обработчик, предназначенный для однократного вызова, регистрируется с помощью метода ​once()​, он оказывается последним в очереди обработчиков и последним вызывается. Метод ​prependOnceListener()​ позволяет добавить такой обработчик в начало очереди.

    emitter.removeAllListeners()
    Данный метод удаляет все обработчики для заданного события, зарегистрированные в соответствующем объекте. Пользуются им так: door.removeAllListeners('open')
    emitter.removeListener()
    Удаляет заданный обработчик, который нужно передать данному методу. Для того чтобы сохранить обработчик для последующего удаления соответствующий коллбэк можно назначить переменной.
    Выглядит это так: const doSomething = () => {} door.on('open', doSomething) door.removeListener('open', doSomething)
    emitter.setMaxListeners()
    Этот метод позволяет задать максимальное количество обработчиков, которые можно добавить к отдельному событию в экземпляре класса ​EventEmitter​. По умолчанию, как уже было сказано, можно добавить до 10 обработчиков для конкретного события. Это значение можно изменить.
    Пользуются данным методом так: door.setMaxListeners(50)
    Модуль Node.js http
    В ​
    восьмой​
    части этой серии материалов мы уже говорили о стандартном модуле Node.js ​http​. Он даёт в распоряжение разработчика механизмы, предназначенные для создания HTTP-серверов. Он является основным модулем, применяемым для решения задач обмена данными по сети в Node.js.
    Подключить его в коде можно так: const http = require('http')
    В его состав входят свойства, методы и классы. Поговорим о них.
    Свойства
    http.METHODS
    В этом свойстве перечисляются все поддерживаемые методы HTTP:
    > require('http').METHODS
    [ 'ACL',
    'BIND',
    'CHECKOUT',
    'CONNECT',
    'COPY',
    'DELETE',
    'GET',
    'HEAD',

    'LINK',
    'LOCK',
    'M-SEARCH',
    'MERGE',
    'MKACTIVITY',
    'MKCALENDAR',
    'MKCOL',
    'MOVE',
    'NOTIFY',
    'OPTIONS',
    'PATCH',
    'POST',
    'PROPFIND',
    'PROPPATCH',
    'PURGE',
    'PUT',
    'REBIND',
    'REPORT',
    'SEARCH',
    'SUBSCRIBE',
    'TRACE',
    'UNBIND',
    'UNLINK',
    'UNLOCK',
    'UNSUBSCRIBE' ]
    http.STATUS_CODES
    Здесь содержатся коды состояния HTTP и их описания:
    > require('http').STATUS_CODES
    { '100': 'Continue',
    '101': 'Switching Protocols',
    '102': 'Processing',

    '200': 'OK',
    '201': 'Created',
    '202': 'Accepted',
    '203': 'Non-Authoritative Information',
    '204': 'No Content',
    '205': 'Reset Content',
    '206': 'Partial Content',
    '207': 'Multi-Status',
    '208': 'Already Reported',
    '226': 'IM Used',
    '300': 'Multiple Choices',
    '301': 'Moved Permanently',
    '302': 'Found',
    '303': 'See Other',
    '304': 'Not Modified',
    '305': 'Use Proxy',
    '307': 'Temporary Redirect',
    '308': 'Permanent Redirect',
    '400': 'Bad Request',
    '401': 'Unauthorized',
    '402': 'Payment Required',
    '403': 'Forbidden',
    '404': 'Not Found',
    '405': 'Method Not Allowed',
    '406': 'Not Acceptable',
    '407': 'Proxy Authentication Required',
    '408': 'Request Timeout',
    '409': 'Conflict',
    '410': 'Gone',
    '411': 'Length Required',

    '412': 'Precondition Failed',
    '413': 'Payload Too Large',
    '414': 'URI Too Long',
    '415': 'Unsupported Media Type',
    '416': 'Range Not Satisfiable',
    '417': 'Expectation Failed',
    '418': 'I\'m a teapot',
    '421': 'Misdirected Request',
    '422': 'Unprocessable Entity',
    '423': 'Locked',
    '424': 'Failed Dependency',
    '425': 'Unordered Collection',
    '426': 'Upgrade Required',
    '428': 'Precondition Required',
    '429': 'Too Many Requests',
    '431': 'Request Header Fields Too Large',
    '451': 'Unavailable For Legal Reasons',
    '500': 'Internal Server Error',
    '501': 'Not Implemented',
    '502': 'Bad Gateway',
    '503': 'Service Unavailable',
    '504': 'Gateway Timeout',
    '505': 'HTTP Version Not Supported',
    '506': 'Variant Also Negotiates',
    '507': 'Insufficient Storage',
    '508': 'Loop Detected',
    '509': 'Bandwidth Limit Exceeded',
    '510': 'Not Extended',
    '511': 'Network Authentication Required' }

    http.globalAgent
    Данное свойство указывает на глобальный экземпляр класса ​http.Agent​. Он используется для управления соединениями. Его можно считать ключевым компонентом HTTP-подсистемы Node.js.
    Подробнее о классе ​http.Agent​ мы поговорим ниже.
    Методы
    http.createServer()
    Возвращает новый экземпляр класса ​http.Server​. Вот как пользоваться этим методом для создания
    HTTP-сервера: const server = http.createServer((req, res) => {
    //в этом коллбэке будут обрабатываться запросы
    })
    http.request()
    Позволяет выполнить HTTP-запрос к серверу, создавая экземпляр класса ​http.ClientRequest​.
    http.get()
    Этот метод похож на ​http.request()​, но он автоматически устанавливает метод HTTP в значение
    GET​ и автоматически же вызывает команду вида ​req.end()​.
    Классы
    Модуль HTTP предоставляет 5 классов — ​Agent​, ​ClientRequest​, ​Server​, ​ServerResponse​ и
    IncomingMessage​. Рассмотрим их.
    http.Agent
    Глобальный экземпляр класса ​http.Agent​, создаваемый Node.js, используется для управления соединениями. Он применяется в качестве значения по умолчанию всеми HTTP-запросами и обеспечивает постановку запросов в очередь и повторное использование сокетов. Кроме того, он поддерживает пул сокетов, что позволяет обеспечить высокую производительность сетевой подсистемы Node.js. При необходимости можно создать собственный объект ​http.Agent​.
    http.ClientRequest
    Объект класса ​http.ClientRequest​, представляющий собой выполняющийся запрос, создаётся при вызове методов ​http.request()​ или ​http.get()​. При получении ответа на запрос вызывается событие ​response​, в котором передаётся ответ — экземпляр ​http.IncomingMessage​. Данные, полученные после выполнения запроса, можно обработать двумя способами:
    ● Можно вызвать метод ​response.read()​.
    ● В обработчике события ​response​ можно настроить прослушиватель для события ​data​, что позволяет работать с потоковыми данными.
    http.Server
    Экземпляры этого класса используются для создания серверов с применением команды http.createServer()​. После того, как у нас имеется объект сервера, мы можем воспользоваться его методами:
    ● Метод ​listen()​ используется для запуска сервера и организации ожидания и обработки входящих запросов.
    ● Метод ​close()​ останавливает сервер.

    http.ServerResponse
    Этот объект создаётся классом ​http.Server​ и передаётся в качестве второго параметра событию request​ при его возникновении. Обычно подобным объектам в коде назначают имя ​res​: const server = http.createServer((req, res) => {
    //res - это объект http.ServerResponse
    })
    В таких обработчиках, после того, как ответ сервера будет готов к отправке клиенту, вызывают метод end()​, завершающий формирование ответа. Этот метод необходимо вызывать после завершения формирования каждого ответа.
    Вот методы, которые используются для работы с HTTP-заголовками:
    ● getHeaderNames()​ — возвращает список имён установленных заголовков.
    ● getHeaders()​ — возвращает копию установленных HTTP-заголовков.
    ● setHeader('headername', value)​ — устанавливает значение для заданного заголовка.
    ● getHeader('headername')​ — возвращает установленный заголовок.
    ● removeHeader('headername')​ — удаляет установленный заголовок.
    ● hasHeader('headername')​ — возвращает ​true​ если в ответе уже есть заголовок, имя которого передано этому методу.
    ● headersSent()​ — возвращает ​true​ если заголовки уже отправлены клиенту.
    После обработки заголовков их можно отправить клиенту, вызвав метод ​response.writeHead()​, который, в качестве первого параметра, принимает код состояния. В качестве второго и третьего параметров ему можно передать сообщение, соответствующее коду состояния, и заголовки.
    Для отправки данных клиенту в теле ответа используют метод ​write()​. Он отправляет буферизованные данные в поток HTTP-ответа.
    Если до этого заголовки ещё не были установлены командой ​response.writeHead()​, сначала будут отправлены заголовки с кодом состояния и сообщением, которые заданы в запросе. Задавать их значения можно, устанавливая значения для свойств ​statusCode​ и ​statusMessage​: response.statusCode = 500 response.statusMessage = 'Internal Server Error'
    http.IncomingMessage
    Объект класса ​http.IncomingMessage​ создаётся в ходе работы следующих механизмов:
    ● http.Server​ — при обработке события ​request​.
    ● http.ClientRequest​ — при обработке события ​response​.
    Его можно использовать для работы с данными ответа. А именно:
    ● Для того чтобы узнать код состояния ответа и соответствующее сообщение используются свойства ​statusCode​ и ​statusMessage​.
    ● Заголовки ответа можно посмотреть, обратившись к свойству ​headers​ или ​rawHearders​ (для получения списка необработанных заголовков).
    ● Метод запроса можно узнать, воспользовавшись свойством ​method​.
    ● Узнать используемую версию HTTP можно с помощью свойства ​httpVersion​.
    ● Для получения URL предназначено свойство ​url​.
    ● Свойство ​socket​ позволяет получить объект ​net.Socket​, связанный с соединением.

    Данные ответа представлены в виде потока так как объект ​http.IncomingMessage​ реализует интерфейс ​Readable Stream​.
    Работа с потоками в Node.js
    Потоки — это одна из фундаментальных концепций, используемых в Node.js-приложениях. Потоки — это инструменты, которые позволяют выполнять чтение и запись файлов, организовывать сетевое взаимодействие систем, и, в целом — эффективно реализовывать операции обмена данными.
    Концепция потоков не уникальна для Node.js. Они появились в ОС семейства Unix десятки лет назад. В частности, программы могут взаимодействовать друг с другом, передавая потоки данных с использованием конвейеров (с применением символа конвейера — ​|​).
    Если представить себе, скажем, чтение файла без использования потоков, то, в ходе выполнения соответствующей команды, содержимое файла будет целиком считано в память, после чего с этим содержимым можно будет работать.
    Благодаря использованию механизма потоков файлы можно считывать и обрабатывать по частям, что избавляет от необходимости хранить в памяти большие объёмы данных.
    Модуль Node.js ​
    stream​
    представляет собой основу, на которой построены все API, поддерживающие работу с потоками.
    О сильных сторонах использования потоков
    Потоки, в сравнении с другими способами обработки данных, отличаются следующими преимуществами:
    ● Эффективное использование памяти. Работа с потоком не предполагает хранения в памяти больших объёмов данных, загружаемых туда заранее, до того, как появится возможность их обработать.
    ● Экономия времени. Данные, получаемые из потока, можно начать обрабатывать гораздо быстрее, чем в случае, когда для того, чтобы приступить к их обработке, приходится ждать их полной загрузки.
    1   2   3   4   5   6   7   8   9


    написать администратору сайта