Используя функцию jsonPost
на адрес http://students.a-level.com.ua:10012 напишите чат-клиент, который:
Для поиграться скопируйте в консоль функцию jsonPost
(или запустите её с этой страницы) и вызовите её с теми или иными объектами в качестве второго параметра. см. RPC
.
jsonPost("http://students.a-level.com.ua:10012", {func: 'addMessage', nick: "Anon", message: 'Я не умею копипастить в консоль, зато умею жать красную кнопку.'})
Если после объявления функции jsonPost
запустить пример выше, то вы напишите в чат.
Отправляет сообщения в чат. Для проверки отслеживайте приходящий с сервера nextMessageId
, который должен увеличиваться.
Интерфейс: поле ввода ника, поле ввода сообщения, кнопка отправки.
Читает только новые сообщения из чата. Для этого надо после каждого получения запоминать nextMessageId
и отправлять его
при следующем запросе новых сообщений. Изначально nextMessageId
равен нулю, что бы вычитать всю историю сообщений с сервера.
Интерфейс: некий div
-контейнер, в котором на каждое сообщение создается div
(или иной блочный контейнерный тэг) и в
него помещается ник и сообщение. Также там есть timestamp
который может показывать время отправки сообщения.
Делаем Stage 2 в setInterval
для периодической проверки сообщений (раз в 2 -5 секунд).
Напишите асинхронную функцию отправки, которая внутри себя будет делать два запроса: на отправку и на проверку, для того что бы
минимизировать задержку между отправкой сообщения пользователя и его появлением в окне чата. Оформите отдельно функции отправки и
проверки новых сообщений как асинхронные (async
, возвращает Promise
)
jsonPost
Данная промисифицированная функция (кстати, сделайте из неё асинхронную) умеет общаться с моим чат-сервером отправляя RPC запросы используя JSON. Remote Procedure Call - вызов функций удаленно, имя функции и параметры передаются AJAX-ом в формате (например) JSON.
function jsonPost(url, data)
{
return new Promise((resolve, reject) => {
var x = new XMLHttpRequest();
x.onerror = () => reject(new Error('jsonPost failed'))
//x.setRequestHeader('Content-Type', 'application/json');
x.open("POST", url, true);
x.send(JSON.stringify(data))
x.onreadystatechange = () => {
if (x.readyState == XMLHttpRequest.DONE && x.status == 200){
resolve(JSON.parse(x.responseText))
}
else if (x.status != 200){
reject(new Error('status is not 200'))
}
}
})
}
Первым параметром указывается URL (см. выше) на который отправляется методом POST с JSON, вторым - готовый к JSONификации объект, который вы хотите отправить на сервер.
addMessage
Если вы отправите подобный JSON на сервер (см jsonPost
), то сервер запишет ваше сообщение во внутренний массив и отдаст новую длину массива. После этого
другие могут прочесть это сообщение, используя метод getMessages
.
{func: "addMessage", nick: 'msg', message: 'msg'}
Поле func
является обязательным и содержит имя функции, которая должна быть вызвана на сервере. Функция на сервере получает параметром остальной объект (поля nick
и message
)
В ответ вы получите так же объект:
{nextMessageId: 100500}
где 100500: новая длина массива сообщений на сервере после добавления вашего сообщения.
getMessages
Позволяет прочесть часть массива сообщений от отпределенного индекса и до конца. Используется для последовательной дочитки новых сообщений. Для этого надо передать в jsonPost
подобный объект:
{func: "getMessages", messageId: 0}
При значении 0 в messageId
сервер отдаст сообщения от 0 до конца, т. е. весь массив:
{
"data": [
{
"nick": "test",
"message": "test",
"timestamp": 1524225450317
},
{
"nick": "test",
"message": "test2",
"timestamp": 1524225460973
},
{
"nick": "test",
"message": "test3",
"timestamp": 1524225504849
},
{
"nick": "SirkoSobaka",
"message": "Hello!",
"timestamp": 1524226323310
},
{
"nick": "SirkoSobaka",
"message": "Hello!",
"timestamp": 1524226326628
},
],
"nextMessageId": 5
}
После чего вы итерируете по data
и выводите каждый отдельный объект как DOM-элемент с текстом, и, возможно, вложенной версткой (время в отдельном элементе и т.п.)
nextMessageId
вы запоминаете для того, что бы отправить следующий запрос начиная с него (т. е. с 5 в примере выше). Тогда сервер отдаст вам только сообщения новее последнего
запроса.
Можно глянуть тут: http://gitlab.a-level.com.ua/gitgod/FrontendLectures/src/master/chatServer/server.js
Обратите внимание на массив messages
и на функции в ассоциативном массиве RPCFuncs
. А также на
http://gitlab.a-level.com.ua/gitgod/FrontendLectures/src/master/chatServer/server.js#L43-L51
http://chat.asmer.fe.a-level.com.ua/
Но вам все равно надо переписать это на async
, await
, Promise
и DOM.
Если у вас не чрезмерно свежий хром, то это можно делать даже на локалхосте и открывать файл из браузера с диска. Сервер позволяет соединятся с собой с любого домена.