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

В этом руководстве я покажу вам, как создать общедоступное приложение для анонимного чата на JavaScript (используя NodeJS и Express на сервере и VanillaJS на клиенте) и Pusher. Pusher позволяет нам создавать масштабируемые и надежные приложения в реальном времени. Поскольку нам нужна доставка сообщений чата в реальном времени, это ключевой компонент приложения чата. На изображении ниже показано, что мы будем строить:

Начиная

Давайте начнем с регистрации бесплатной учетной записи Pusher (или входа в систему, если она у вас уже есть). После входа в систему создайте новое приложение Pusher на панели управления и запишите свой идентификатор приложения, ключ и секрет, которые уникальны для приложения.

Чтобы создать новое приложение Pusher, нажмите Your apps боковое меню, а затем нажмите кнопку Create a new app под ящиком. Это вызывает мастер установки.

  1. Введите название приложения. В данном случае я назову это «чат».
  2. Выберите кластер.
  3. Выберите вариант «Создать приложение для нескольких сред», если вы хотите иметь разные экземпляры для разработки, подготовки и производства.
  4. Выберите Vanilla JS в качестве внешнего интерфейса и NodeJS в качестве внутреннего интерфейса.
  5. Завершите процесс, нажав кнопку Create my app, чтобы настроить экземпляр приложения.

Запрограммируйте сервер

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

Нам нужен package.json файл, и я добавлю его, выполнив команду ниже. Я буду использовать настройки по умолчанию, нажимая Enter для каждого запроса.

$ npm init

Добавив package.json файл, я установлю пакеты npm Express, body-parser и Pusher. Выполните следующую команду:

$ npm install –save pusher express body-parser

После установки этих пакетов давайте добавим новый файл с именем server.js со следующим содержанием:

var express = require('express');
var bodyParser = require('body-parser');
var Pusher = require('pusher');
var app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
var pusher = new Pusher({ appId: "APP_ID", key: "APP_KEY", secret:  "APP_SECRET", cluster: "APP_CLUSTER" });
app.post('/message', function(req, res) {
  var message = req.body.message;
  pusher.trigger( 'public-chat', 'message-added', { message });
  res.sendStatus(200);
});
app.get('/',function(req,res){      
     res.sendFile('/public/index.html', {root: __dirname });
});
app.use(express.static(__dirname + '/public'));
var port = process.env.PORT || 5000;
app.listen(port, function () {
  console.log(`app listening on port ${port}!`)
});

С помощью приведенного выше кода мы определили конечную точку /message, которая будет использоваться одним клиентом для отправки сообщения другому через Pusher. Остальные маршруты используются для обслуживания статических файлов, которые мы добавим позже.

Замените строки заполнителя App ID, Secret и Key значениями из панели управления Pusher. Добавьте этот оператор "start": "node server.js" в свойство скрипта нашего package.json файла. Это позволит нам запустить сервер при выполнении npm start.

Создание интерфейса

Переходя к интерфейсу, давайте добавим новую папку под названием public. Эта папка будет содержать нашу страницу и файлы JavaScript. Добавьте новый файл с именем style.css с приведенным ниже содержимым, в котором будет содержаться определение нашего стиля для страницы.

@import url("http://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css");
.chat
{
    list-style: none;
    margin: 0;
    padding: 0;
}
.chat li
{
    margin-bottom: 10px;
    padding-bottom: 5px;
    border-bottom: 1px dotted #B3A9A9;
}
.chat li.left .chat-body
{
    margin-left: 60px;
}
.chat li.right .chat-body
{
    margin-right: 60px;
}

.chat li .chat-body p
{
    margin: 0;
    color: #777777;
}
.panel .slidedown .glyphicon, .chat .glyphicon
{
    margin-right: 5px;
}
.body-panel
{
    overflow-y: scroll;
    height: 250px;
}
::-webkit-scrollbar-track
{
    -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
    background-color: #F5F5F5;
}
::-webkit-scrollbar
{
    width: 12px;
    background-color: #F5F5F5;
}
::-webkit-scrollbar-thumb
{
    -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3);
    background-color: #555;
}

Добавьте еще один файл с именем index.html с разметкой ниже.

<!DOCTYPE html>
<html>
<head>
    <!-- Latest compiled and minified CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    <!-- Optional theme -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
    <script
        src="https://code.jquery.com/jquery-2.2.4.min.js"
        integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44="
        crossorigin="anonymous"></script>
    <!-- Latest compiled and minified JavaScript -->
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
    <link rel="stylesheet" href="style.css">
    <script src="https://js.pusher.com/4.0/pusher.min.js"></script>
    <script src="index.js"></script>
</head>
<body>
    <div class="container">
    <div class="row form-group">
        <div class="col-xs-12 col-md-offset-2 col-md-8 col-lg-8 col-lg-offset-2">
            <div class="panel panel-primary">
                <div class="panel-heading">
                    <span class="glyphicon glyphicon-comment"></span> Anonymous Chat
                    <div class="btn-group pull-right">
                        <button type="button" class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown">
                            <span class="glyphicon glyphicon-chevron-down"></span>
                        </button>
                        <ul class="dropdown-menu slidedown">
                            <li><a href="http://www.jquery2dotnet.com"><span class="glyphicon glyphicon-refresh">
                            </span>Refresh</a></li>
                            <li><a href="http://www.jquery2dotnet.com"><span class="glyphicon glyphicon-ok-sign">
                            </span>Available</a></li>
                            <li><a href="http://www.jquery2dotnet.com"><span class="glyphicon glyphicon-remove">
                            </span>Busy</a></li>
                            <li><a href="http://www.jquery2dotnet.com"><span class="glyphicon glyphicon-time"></span>
                                Away</a></li>
                            <li class="divider"></li>
                            <li><a href="http://www.jquery2dotnet.com"><span class="glyphicon glyphicon-off"></span>
                                Sign Out</a></li>
                        </ul>
                    </div>
                </div>
                <div class="panel-body body-panel">
                    <ul class="chat">
                    </ul>
                </div>
                <div class="panel-footer clearfix">
                    <textarea id="message" class="form-control" rows="3"></textarea>
                    <span class="col-lg-6 col-lg-offset-3 col-md-6 col-md-offset-3 col-xs-12" style="margin-top: 10px">
                        <button class="btn btn-warning btn-lg btn-block" id="btn-chat">Send</button>
                    </span>
                </div>
            </div>
        </div>
    </div>
</div>
<script id="new-message-other" type="text/template">
    <li class="left clearfix">
        <span class="chat-img pull-left">
            <img src="http://placehold.it/50/55C1E7/fff&text=U" alt="User Avatar" class="img-circle" />
        </span>
        <div class="chat-body clearfix">
            <p>
                {{body}}
            </p>
        </div>
    </li>
</script>
<script id="new-message" type="text/template">
    <li id="{{id}}" class="right clearfix">
        <div class="chat-body clearfix">
            <p>
                {{body}}
            </p>
        </div>
    </li>
</script>
</body>
</html>

Я использую шаблон от bootsnipp, который был немного изменен, чтобы отображать только имя и сообщение.

Добавьте новый файл index.js с приведенным ниже содержанием. Не забудьте добавить информацию о приложении Pusher:

$(document).ready(function(){    
    var pusher = new Pusher('APP_KEY', {
        cluster: 'APP_CLUSTER',
        encrypted: false
    });
    let channel = pusher.subscribe('public-chat');
    channel.bind('message-added', onMessageAdded);
    $('#btn-chat').click(function(){
        const message = $("#message").val();
        $("#message").val("");
        //send message
        $.post( "http://localhost:5000/message", { message } );
    });
    function onMessageAdded(data) {
        let template = $("#new-message").html();
        template = template.replace("{{body}}", data.message);
        $(".chat").append(template);
    }
});

С помощью кода в этом файле мы получаем сообщение для отправки, а затем вызываем сервер с сообщением. После этого мы подключаемся к Pusher, создавая новый объект Pusher с ключом приложения и кластером, который вы установили ранее.

Мы подписываемся на канал и событие под названием message-added. Канал является общедоступным, поэтому его можно называть как угодно. Я решил добавить к своему префиксу public-, но это всего лишь мое личное соглашение об именах, поскольку для общедоступных каналов нет правил. Разница между public каналом и private или presence каналом заключается в том, что общедоступный канал не требует аутентификации клиента и может быть подписан любым, кто знает имя канала. Подробнее о каналах Pusher можно прочитать здесь.

Мы привязываемся к событию нажатия кнопки чата на странице, получаем сообщение из текстового поля на странице, а затем отправляем его на сервер с именем пользователя. Имея все необходимые настройки, мы можем запустить приложение, запустив npm start. Вот вам пример того, как это работает на моем компьютере.

Заворачивать

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

Изначально это было опубликовано на Pusher