Upload
alexei-smolyanov
View
282
Download
2
Embed Size (px)
Citation preview
Node.JS: возможности для РНР-разработчика
Морозов Андрей
декан факультета информационно-компьютерных технологий ЖГТУ
1. Общие сведения - интерпретатор JavaScript, основанный на движке V8. Особенности:•использование без браузера;•обращение к файловой системе,работа с сетью;•асинхронный код;•событийно-ориентированное программирование;•библиотеки;Автор языка: Райан ДалДата выхода: 27 мая 2009 годаПоследнее обновление: 20 октября 2014 года
2. Схема работы PHP
• Запрос А выполняется за 1 секунду, он не требует обращение к БД.
• Запрос Б выполняется за 5 секунд, причем 4 из них, он тратит на ожидание ответа БД.
• Время между запросами не менее 1 секунды.
2. Схема работы PHP• Сервер с одним РНР-процессом
2. Схема работы PHP• Сервер с двумя РНР-процессами
3. Схема работы Node.JS
3. Схема работы Node.JS
4. Установка Node.JS• Под Linux:
• Под Windows:
sudo apt-get install nodejssudo apt-get install npm
5. Запуск программ• Из командной строки: node имя_файла.js
• Для управления запуском скриптов следует установить:
sudo apt-get install supervisorsudo service supervisor start
• Файлы конфигурации находятся в директории: /etc/supervisor/
• Для включения доступа через веб-интерфейс нужно добавить в файл /etc/supervisor/supervisord.conf:[inet_http_server]port = 9001username = логин password = пароль
5. Запуск программ• Для проекта создать файл конфигурации запуска
Node.JS-скрипта в директории /etc/supervisor/conf.d/файл.conf:
[program:проект]command=/usr/bin/node /путь/к файлу.jsdirectory=/путьautostart=trueautorestart=truestartretries=3stderr_logfile=/var/log/проект/файл.err.logstdout_logfile=/var/log/проект/файл.out.loguser=www-data
5. Запуск программ• Управление состоянием запущенных процессов через
командную строку:
supervisorctl start проектsupervisorctl stop проектsupervisorctl restart проект
• Управление состоянием запущенных процессов через веб-интерфейс:
6. Интегрированные среды разработки
• Коммерческие:
• JetBrains WebStorm/PhpStorm или IntelliJ IDEA
• Коммерческие:
• Microsoft Visual Studio with Node.js Tools for Visual Studio
6. Интегрированные среды разработки
• Бесплатные:
• Облачная IDE Cloud9
6. Интегрированные среды разработки
• Бесплатные:
• Nodeclipse
6. Интегрированные среды разработки
• Бесплатные:
• NetBeans IDE с Node.JS плагином
6. Интегрированные среды разработки
Простейший веб-сервер:var http = require('http');http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World\n');}).listen(80, '127.0.0.1');console.log('Server running at http://127.0.0.1:80/');
7. Создание веб-сервера
Простейший веб-сервер:
var http = require('http');http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World\n');}).listen(80, '127.0.0.1');console.log('Server running at http://127.0.0.1:80/');
7. Создание веб-сервера
Определение запрошенного URL:var http = require('http');var url = require('url');http.createServer(onRequest).listen(80, '127.0.0.1');console.log ('Server running at http://127.0.0.1:80/');
function onRequest(request, response) { var pathname = url.parse(request.url).pathname; route(pathname); response.writeHead(200, {"Content-Type": "text/plain"}); response.write("Hello World"); response.end();}function route(path){ console.log(path);}
7. Создание веб-сервера
Определение запрошенного URL:var http = require('http');var url = require('url');http.createServer(onRequest).listen(80, '127.0.0.1');console.log ('Server running at http://127.0.0.1:80/');
function onRequest(request, response) { var pathname = url.parse(request.url).pathname; route(pathname); response.writeHead(200, {"Content-Type": "text/plain"}); response.write("Hello World"); response.end();}function route(path){ console.log(path);}
7. Создание веб-сервера
Весь механизм IO Node.JS полностью асинхронен:•обработка HTTP- и TCP-запросов;•чтение и запись файлов;•запросы к БД;Если что-то делается не асинхронно – это делается неправильно!
8. Асинхронная модель
Весь механизм IO Node.JS полностью асинхронен:•обработка HTTP- и TCP-запросов;•чтение и запись файлов;•запросы к БД;Если что-то делается не асинхронно – это делается неправильно!
8. Асинхронная модель
Код, содержащий логическую ошибку:var http = require('http');var fs = require('fs')http.createServer(onRequest).listen(80, '127.0.0.1');
function onRequest(request, response) { var readData; fs.readFile('www/index.html', 'utf8', function (err, data) { if (err) { return console.log(err); } readData = data.toString(); });
response.writeHead(200, {"Content-Type": "text/html"}); response.write(readData); response.end();}
8. Асинхронная модель
Правильный код:var http = require('http');var fs = require('fs')http.createServer(onRequest).listen(80, '127.0.0.1');
function onRequest(request, response) { fs.readFile('www/index.html', 'utf8', function (err, data) { response.writeHead(200, {"Content-Type": "text/html"}); if (err) { console.log(err); response.write('Read file error!'); } else response.write(data.toString()); response.end(); });}}
8. Асинхронная модель
Плохо:var fs = require('fs')var configData = fs.readFileSync('config.xml');response.write(configData);Хорошо:var fs = require('fs')fs.readFile('config.xml', function(err, configData){
response.write(configData);});
8. Асинхронная модель
var http = require("http"), url = require("url"), path = require("path"), fs = require("fs");var directory = "/www/";port = process.argv[2] || 80;http.createServer(function(request, response) { var uri = url.parse(request.url).pathname, filename = path.join(process.cwd() + directory, uri); path.exists(filename, function(exists) { console.log(filename); if(!exists) { response.writeHead(404, {"Content-Type": "text/plain"}); response.write("404 Not Found\n"); response.end(); return; } if (fs.statSync(filename).isDirectory()) filename += '/index.html'; fs.readFile(filename, "binary", function(err, file) { if(err) { response.writeHead(500, {"Content-Type": "text/plain"}); response.write(err + "\n"); response.end(); return; } response.writeHead(200); response.write(file, "binary"); response.end(); }); });}).listen(parseInt(port, 10));
9. Статический веб-сервер
• Для установки библиотек и фреймворков:npm install –g библиотека• Для установки фреймворка express:npm install –g express• Статический сервер на Expressvar express = require('express');var app = express();app.use(express.static( __dirname + '/www'));app.listen(80);
10. Фреймворк Express
• Обработка GET-запросов:var express = require('express');var app = express();app.get('/hello', function(req, res){ res.send('hello world');});app.get('/user/:id', function(req, res){ res.send('user ' + req.params.id);});app.get(/^\/books?(?:\/(\d+)(?:\.\.(\d+))?)?/, function(req, res){
res.send(req.params);});app.use(express.static(__dirname + '/www'));app.listen(80);
10. Фреймворк Express
Серверная часть (server.js):var app = require('express')();var http = require('http').Server(app);var io = require('socket.io')(http);
app.get('/', function(req, res){ res.sendFile(__dirname + '/www/index.html');});
io.on('connection', function(socket){ socket.on('chat message', function(msg){ io.emit('chat message', msg); });});
http.listen(3000, function(){ console.log('listening on *:3000');});
11. Веб-сокеты (socket.io)
Клиентская часть (index.html):<!doctype html><html><head> <title>Socket.IO chat</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font: 13px Helvetica, Arial; } form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; } form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; } form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; } #messages { list-style-type: none; margin: 0; padding: 0; } #messages li { padding: 5px 10px; } #messages li:nth-child(odd) { background: #eee; } </style>
11. Веб-сокеты (socket.io)
Клиентская часть (index.html):<script src="http://localhost:3000/socket.io/socket.io.js"></script><script src="http://code.jquery.com/jquery-1.11.1.js"></script><script> var socket = io(); $('form').submit(function(){ socket.emit('chat message', $('#m').val()); $('#m').val(''); return false; }); socket.on('chat message', function(msg){ $('#messages').append($('<li>').text(msg)); });</script></head>
11. Веб-сокеты (socket.io)
Клиентская часть (index.html):<body> <ul id="messages"></ul> <form action=""> <input id="m" autocomplete="off" /> <button>Send</button> </form></body></html>
11. Веб-сокеты (socket.io)
Адрес http://localhost:3000/socket.io/socket.io.js:
11. Веб-сокеты (socket.io)
11. Веб-сокеты (socket.io)
12. Работа с базой данных MySQL• Установить библиотеку mysql:npm install mysql• Соединение с базой данных:var mysql = require('mysql');var connection = mysql.createConnection({
host : 'localhost', user : 'me', password : 'secret'});
connection.connect();
12. Работа с базой данных MySQL• Выполнение запросов:connection.query('SELECT user_id, user_login as login FROM users', function(err, rows, fields) {
if (err) throw err; console.log('The login is: ', rows[0]. login); });
• Подготовленные запросы:connection.query('SELECT * FROM users WHERE user_id = ?', [userId], function(err, results) { // ... });
Appjs:var app = module.exports = require('appjs');app.serveFilesFrom(__dirname + '/content');var window = app.createWindow({ width : 640, height : 460, icons : __dirname + '/content/icons'});window.on('create', function(){ console.log("Window Created"); window.frame.show(); window.frame.center();});window.on('ready', function(){ console.log("Window Ready"); window.require = require; window.process = process; window.module = module; window.addEventListener('keydown', function(e){ if (e.keyIdentifier === 'F12') { window.frame.openDevTools(); } });});window.on('close', function(){ console.log("Window Closed");});
12. Оконные приложения
• Программа на Node.JSvar sys = require('sys'), http = require('http');http.createServer(function(req, res) { res.writeHead(200, {'Content-Type': 'text/html'}); res.write('<p>Hello World</p>'); res.end();}).listen(8080);
• Программа на PHP<?phpecho '<p>Hello World</p>';
13. Тесты производительности
• 100 000 запросов, 1 000 одновременных
• 1 000 000 запросов, 20 000 одновременных
13. Тесты производительности
Время Запросов в сек.
Apache PHP 121.451 сек 823.38
nodeJS 21.162 сек. 4725.43
Время Запросов в сек.
Apache PHP 3570.753 сек 280.05
nodeJS 1043.076 сек 958.70
13. Тесты производительностиЗагрузка процессора
13. Тесты производительностиИспользование памяти
• создан форк Node.JS под названием io.js;• первый релиз готовится к выпуску 13 января 2015 года;• io.js будет Node.JS-совместимым;
14. Раскол в группе разработчиков Node.JS
Спасибо за внимание!
Морозов Андрей Васильевич, к.т.н., декан факультета информационно-
компьютерных технологий ЖГТУ,