javascript Базовый. Занятие 09

25
Темы лекции: Real-time веб приложения. Практическое задание: Real-time веб приложение. Тренер: Игорь Шкулипа, к.т.н. JavaScript. Базовый курс Занятие 9

Upload: igor-shkulipa

Post on 16-Apr-2017

142 views

Category:

Education


3 download

TRANSCRIPT

Page 1: JavaScript Базовый. Занятие 09

Темы лекции: Real-time веб приложения.

Практическое задание: Real-time веб приложение.

Тренер: Игорь Шкулипа, к.т.н.

JavaScript. Базовый курс

Занятие 9

Page 2: JavaScript Базовый. Занятие 09

http://www.slideshare.net/IgorShkulipa 2

Real-time веб приложения

Основной отличительной способностью сервисов, которые можно назватьreal-time веб-приложениями является то, что они “ломают” привычнуюнам всем модель работы в вебе – запрос-ответ, благодаря чемупользователи видят обновление данных сразу же, как только онипоявляются на сервере.

Если не знать, насколько далеко вперед шагнули технологии запоследние несколько лет, то можно предположить, что все подобныеприложения реализованы при помощи периодического опрашиваниясервера обычными Ajax-запросами, т.н. polling. Выглядит похоже, ноэто не совсем так.

Page 3: JavaScript Базовый. Занятие 09

http://www.slideshare.net/IgorShkulipa 3

Способы реализации

Техника Описание Преимущества Недостатки

Polling Постоянный опрос сервера Ajax-запросами

+ простота реализации+ поддержка во всех современных браузерах

- задержка в результатах- при уменьшении задержки существенно увеличивается нагрузка на сервер

Long Polling

Ajax-запросы, идущие один за другим, но каждый запрос держится открытым в течение нескольких минут

+ сниженная нагрузка на сервер по сравнению с обычным Polling+ уменьшенный трафик+ поддержка во всех современных браузерах

- больше одновременно открытых соединений, т.к. каждый запрос живет дольше

Page 4: JavaScript Базовый. Занятие 09

http://www.slideshare.net/IgorShkulipa 4

Способы реализации

Техника Описание Преимущества Недостатки

Server-Sent Events

Новый стандарт HTML5, работающий поверх HTTP. Позволяет создавать долгоживущее соединение с сервером, чтобы сервер мог отправлять данные на клиент

+ нет необходимости постоянно пересоединяться с сервером+ нет изменений на стороне сервера, поэтому работает на всех современных веб-серверах

- не поддерживается в IE (даже в IE10)- работает только в направлении сервер –> клиент (на сервер можно отправлять обычные Ajax запросы)

WebSockets Новый протокол (ws:// и wss://), работающий поверх TCP на одном уровне с HTTP. Позволяет создавать двустороннее долгоживущее соединение с клиентом

+ нет необходимости постоянно пересоединяться с сервером+ работает в двустороннем режиме

- поддерживается не во всех веб-серверах (IIS8)- поддерживается не во всех браузерах (в IE7-9, Android)

Page 5: JavaScript Базовый. Занятие 09

http://www.slideshare.net/IgorShkulipa 5

WebSocket

Протокол WebSocket (стандарт RFC 6455) предназначен для решениялюбых задач и снятия ограничений обмена данными между браузероми сервером.

Он позволяет пересылать любые данные, на любой домен, безопасно ипочти без лишнего сетевого трафика.

Page 6: JavaScript Базовый. Занятие 09

http://www.slideshare.net/IgorShkulipa 6

WebSocket

WebSocket — современное средство коммуникации. Кросс-доменное,универсальное, безопасное.

На текущий момент он работает в браузерах IE10, FF11, Chrome 16, Safari6, Opera 12.5. В более старых версиях FF, Chrome, Safari, Opera естьподдержка черновых редакций протокола.

Там, где вебсокеты не работают — обычно используют другиетранспорты.

Есть и готовые библиотеки, реализующие функционал COMET сиспользованием сразу нескольких транспортов, из которых вебсокетимеет приоритет. Как правило, библиотеки состоят из двух частей:клиентской и серверной.

Например, для Node.JS одной из самых известных библиотек являетсяSocket.IO.

К недостаткам библиотек следует отнести то, что некоторые продвинутыевозможности WebSocket, такие как двухсторонний обмен бинарнымиданными, в них недоступны. С другой — в большинстве случаевстандартного текстового обмена вполне достаточно.

Page 7: JavaScript Базовый. Занятие 09

http://www.slideshare.net/IgorShkulipa 7

NodeJS

Node или Node.js — программная платформа, основанная на движке V8(транслирующем JavaScript в машинный код), превращающая JavaScript изузкоспециализированного языка в язык общего назначения.

Node.js добавляет возможность JavaScript взаимодействовать с устройствами ввода-вывода через свой API (написанный на C++), подключать другие внешниебиблиотеки, написанные на разных языках, обеспечивая вызовы к ним изJavaScript-кода.

Node.js применяется преимущественно на сервере, выполняя роль веб-сервера, ноесть возможность разрабатывать на Node.js и десктопные оконные приложения(при помощи node-webkit и AppJS для Linux, Windows и Mac OS) и дажепрограммировать микроконтроллеры (например, tessel и espruino). В основеNode.js лежит событийно-ориентированное и асинхронное (или реактивное)программирование с неблокирующим вводом/выводом.

Node разработал Райан Дал (англ. Ryan Dahl) в 2009 году после двух летэкспериментирования над созданием серверных веб-компонентов. В ходе своихисследований он пришёл к выводу, что вместо традиционной моделипараллелизма на основе потоков следует обратиться к событийно-ориентированным системам. Эта модель была выбрана из-за простоты, низкихнакладных расходов (по сравнению с идеологией «один поток на каждоесоединение») и быстродействия. Целью Node является предложить «простойспособ построения масштабируемых сетевых серверов».

Page 8: JavaScript Базовый. Занятие 09

http://www.slideshare.net/IgorShkulipa 8

Ссылки

http://nodejs.org/

http://www.nodebeginner.ru/

Page 9: JavaScript Базовый. Занятие 09

http://www.slideshare.net/IgorShkulipa 9

Пример. Самый простой сервер

var http = require("http");

http.createServer(function (request, response) {

response.writeHead(200, { “Content-Type”: “text/plain” });

response.end("Hello, World from NodeJS");

}).listen(12345);

Page 10: JavaScript Базовый. Занятие 09

http://www.slideshare.net/IgorShkulipa 10

Пример. Чат. Сервер. chatserver.js

var ws = require("nodejs-websocket");

var server = ws.createServer(function (connection) {

connection.on("text", function (message) {

console.log("Message Received");

server.connections.forEach(function (conn) {

conn.sendText(message);

console.log("Message Sent");

});

})

}).listen(12345)

Необходимо доустановить

пакетдля Node.js

Page 11: JavaScript Базовый. Занятие 09

http://www.slideshare.net/IgorShkulipa 11

Пример. Чат. Клиент. HTML

<!DOCTYPE html> <html> <head>

<title>JavaScript OOP Example</title>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<link rel="stylesheet" href="css/site.css" type="text/css" />

<script type="text/javascript" src="js/functions.js"> </script>

<script type="text/javascript" src="js/chatclient.js"> </script>

<body>

<div id="page">

<div id="head">

<div id="logo">

<img src="img/logo.png" height="94" width="100" alt="logo">

</div>

<div id="title">JavaScript OOP Example</div>

</div>

<div class="main">

<div class="innermain">

<div id="menu" class="menu">

<a href="#" id="mi1" class="menuitem">Chat</a>

</div>

<div id="content" class="content">

</div> </div> </div>

<div id="foot">

<p onmouseover="this.className = 'pmouseover'"

onmouseout="this.className = 'pmouseout'">

Move Closer to Change the Style</p>

</div> </div>

Page 12: JavaScript Базовый. Занятие 09

http://www.slideshare.net/IgorShkulipa 12

Пример. Чат. Клиент. HTML

<script type="text/javascript">

var mi1 = document.getElementById("mi1");

mi1.addEventListener("click", ChatMenuItemClick, false);

</script>

</body>

</html>

Page 13: JavaScript Базовый. Занятие 09

http://www.slideshare.net/IgorShkulipa 13

Пример. Чат. Клиент. functions.js

function Show(element) {

element.setAttribute("style", "visibility:visible");

}

function Hide(element) {

element.setAttribute("style", "visibility:hidden");

}

String.format = function () {

// The string containing the format items (e.g. "{0}")

// will and always has to be the first argument.

var theString = arguments[0];

// start with the second argument (i = 1)

for (var i = 1; i < arguments.length; i++) {

// "gm" = RegEx options for Global search (more than one instance)

// and for Multiline search

var regEx = new RegExp("\\{" + (i - 1) + "\\}", "gm");

theString = theString.replace(regEx, arguments[i]);

}

return theString;

}

Page 14: JavaScript Базовый. Занятие 09

http://www.slideshare.net/IgorShkulipa 14

Пример. Чат. Клиент. chatclient.jsChatUI = {

// Айдишники элементов интерфейса

GlobalChatDivID: "",

WelcomeHeaderID: "welcomeHeader",

LoginDivID: "loginDiv",

LoginTextBoxID: "usernameText",

LoginButtonID: "connectButton",

MainChatDivID: "mainChatDiv",

InputMessageDivID: "inputMessageDiv",

InputMessageTextBoxID: "inputMessageText",

InputMessageButtonID: "inputMessageButton",

MessagesDivID: "messagesDiv",

MessagesListID: "messagesList",

//Заголовки

MainHeaderText: "Chat",

ConnectButtonText: "Connect",

SendButtonText: "Send",

// Сообщения

WelcomeMessageText: "Welcome, {0}!",

InputNameMessageText: "You must input the name!",

InputMessageMessageText: "You must input message!",

ConnectedToChatMessageText: "Connected!",

ErrorMessageText: "An Error Occured!",

Page 15: JavaScript Базовый. Занятие 09

http://www.slideshare.net/IgorShkulipa 15

Пример. Чат. Клиент. chatclient.js// Пользовательский интерфейс

GetWelcomeHeader: function () {

return String.format("<h2 id=\"{0}\">{1}</h2>",

ChatUI.WelcomeHeaderID,

ChatUI.MainHeaderText);

},

GetLoginDiv: function () {

return String.format("<div id=\"{0}\" class=\"container\">" +

"<input type=\"text\" id=\"{1}\" />" +

"<input type=\"button\" id=\"{2}\" value=\"{3}\" /></div>",

ChatUI.LoginDivID,

ChatUI.LoginTextBoxID,

ChatUI.LoginButtonID,

ChatUI.ConnectButtonText);

},

GetMainChatDiv: function () {

return String.format("<div id=\"{0}\"><div id=\"{1}\" class=\"container\">" +

"<input type=\"text\" id=\"{2}\" />" +

"<input type=\"button\" id=\"{3}\" value=\"{4}\" /></div>" +

"<div id=\"{5}\" class=\"container\">" +

"<ul id=\"{6}\"></ul\></div></div>",

ChatUI.MainChatDivID,

ChatUI.InputMessageDivID,

ChatUI.InputMessageTextBoxID,

ChatUI.InputMessageButtonID,

ChatUI.SendButtonText,

ChatUI.MessagesDivID,

ChatUI.MessagesListID);

},

Page 16: JavaScript Базовый. Занятие 09

http://www.slideshare.net/IgorShkulipa 16

Пример. Чат. Клиент. chatclient.js// Добавление сообщения в список

AddMessageToUI: function (name, message) {

$(ChatUI.MessagesListID).innerHTML += String.format("<li><strong>{0}</strong>:

{1}</li>", name, message);

},

// Обработчики кнопок

LoginButtonClick: function () {

ChatEngine.UserName = $(ChatUI.LoginTextBoxID).value;

if (ChatEngine.UserName.length > 0) {

Show($(ChatUI.MainChatDivID));

Hide($(ChatUI.LoginDivID));

$(ChatUI.WelcomeHeaderID).innerHTML =

String.format(ChatUI.WelcomeMessageText, ChatEngine.UserName);

ChatEngine.StartChat();

}

else {

alert(ChatUI.InputNameMessageText);

}

},

SendMessageButtonClick: function () {

var message = $(ChatUI.InputMessageTextBoxID).value;

if (message.length > 0) {

ChatEngine.SendMessageToServer(message);

$(ChatUI.InputMessageTextBoxID).value = "";

}

else {

alert(ChatUI.InputMessageMessageText);

}

},

Page 17: JavaScript Базовый. Занятие 09

http://www.slideshare.net/IgorShkulipa 17

Пример. Чат. Клиент. chatclient.js

ShowUI: function (divID) {

ChatUI.GlobalChatDivID = divID;

$(ChatUI.GlobalChatDivID).innerHTML =

ChatUI.GetWelcomeHeader() +

ChatUI.GetLoginDiv() +

ChatUI.GetMainChatDiv();

Hide($(ChatUI.MainChatDivID));

Show($(ChatUI.LoginDivID));

},

BindEventHandlers: function () {

$(ChatUI.LoginButtonID).addEventListener("click",

ChatUI.LoginButtonClick, false);

$(ChatUI.InputMessageButtonID).addEventListener("click",

ChatUI.SendMessageButtonClick, false);

}

}

Page 18: JavaScript Базовый. Занятие 09

http://www.slideshare.net/IgorShkulipa 18

Пример. Чат. Клиент. chatclient.js

ChatMessage = {

Divider: ":-:",

User: "",

Message: "",

ToString: function () {

return this.User + this.Divider + this.Message;

},

FromSring: function (str) {

this.User = str.substring(0, str.indexOf(this.Divider));

this.Message = str.substring(str.indexOf(this.Divider) +

this.Divider.length);

}

};

Page 19: JavaScript Базовый. Занятие 09

http://www.slideshare.net/IgorShkulipa 19

Пример. Чат. Клиент. chatclient.js

ChatEngine = {

ServerAddress: "",

Connection: Object,

UserName: "",

StartChat: function () {

window.WebSocket = window.WebSocket || window.MozWebSocket;

ChatEngine.Connection = new WebSocket("ws://" + ChatEngine.ServerAddress);

ChatEngine.Connection.onopen = function () {

alert(ChatUI.ConnectedToChatMessageText);

};

ChatEngine.Connection.onerror = function (error) {

alert(ChatUI.ErrorMessageText);

};

ChatEngine.Connection.onmessage = function (message) {

ChatMessage.FromSring(message.data)

ChatUI.AddMessageToUI(ChatMessage.User, ChatMessage.Message);

};

},

SendMessageToServer: function (message) {

ChatMessage.User = ChatEngine.UserName;

ChatMessage.Message = message;

ChatEngine.Connection.send(ChatMessage.ToString());

}

};

Page 20: JavaScript Базовый. Занятие 09

http://www.slideshare.net/IgorShkulipa 20

Пример. Чат. Клиент. chatclient.js

function ChatMenuItemClick() {

ChatUI.ShowUI("content");

ChatUI.BindEventHandlers();

ChatEngine.ServerAddress = "127.0.0.1:12345";

}

Page 21: JavaScript Базовый. Занятие 09

http://www.slideshare.net/IgorShkulipa 21

Пример. Результат

Page 22: JavaScript Базовый. Занятие 09

http://www.slideshare.net/IgorShkulipa 22

Пример. Результат

Page 23: JavaScript Базовый. Занятие 09

http://www.slideshare.net/IgorShkulipa 23

Пример. Результат

Page 24: JavaScript Базовый. Занятие 09

http://www.slideshare.net/IgorShkulipa 24

Пример. Результат

Page 25: JavaScript Базовый. Занятие 09

http://www.slideshare.net/IgorShkulipa 25

Лабораторная работа №6.

Добавить чат на персональную страницу