В этом руководстве я покажу вам, как реализовать приложение для чата в реальном времени с Laravel 5, PostgreSQL и Pusher. Затем мы развернем это приложение в модуле вместе.
Мы будем использовать Laravel 5 для серверной службы, HTML5 и jQuery для простого интерфейсного приложения, PostgreSQL для базы данных и Pusher для связи в реальном времени между сервером и клиентами. Общая архитектура будет выглядеть так:
Сценарий
- Пользователь открывает приложение чата в браузере и предоставляет псевдоним для продолжения чата.
- Пользователь вводит текст и нажимает кнопку « Отправить» .
- Сообщение будет обработано службой, написанной с использованием Laravel 5, и оно будет сохранено в базе данных.
- Постоянное сообщение будет отправлено в Pusher для запуска нового события сообщения для передачи этого сообщения подключенным клиентам.
- Новое сообщение будет получено клиентами, а список сообщений чата будет обновлен для всех подключенных клиентов.
В этом сценарии мы рассмотрим очень полезные темы, даже если это очень простое приложение.
Подготовка среды
Настройка проекта Laravel
Давайте сначала установим Laravel, чтобы мы могли написать сервис чата для нашего приложения. Мы будем использовать Composer для простой установки Laravel и связанных пакетов. Пожалуйста, обратитесь к веб-сайту Composer, чтобы узнать больше об установке Composer. После установки Composer откройте окно командной строки и выполните следующую команду для установки Laravel 5:
composer global require "laravel/installer=~1.1"
Вы увидите вывод, подобный следующему:
Мы готовы создать проект Laravel. Запустите следующий код, чтобы сгенерировать структуру проекта для приложения чата.
laravel new RealtimeChatLaravel
Это создаст шаблонный проект Laravel, и вы увидите следующую структуру папок:
База данных
Наше приложение будет взаимодействовать с базой данных, и это будет PostgreSQL. В этом проекте мы будем использовать ElephantSQL , компанию, которая предоставляет PostgreSQL как сервис. Вы можете использовать несколько типов баз данных с Laravel, таких как SQLite, MySQL, PostgreSQL и SQL Server. Я выбрал PostgreSQL, потому что, когда мы развернем наш проект в Modulus, вы не сможете использовать внутреннюю базу данных, как указано выше. Я предпочитаю использовать базу данных, которая предоставляет ее в качестве услуги. ElephantSQL позволяет вам попробовать некоторые из полезных функций PostgreSQL с бесплатным планом.
Вы можете получить бесплатный план от ElephantSQL и использовать его для своих нужд. Когда вы закончите создание своей учетной записи и базы данных, вы будете знать информацию базы данных, такую как имя хоста , имя базы данных, имя пользователя и пароль. Пожалуйста, запишите эту информацию для использования в Laravel для конфигурации базы данных.
толкатель
Эта компания предоставляет услугу для запуска событий для общения в реальном времени. Вы можете перейти на сайт Pusher, чтобы получить его. После успешного создания учетной записи и приложения вы сможете получить некоторые учетные данные, такие как App ID , App Secret и App Key . Мы поговорим об их использовании в следующих разделах.
Nginx
Чтобы запустить приложение PHP в модуле, вам необходимо настроить веб-сервер для обслуживания вашего приложения. Мы будем использовать следующую конфигурацию Nginx:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
server {
listen 8080;
server_name modulus_app_url;
root /mnt/app/public;
index index.html index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/mnt/home/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_index index.php;
include fastcgi_params;
}
}
|
Мы завершили необходимые настройки среды, чтобы продолжить разработку. Давайте перейдем к части дизайна.
Дизайн проекта с нуля
модель
Если вы когда-либо использовали каркас ORM раньше, вы будете очень хорошо знакомы с этой темой. В проектах Laravel модели доменов по умолчанию размещаются в папке app/
. В этом приложении мы будем выполнять CRUD-операции с сообщениями, а это значит, что нам нужно создать модель Message
.
Если вы хотите создать модель, просто создайте класс, который расширяет класс Model
, который является абстрактным классом в базовом пакете Laravel Illuminate\Database\Eloquent
. Создайте файл с именем Message.php
в папке app/
и поместите в него следующее содержимое:
01
02
03
04
05
06
07
08
09
10
11
|
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Message extends Model
{
protected $table = ‘messages’;
}
|
Эта модель позволит нам легко выполнить несколько операций, связанных с базой данных. Например, когда вы выполняете следующий запрос:
1
2
3
4
5
|
<?php
…..
Message::all();
…
?>
|
это даст вам все сообщения из базы данных. Тем не менее, как он определяет имя таблицы, которую он выберет в результате? Он использует значение $table
в классе модели. Когда вы создаете новое сообщение, оно напрямую сохраняет вашу модель messages
таблице messages
. Мы подробно рассмотрим модели в разделе «Контроллер».
контроллер
Контроллер — это место, где определяется поведение вашего приложения. Мы будем выполнять некоторые операции с сообщениями, если в нашем приложении есть ChatController
. У нас будет четыре конечных точки для нашего приложения:
-
GET /login
: для отображения страницы входа -
GET /chat
: для отображения страницы чата -
GET /messages
: для отображения последних пяти сообщений, отображаемых на странице чата, когда пользователь впервые открывает ее -
POST /messages
: для сохранения нового сообщения
Чтобы создать контроллер, просто создайте класс в App\Http\Controllers
и заставьте этот класс расширять специфичный для Laravel класс Controller
который существует в App\Http\Controllers
. Когда вы запрашиваете конечную точку /login
или /chat
, они отображают свои собственные шаблоны в resources/views
. Вы можете сделать это, используя следующие действия.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
class ChatController extends Controller
{
public function getLogin()
{
return view(«login»);
}
public function getChat()
{
return view(«chat»);
}
public function saveMessage()
{
if(Request::ajax()) {
$data = Input::all();
$message = new Message;
$message->author = $data[«author»];
$message->message = $data[«message»];
$message->save();
Pusher::trigger(‘chat’, ‘message’, [‘message’ => $message]);
}
}
public function listMessages(Message $message) {
return response()->json($message->orderBy(«created_at», «DESC»)->take(5)->get());
}
}
|
Первое и второе действия будут отображать определенные страницы. Третье действие — сохранение сообщений. В этом действии проверяется первый тип запроса. Если это AJAX-запрос, он получает все тело запроса в виде ассоциативного массива. Этот массив используется для заполнения вновь созданной модели сообщения.
Затем метод save()
напрямую выполняется в модели для сохранения базы данных. Каждый раз, когда новое сообщение сохраняется в базе данных, то же самое сообщение будет отправлено в Pusher, вызвав событие message
. Когда вы инициируете событие, все подключенные клиенты будут уведомлены. Чтобы использовать класс Pusher
в ваших проектах Laravel, вы можете сделать следующее:
-
composer require vinkla/pusher
связанные с Pusher пакеты черезcomposer require vinkla/pusher
. - Добавьте пакет Pusher, которым является
Vinkla\Pusher\PusherServiceProvider::class
, вconfig/app.php
. - Используйте классы Pusher в своих контроллерах, например,
Vinkla\Pusher\Facades\Pusher;
выше класса контроллера.
У вас все в порядке с пакетами, но как насчет конфигурации Pusher? Вам необходимо опубликовать поставщиков в своих проектах с помощью следующей команды:
1
|
php artisan vendor:publish
|
Эта команда создаст файл config/pusher.php
, и вам необходимо предоставить необходимые учетные данные, которые вы можете найти на панели инструментов Pusher. Файл конфигурации будет выглядеть так:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
‘connections’ => [
‘main’ => [
‘auth_key’ => ‘auth_key’,
‘secret’ => ‘secret’,
‘app_id’ => ‘app_id’,
‘options’ => [],
‘host’ => null,
‘port’ => null,
‘timeout’ => null,
],
‘alternative’ => [
‘auth_key’ => ‘your-auth-key’,
‘secret’ => ‘your-secret’,
‘app_id’ => ‘your-app-id’,
‘options’ => [],
‘host’ => null,
‘port’ => null,
‘timeout’ => null,
],
]
|
Четвертая конечная точка предназначена для отображения последних пяти сообщений, отображаемых на странице чата для вновь присоединившихся пользователей. Магический код:
1
2
3
|
public function listMessages(Message $message) {
return response()->json($message->orderBy(«created_at», «DESC»)->take(5)->get());
}
|
В этом коде модель Message
внедряется в действие или выполняет операции, связанные с базой данных, с помощью $message
. Сначала упорядочите сообщения с помощью created_at
в порядке убывания, а затем возьмите последние пять. Результат возвращается в формате JSON с помощью response()->json(...)
.
Мы упоминали о контроллерах и действиях, но как эти действия выполняются, когда пользователь переходит на определенный URL? Вы можете добавить свои конфигурации маршрутов в файл app/Http/routes.php
. Вы можете увидеть пример ниже:
1
2
3
4
5
6
7
8
9
|
<?php
Route::get(‘/chat’, ‘\App\Http\Controllers\Chat\ChatController@getChat’);
Route::get(‘/login’, ‘\App\Http\Controllers\Chat\ChatController@getLogin’);
Route::get(‘/messages’, ‘\App\Http\Controllers\Chat\ChatController@listMessages’);
Route::post(‘/messages’, ‘\App\Http\Controllers\Chat\ChatController@saveMessage’);
|
В этом случае URI запроса и метод запроса отображаются на имя контроллера и имя действия.
Это все с контроллерами. Давайте перейдем к части View.
Посмотреть
В этом разделе мы использовали шаблонный движок Blade, предоставленный Laravel. На самом деле, в наших проектах нет движка шаблонов, но если вы хотите отправить значения из контроллера в представления, вы можете напрямую использовать этот проект.
У нас есть две страницы просмотра: login.blade.php
и chat.blade.php
. Как видите, в именах файлов вида есть ключевое слово blade, которое указывает, что оно будет использоваться для механизма шаблонов Blade.
Первый просто для входа в систему, так что давайте поговорим о странице chat
. В этом файле представления есть некоторые сторонние библиотеки JavaScript, обслуживаемые из CDN, такие как jQuery
, jQuery Cookie
, Bootstrap
и Pusher
. У нас есть форма чата для отправки сообщений, и Laravel добавляет мета-описание на страницу:
1
|
<meta name=»_token» value=»token»>
|
Однако мы отправляем сообщение чата через AJAX, и в заголовках запросов AJAX нет токенов. Мы предлагаем решение, используя следующий фрагмент кода:
1
2
3
|
$.ajaxSetup({
headers: { ‘X-CSRF-Token’ : $(‘meta[name=_token]’).attr(‘content’) }
});
|
Всякий раз, когда вы отправляете запрос AJAX, этот токен будет помещен в заголовок.
Для прослушивания канала сообщений в режиме реального времени мы использовали следующее:
1
2
3
4
5
6
7
8
|
var pusher = new Pusher(‘app_id’);
var channel = pusher.subscribe(‘chat’);
channel.bind(‘message’, function(data) {
var message = data.message;
$(«.media-list li»).first().remove();
$(«.media-list»).append(‘<li class=»media»><div class=»media-body»><div class=»media»><div class=»media-body»>’
+ message.message + ‘<br/><small class=»text-muted»>’ + message.author + ‘ |
});
|
Прежде всего, у нас есть объект Pusher
с конструктором app_id
. И тогда клиент подписывается на канал. Всякий раз, когда приходит новое событие с message
имени, внутри функции bind()
выполняется функция обратного вызова. Область списка сообщений будет обновлена новыми сообщениями.
Наконец, всякий раз, когда новый пользователь открывает страницу чата, последние пять сообщений будут отображаться в области списка сообщений с помощью следующего кода:
1
2
3
|
$.get(«/messages», function (messages) {
refreshMessages(messages)
});
|
Вы можете обратиться к исходному коду, чтобы проанализировать полный исходный код страниц просмотра.
развертывание
Мы будем использовать модуль для размещения нашего приложения.
Modulus — это один из лучших PaaS для развертывания, масштабирования и мониторинга вашего приложения на выбранном вами языке. Прежде чем приступить к развертыванию, перейдите в модуль и создайте учетную запись.
Предпосылки
Развертывание очень легко в модуле. Единственное, что вам нужно сделать, это установить модуль Node.js и запустить команду. Также вы можете заархивировать свой проект и загрузить его в модуль. Мы предпочтем первый вариант в этом уроке.
Я предполагаю, что вы уже установили Node.js и npm на свой компьютер. Просто откройте инструмент командной строки и выполните npm install -g modulus
. После успешной установки войдите в свою учетную запись Modulus с помощью Modulus CLI: modulus login
. Если вы хотите войти в систему с помощью GitHub, вы можете использовать modulus login --github
.
После того, как вы вошли в систему, создайте проект с помощью этой команды: modulus project create "RealtimeChatLaravel"
. Вы создали приложение на стороне модуля.
Последнее, что вам нужно сделать, это создать папку в корневой папке вашего проекта с именем sites-enabled
и поместить конфигурацию Nginx, о которой мы упоминали в разделе Nginx выше, в эту папку, sites-enabled
.
Давайте развернем ваш проект в модуле под этим приложением. Выполните modulus deploy
чтобы начать развертывание, и все готово! Эта команда загрузит файлы вашего проекта в Modulus, а также настроит веб-сервер, используя конфигурацию Nginx, которую вы поместили в папку sites-enabled
.
После успешного развертывания вы получите сообщение RealtimeChatLaravel running at http://realtimechatlaravel-51055.onmodulus.net/cha
. Перейдите по этому URL, чтобы увидеть работающую демонстрацию.
Модуль CLI имеет очень полезные команды для использования в разделе развертывания и выполнения. Например, вы можете привязывать журналы вашего работающего проекта к хвосту журналов проекта modulus project logs tail
, устанавливать переменную среды с modulus env set <key> <value>
и т. Д. Полный список команд можно просмотреть с modulus help
по modulus help
.
Вывод
Если вы создаете веб-приложение на PHP, вам неизбежно придется иметь дело с веб-серверами, такими как Apache из NGINX; однако, если вы используете модуль, вы можете просто сосредоточиться на своем проекте PHP. Модуль позволяет вам поместить конфигурацию вашего веб-сервера в ваш проект так, чтобы это оказало влияние при развертывании вашего кода.
В этом уроке мы сосредоточились на приложении чата в реальном времени и увидели, что другие аспекты приложения были очень просты в обращении благодаря Modulus.