В декабре прошлого года, была представлена 5 версия, всеми любимого фреймворка Ruby on Rails. Главной особенностью новой версии стал Action Cable, который позволяет легко интегрировать WebSockets с остальной частью вашего Rails приложения.
Action Cable
На днях появилась задача, считать количество онлайн пользователей на сайте. Для этих целей я решил использовать Action Cable, тем более готовый пример уже был в документации.
Реализовав задачу и отправив все изменения на сервер, я столкнулся с проблемой подключения к WebSocket серверу через браузер Safari.
Phusion Passenger
В качестве сервера приложений я использую Phusion Passenger. По умолчанию каждый процесс Passenger может одновременно обрабатывать только 1 запрос. Для работы WebSockets этого будет недостаточно.
Начиная с версии 5.0.22, Passenger имеет опцию passenger_force_max_concurrent_requests_per_process
, которая позволяет указазать, какое количество запросов может обработать каждый процесс одновременно. Если в качестве параметра передать 0
, то количество запросов будет неограничено.
Приступаем к настройке. Первым делом обновляем Passenger. На данный момент, самая последняя версия - 5.0.25, в ней улучшена интеграция с Rails 5 и Action Cable.
Рассмотрим ситуацию, когда Action Cable сервер работает внутри основного приложения:
# config/routes.rb
Example::Application.routes.draw do
mount ActionCable.server => '/cable'
end
Открываем настройки виртуального хоста для вашего проекта из директории /etc/nginx/sites-available
и добавляем следующие строчки внутрь блока server
:
server {
...
location /cable {
passenger_app_group_name YOUR_APP_NAME_action_cable;
passenger_force_max_concurrent_requests_per_process 0;
}
}
Если Action Cable сервер запущен в отдельном процессе, то виртуальный хост будет выглядить следующим образом:
server {
listen YOUR_ACTION_CABLE_PORT_NUMBER;
server_name YOUR_ACTION_CABLE_HOST_NAME;
root /path-to-your-app/public;
passenger_enabled on;
passenger_app_group YOUR_APP_NAME_action_cable;
passenger_app_type rack;
passenger_startup_file config/cable.ru;
passenger_force_max_concurrent_requests_per_process 0;
}
Чтобы изменений вступили в силу, перезагружаем сервер:
$ sudo service nginx restart
И вуаля, все работает.