Рубрики
Без рубрики

Как обновить статус пользователя в реальном времени в JavaScript!

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

Автор оригинала: Rahat Khanna (mappmechanic).

“Эй, как жизнь?” это не фраза, нам нужно спросить кого-то в эти дни. В эти дни, зная, что кто-то должен, стал настолько легко, чтобы мы продолжали видеть обновленное статус для всех наших друзей на WhatsApp, Snapchat, Facebook и т. Д. В этом сообщении в этом блоге мы узнаем, как мы можем обновить статус пользователя в компоненте Realtime Список всех членов, которые онлайн.

Мы будем использовать Nodejs Как сервер приложений Ваниль Джс на переднем и Толкатель Для связи в реальном времени между нашим сервером и передним концом.

Мы построим приложение, которое будет похоже на ваш список друзей или обычный чат, где вы можете увидеть, кто онлайн и их последнее обновление статуса в реальном времени. В сообщении в блоге мы узнаем о Pusher Присутствие Канал и как узнать об онлайн-членах на этот канал.

Мы будем строить следующие компоненты во время этого блога:

  • Nodejs Server с использованием Frameworks Framework

    • /Регистрация API – Для того, чтобы зарегистрироваться/войти нового пользователя на наш канал и сервер, создавая их сеанс и сохраняя их информацию
    • /isloggedin API – чтобы проверить, будет ли пользователь уже войти в систему или нет в случае обновления браузера
    • /usersystem/auth API – валидация авторизации, сделанная от Pusher после регистрации в нашем приложении и подписки к присутствию или частным каналам
    • /Выход из системы API – для выхода пользователя и удалить сеанс
  • Приложение для переднего конца, используя Ванильный JavaScript

    • Форма регистрации/входа – для регистрации/входа нового пользователя, заполнив их имя пользователя и начальный статус
    • Список участников – чтобы увидеть всех, кто онлайн и их обновленный статус
    • Состояние обновления – нажать на существующий статус и обновить его на размытии элемента управления текстом состояния

Найдите здесь The The Ссылка в репозиторий GitHub для справки.

Pusher – это платформа, которая резитарует сложности реализации системы Realtime на наших собственных с использованием WebSockets или длительного опроса. Мы можем мгновенно добавить функции в реальном времени нашим существующим веб-приложениям, используя Pusher, поскольку он поддерживает широкий спектр SDKS. Интеграционные комплекты доступны для разнообразных фабричных библиотек, таких как Боси, реагировать, угловые, jQuery etc а также бэкэнд платформы/языки, такие как .Net, Java, Python, Ruby, PHP, и др. Отказ

Подписаться с топлером

Вы можете создать бесплатный аккаунт в толках здесь Отказ После того, как вы зарегистрируетесь и войдите в систему, вам будет предложено создать новое приложение, как видно на рисунке ниже. Вам придется заполнить некоторую информацию о вашем проекте, а также на передней библиотеке или языке BackeNG, с которым вы будете создавать ваше приложение.

Пользователи-пользователи-status-update-create_app-1.png

Для этого конкретного поста в блоге мы выберем Ваниль Джс для переднего конца и Nodejs для бэкэнда, как видно на картинке выше. Это просто покажет вам набор кодов образец стартера для этих выборов, но вы можете использовать любой интеграционный комплект позже с помощью этого приложения.

image.png.png

Nodejs должны быть установлены в системе как предпосылка для этого. Теперь давайте начнем строить сервер Nodejs и все необходимые API, используя Экспресс Отказ Инициализируйте новый проект узла по следующей команде

npm init

Установка зависимостей

Мы будем устанавливать необходимые зависимости, такие как Express, Express-Session, Pusher, Body-Parser, Cookie-Parser по следующей команде:

npm install express express-session body-parser cookie-parser --save

Фонд сервера

Теперь мы создадим базовый фонд для сервера узлов, а также включить сеансы в том, что используя модуль Express-Session.

var express = require('express');
var path = require('path');
var bodyParser = require('body-parser');
var expressSession = require('express-session');
var cookieParser = require('cookie-parser');

var app = express();

// must use cookieParser before expressSession
app.use(cookieParser());

app.use(expressSession({
  secret:'',
  resave: true, 
  saveUninitialized: true
}));

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'public')));

// Error Handler for 404 Pages
app.use(function(req, res, next) {
    var error404 = new Error('Route Not Found');
    error404.status = 404;
    next(error404);
});

module.exports = app;

app.listen(9000, function(){
  console.log('Example app listening on port 9000!')
});

В приведенном выше коде мы создали базовый экспресс-сервер и используя метод .use Мы включили Cookie-Parser, Body-Parser и статический файл, обслуживающий от публичный папка. Мы также включили сеансы, используя Экспресс-сессия модуль. Это позволит нам сохранять информацию о пользователе в соответствующей сеансе запроса для пользователя.

Добавление толка

У Pusher есть модуль NPM с открытым исходным кодом для Nodejs Интеграции, которые мы будем использовать. Он обеспечивает набор полезных методов для интеграции с Толкатель API, используя уникальный AppID, ключ и секрет. Сначала установим толкатель NPM Модуль с использованием следующей команды:

npm install pusher --save

Теперь мы можем использовать «требовать», чтобы получить модуль толкателя и создать новый экземпляр, проходящий объект параметров с важными ключами для инициализации нашей интеграции. Для этого поста в блоге у меня есть случайные клавиши; Вам придется получить его для вашего приложения из приборной панели толкателя.

var Pusher = require('pusher');

var pusher = new Pusher({
  appId: '30XXX64',
  key: '82XXXXXXXXXXXXXXXXXb5',
  secret: '7bXXXXXXXXXXXXXXXX9e',
  encrypted: true
});

var app = express();
...

Вам придется заменить AppID , ключ и а Секрет со значениями, специфичными для вашего собственного приложения. После этого мы напишем код для нового API, который будет использоваться для создания нового комментария.

Регистрация/Вход API

Теперь мы разработаем первый маршрут API нашего приложения, через который новый пользователь может зарегистрироваться/войти в систему и входить в систему в нашем приложении.

app.post('/register', function(req, res){
  console.log(req.body);
  if(req.body.username && req.body.status){
    var newMember = {
      username: req.body.username,
      status: req.body.status
    }
    req.session.user = newMember;
    res.json({  
      success: true,
      error: false
    });
  }else{
    res.json({  
      success: false,
      error: true,
      message: 'Incomplete information: username and status are required'
    });
  }
});

В приведенном выше коде мы вызовели вызов почтового API по маршруту /Регистрация который ожидал Имя пользователя и Статус Параметры для передачи в тело запроса. Мы будем сохранять эту информацию о пользователе на сеансе запроса.

Пользовательская система AUTH API API

Чтобы позволить любому клиенту подписаться на толкатель Частный и Присутствие Каналы, нам нужно реализовать API аутентификации, который будет подтверждать запрос пользователя, позвонив Толкатель Способ на стороне сервера. Добавьте следующий код на сервере, чтобы выполнить это условие:

app.post('/usersystem/auth', function(req, res) {
  var socketId = req.body.socket_id;
  var channel = req.body.channel_name;
  var currentMember = req.session.user;
  var presenceData = {
    user_id: currentMember.username,
    user_info: {
      status: currentMember.status,
    }
  };
  var auth = pusher.authenticate(socketId, channel, presenceData);
  res.send(auth);
});

Нам нужно предоставить конкретный маршрут в инициализации Толкатель клиент Боковая библиотека, которую мы увидим позже в этом сообщении в блоге. Клиентская библиотека Pusher автоматически позвонит этому маршруту и проходит в свойствах Channel_Name и Socket_id. Мы одновременно получим информацию о пользователе от объекта сеанса пользователя и передаем его как PreSensata для Толкатель Способ вызова.

Isloggedin и logout API

Если пользователь обновляет браузер, приложение для клиента должно обнаружить, будет ли пользователь уже зарегистрирован или нет. Мы осуществим isloggedin API маршрут для этого. Кроме того, нам нужен Выход из системы Маршрут, чтобы позволить любому пользователю выйти из приложения.

app.get('/isLoggedIn', function(req,res){
  if(req.session.user){
    res.send({ 
      authenticated: true 
    });
  }else{
    res.send({ authenticated: false });
  }
});

app.get('/logout', function(req,res){
  if(req.session.user){
    req.session.user = null;
  }
  res.redirect('/');
});

Мы будем разрабатывать приложение Front End, чтобы зарегистрировать новый пользователь с начальным статусом, см. Участников, которые являются онлайн и их статусами. Мы также будем создавать функцию для зарегистрированных пользователей, чтобы обновить своих пользователей, и все остальные пользователи увидят обновленный статус в реальном времени.

Шаг 1: Создайте папку с именем общественности и создать index.html

Мы уже написали код в нашем server.js служить статическому контенту от публичный Папка, поэтому мы напишем весь наш передний код в этой папке.

Пожалуйста, создайте новую папку публичный а также создать пустую index.html пока что.

Шаг 2: добавить код BoaterPlate на наш index.html

Мы будем добавлять какой-то базовый код Bovertlate для настройки базовой структуры для нашего веб-приложения, как заголовок, разделы, в которых можно разместить регистрационную форму и список участников.




    
        Whats Up ! Know what other's are up to in Realtime !
        
        
        
        
    
    
        

Whats Up ! Know what other's are up to in Realtime !

First Time Sign Up !

В вышеупомянутом коде котел, мы ссылались на наш основной файл JavaScript app.js и библиотека Pusher клиентская библиотека JS. У нас также есть тег сценария, где мы разместим шаблон для ряда элементов в списке участников. Кроме того, у нас есть два пустых теги DIV с IDS я и Члецы Содержать зарегистрированные имени пользователя и информацию, а также список всех других участников со своими состояниями.

Шаг3: Style.css.

Важно отметить, что мы будем отображать форму регистрации в первый раз, и кнопка «Участники» и «Выход» будут скрыты по умолчанию изначально. Пожалуйста, создайте новый файл под названием still.css И добавьте следующие CSS к нему:

body{
    margin:0;
    padding:0;
    overflow: hidden;
    font-family: Raleway;
}

header{
    background: #2b303b;
    height: 50px;
    width:100%;
    display: flex;
    color:#fff;
}


.loader,
.loader:after {
  border-radius: 50%;
  width: 10em;
  height: 10em;
}
.loader {
  margin: 60px auto;
  font-size: 10px;
  position: relative;
  text-indent: -9999em;
  border-top: 1.1em solid rgba(82,0,115, 0.2);
  border-right: 1.1em solid rgba(82,0,115, 0.2);
  border-bottom: 1.1em solid rgba(82,0,115, 0.2);
  border-left: 1.1em solid #520073;
  -webkit-transform: translateZ(0);
  -ms-transform: translateZ(0);
  transform: translateZ(0);
  -webkit-animation: load8 1.1s infinite linear;
  animation: load8 1.1s infinite linear;
}
@-webkit-keyframes load8 {
  0% {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  100% {
    -webkit-transform: rotate(360deg);
    transform: rotate(360deg);
  }
}
@keyframes load8 {
  0% {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  100% {
    -webkit-transform: rotate(360deg);
    transform: rotate(360deg);
  }
}


.subheader{
    display: flex;
    align-items: center;
    margin: 0px;
}

.whatsup-logo{
    height:60px;
    border-radius: 8px;
    flex:0 60px;
    margin-right: 15px;
}

.logout{
    flex:1;
    justify-content: flex-end;
    padding:15px;
    display: none;
}

.logout a{
    color:#fff;
    text-decoration: none;
}

#signup-form{
    display: none;
}

input, textarea{
  width:100%;
}


section{
    padding: 0px 15px;
}

.logo img{
    height: 35px;
    padding: 6px;
    margin-left: 20px;
}

#updateStatus{
    display: none;
}

.members-list{
    display: none;
    flex-direction: column;
}

.me {
  display: none;
}

Пожалуйста, попробуйте открыть URL http://localhost: 9000 В вашем браузере и приложение загрузится с основным регистром или формой входа в систему с именем пользователя и статус. Выход будет выглядеть как скриншот ниже:

Создание-пользователи-статус-регистрация-форма2-1.PNG

Шаг 4: Добавить App.js Базовый код

Теперь мы добавим наш код JavaScript, чтобы иметь базовые элементы утилиты внутри функции самопознания, чтобы создать личный объем для наших переменных приложений. Мы не хотим загрязнять глобальную область JS.

// Using IIFE for Implementing Module Pattern to keep the Local Space for the JS Variables
(function() {
    // Enable pusher logging - don't include this in production
    Pusher.logToConsole = true;

    var serverUrl = "/",
        members = [],
        pusher = new Pusher('73xxxxxxxxxxxxxxxdb', {
          authEndpoint: '/usersystem/auth',
          encrypted: true
        }),
        channel,
        userForm = document.getElementById("user-form"),
        memberTemplateStr = document.getElementById('member-template').innerHTML;

    function showEle(elementId){
      document.getElementById(elementId).style.display = 'flex';
    }

    function hideEle(elementId){
      document.getElementById(elementId).style.display = 'none';
    }

    function ajax(url, method, payload, successCallback){
      var xhr = new XMLHttpRequest();
      xhr.open(method, url, true);
      xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
      xhr.onreadystatechange = function () {
        if (xhr.readyState != 4 || xhr.status != 200) return;
        successCallback(xhr.responseText);
      };
      xhr.send(JSON.stringify(payload));
    }

    ajax(serverUrl+"isLoggedIn","GET",{},isLoginChecked);

    function isLoginChecked(response){
      var responseObj = JSON.parse(response);
      if(responseObj.authenticated){
        channel = pusher.subscribe('presence-whatsup-members');
        bindChannelEvents(channel);
      }
      updateUserViewState(responseObj.authenticated);
    }

    function updateUserViewState(isLoggedIn){
      document.getElementById("loader").style.display = "none";
      if(isLoggedIn){
        document.getElementById("logout").style.display = "flex";
        document.getElementById("signup-form").style.display = "none";
      }else{
        document.getElementById("logout").style.display = "none";
        document.getElementById("signup-form").style.display = "block";
      }
    }

    function showLoader(){
        document.getElementById("loader").style.display = "block";
        document.getElementById("logout").style.display = "none";
        document.getElementById("signup-form").style.display = "none";
    }

    // Adding a new Member Form Submit Event
    userForm.addEventListener("submit", addNewMember);


    function addNewMember(event){
      event.preventDefault();
      var newMember = {
        "username": document.getElementById('display_name').value,
        "status": document.getElementById('initial_status').value
      }
      showLoader();
      ajax(serverUrl+"register","POST",newMember, onMemberAddSuccess);
    }

    function onMemberAddSuccess(response){
        // On Success of registering a new member
        console.log("Success: " + response);
        userForm.reset();
        updateUserViewState(true);
        // Subscribing to the 'presence-members' Channel
        channel = pusher.subscribe('presence-whatsup-members');
        bindChannelEvents(channel);
    }
})();

В приведенном выше коде мы ссылались на все важные переменные, которые мы будем требовать. Мы также инициализируем библиотеку Pusher, используя Новый толкатель и передавая ключ API в качестве первого аргумента. Второй аргумент содержит необязательный объект Config, в котором мы добавим ключ AuthencePoint с маршрутом пользовательского узла API /usersystem/auth а также добавить ключ зашифрован устанавливая его значение true.

Мы создадим пару общих функций для отображения или скрытия элемента, проходящего его уникальный идентификатор. Мы также добавили общий метод имени Ajax Чтобы сделать AJAX-запросы с использованием объекта XMLHTTP в ванильном JavaScript.

При нагрузке страницы мы производим запрос AJAX, чтобы проверить, вошел ли пользователь в системе или нет. Если пользователь вошел в систему, мы будем непосредственно использовать экземпляр Pusher, чтобы подписаться на пользователь на канал присутствия с именем Присутствие-Whatsup-члены , Вы можете иметь это как уникальный чат или местоположение приложения, где вы хотите сообщить/отслеживать онлайн-члены онлайн.

Мы также написали метод выше для addnewmember Использование запроса AJAX к Регистрация Маршрут API Мы встроили в Nodejs. Мы будем передавать имя и начальный статус, введенный в форму.

У нас также есть способ обновления состояния просмотра пользователя на основе состояния в системе зарегистрированного в системе. Этот метод ничего не делает, кроме как обновляет видимость списка членов, кнопки выхода из системы и формы регистрации. Мы использовали BindChannelevents Метод, когда пользователь регистрируется, в котором мы будем реализовывать позже в сообщении в блоге.

Пожалуйста, добавьте следующие CSS в still.css файл для отображения я Элемент надлежащим образом с именем пользователя и состоянием зарегистрированного пользователя.

.me {
    border:1px solid #aeaeae;
    padding:10px;
    margin:10px;
    border-radius: 10px;
}

.me img{
    height: 40px;
    width: 40px;
}

.me .status{
    padding:5px;
    flex:1;
}

.me .status .username{
    font-size:13px;
    color: #aeaeae;
    margin-bottom:5px;
}

.me .status .text{
    font-size: 15px;
    width:100%;
    -webkit-transition: all 1s ease-in 5ms;
    -moz-transition: all 1s ease-in 5ms;
    transition: all 1s ease-in 5ms;
}

Шаг 5: Добавить код, чтобы сделать список пользователей и BindChannelevents

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

Добавьте следующий код в app.js файл:

// Binding to Pusher Events on our 'presence-whatsup-members' Channel

  function bindChannelEvents(channel){
      channel.bind('client-status-update',statusUpdated);
      var reRenderMembers = function(member){
        renderMembers(channel.members);
      }
      channel.bind('pusher:subscription_succeeded', reRenderMembers);
      channel.bind('pusher:member_added', reRenderMembers);
      channel.bind('pusher:member_removed', reRenderMembers);
    }


В вышеуказанном BindChannelevents Метод, мы используем Channel.bind Метод связывания обработчиков событий для 3 внутренних событий – Pusher: подписка_Седом , Pusher: Member_addoed , Pusher: Member_remured и 1 пользовательское событие – Client-Status-Update Отказ

Теперь мы добавим код JavaScript для рендеринга списка членов. Важно знать, что объект, который я вернулся из . Подписаться Метод имеет свойство под названием Члены Что можно использовать для знания информации о зарегистрированном пользователе, упомянутую ключом я и другие участники по ключу Члены Отказ Добавьте следующий код в app.js файл

// Render the list of members with updated data and also render the logged in user component

    function renderMembers(channelMembers){
      var members = channelMembers.members;
      var membersListNode = document.createElement('div');
      showEle('membersList');

      Object.keys(members).map(function(currentMember){
        if(currentMember !== channelMembers.me.id){
          var currentMemberHtml = memberTemplateStr;
          currentMemberHtml = currentMemberHtml.replace('{{username}}',currentMember);
          currentMemberHtml = currentMemberHtml.replace('{{status}}',members[currentMember].status);
          currentMemberHtml = currentMemberHtml.replace('{{time}}','');
          var newMemberNode = document.createElement('div');
          newMemberNode.classList.add('member');
          newMemberNode.setAttribute("id","user-"+currentMember);
          newMemberNode.innerHTML = currentMemberHtml;
          membersListNode.appendChild(newMemberNode);
        }
      });
      renderMe(channelMembers.me);
      document.getElementById("membersList").innerHTML = membersListNode.innerHTML;
    }


    function renderMe(myObj){
      document.getElementById('myusername').innerHTML = myObj.id;
      document.getElementById('mystatus').innerHTML = myObj.info.status;
    }

Мы добавили обработчик событий для нового события Add/Remove Plact/Remove для перезарядки списка участников, чтобы он остался обновлен только с онлайн-членами. Чтобы показать список участников, нам нужно добавить следующий стиль в наш файл still.css

.member{
    display: flex;
    border-bottom: 1px solid #aeaeae;
    margin-bottom: 10px;
    padding: 10px;
}

.member .user-icon{
    flex:0 40px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.member .user-icon img{
    width:50px;
    height:50px;
}

.member .user-info{
    padding:5px;
    margin-left:10px;
}

.member .user-info .name{
    font-weight: bold;
    font-size: 16px;
    padding-bottom:5px;
}

.member .user-info .status{
    font-weight: normal;
    font-size:13px;
}

.member .user-info .time{
    font-weight: normal;
    font-size:10px;
    color:#aeaeae;
}

Теперь мы напишем код, чтобы вызвать событие клиента на нашем канале, чтобы уведомить всех пользователей о изменении состояния зарегистрированного пользователя. Добавьте следующий код на ваш app.js файл

 // On Blur of editting my status update the status by sending Pusher event
    document.getElementById('mystatus').addEventListener('blur',sendStatusUpdateReq);

    function sendStatusUpdateReq(event){
      var newStatus = document.getElementById('mystatus').innerHTML;
      var username = document.getElementById('myusername').innerText;
      channel.trigger("client-status-update", {
        username: username,
        status: newStatus
      });
    }

    // New Update Event Handler
    // We will take the Comment Template, replace placeholders and append to commentsList
    
    function statusUpdated(data){
      var updatedMemberHtml = memberTemplateStr;
          updatedMemberHtml = updatedMemberHtml.replace('{{username}}',data.username);
          updatedMemberHtml = updatedMemberHtml.replace('{{status}}',data.status);
          updatedMemberHtml = updatedMemberHtml.replace('{{time}}','just now');
      document.getElementById("user-"+data.username).style.color = '#1B8D98';    
      document.getElementById("user-"+data.username).innerHTML=updatedMemberHtml;
      setTimeout(function(){
        document.getElementById("user-"+data.username).style.color = '#000';
      },500);
    }

Важно : Когда мы запускаем этот код в наших браузерах, обновите статус и размыты из элемента управления состояниями, мы получим ошибку в консоли JavaScript для библиотеки Pusher. Чтобы исправить это, перейдите к консоли в Pusher.com Сайт, перейдите к настройкам и включите отправку событий с клиентов напрямую.

Мы можем отправлять события только с клиента SDirectly для наличия или частных каналов. Ссылка на официальную документацию – https://pusher.com/docs/client_api_guide/client_events#trigger-events.

Pusher : Error : {
  "type":"WebSocketError",
  "error":{
    "type":"PusherError",
    "data":
      {
        "code":null,
        "message":"To send client events, you must enable this feature in the Settings page of your dashboard."
      }
   }
}

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

Этот компонент или код можно использовать для разработки сетевого сетевого раздела в большинстве веб-приложений в эти дни. Это важный случай использования, когда пользователь должен знать о других доступных участниках. Например: онлайн-приложение в классе может видеть других участников, и статус может соответствовать любому вопросу, который любой участник хочет спросить докладчика.

Создание-пользователи-статус-приложение-анимированные-1.гиф

Мы только что использовали Nodejs и Ваниль Джс реализовать вышеуказанные функциональные возможности. Вы можете использовать JavaScript для переднего кода с любыми популярными каркасами, такими как Rectjs или Angularjs И т.д. Бэкэнда также может быть Java или Ruby Отказ Пожалуйста, обратитесь к DUSHER DOCS для получения дополнительной информации об этом.

Этот блог пост был первоначально опубликован на Блог Pusher Отказ