Building a Live Online Chat Room Based on Laravel + Swoole + Vue (P5): Homestead Development Environment Initialization
Integrating the Swoole environment in Homestead, of course, it is not necessary to manually install the Swoole extension after rebuilding Homestead, or to manually configure the Nginx reverse proxy based on the Swoole HTTP server driver every time you create a new site. This is too laborious, we It is entirely possible to automate these operations through configuration based on the extension mechanism provided by Homestead. Next, the Academy takes the Mac environment + Homestead 8.1.0 version as an example to demonstrate how to integrate Laravel + Swoole development environment in Homestead.
To use Swoole, you must first install PHP extensions corresponding to the global share of Homestead, for example, into the Homestead
project root directory, open the after.sh
file, add the following command to install extensions enabled Swoole the end of the file:
# Install Swoole Extension
sudo pecl install swoole
sudo echo "extension=swoole.so" > /tmp/swoole.ini
sudo cp /tmp/swoole.ini /etc/php/7.3/mods-available/swoole.ini # Write directly without permission error, so here is done through the tmp directory
sudo ln -fs /etc/php/7.3/mods-available/swoole.ini /etc/php/7.3/cli/conf.d/20-swoole.ini
Note: Homestead uses the default PHP version of 7.3, so the Swoole extension I installed applies to 7.3 by default. If your Homestead defaults to another version of PHP, you need to adjust the corresponding PHP version directory to enable the extension.
after.sh
The script will run after the Homestead refactoring (provision
), so every time you refactor the Homestead development environment, the Swoole extension will be reinstalled, so that we don’t need to log in to the Homestead virtual machine and install it manually.
Next, we run Homestead
the project directory vagrant reload --provision
restart Homestead, then by homestead ssh
log on to the virtual machine, run php -m
to see expansion is enabled, see swoole
in the list, said the installation was successful:
At this point, the Swoole extension has been successfully installed, indicating that we can use the various APIs provided by the Swoole extension package in the Homestead virtual machine.
However, we know, Homestead also has a very powerful feature that can be configured Homestead.yaml
to achieve the configuration file directory mapping host and the virtual machines, as well as the corresponding Nginx virtual hosts and automatically create and configure the database, we can extend the functionality to support Swoole type sites, of course you can, next, the academy will show you how to achieve it.
Before that, let’s look briefly at startup Homestead virtual machine at the entrance of the file vagrantfile
, the configuration file is loaded Homestead and Homestead master file:
...
homesteadYamlPath = confDir + "/Homestead.yaml"
homesteadJsonPath = confDir + "/Homestead.json"
afterScriptPath = confDir + "/after.sh"
customizationScriptPath = confDir + "/user-customizations.sh"
aliasesPath = confDir + "/aliases"
require File.expand_path(File.dirname(__FILE__) + '/scripts/homestead.rb')
...
And then reads the configuration file by the Homestead.configure
analytical method and initialize these configurations:
...
if File.exist? homesteadYamlPath then
settings = YAML::load(File.read(homesteadYamlPath))
elsif File.exist? homesteadJsonPath then
settings = JSON::parse(File.read(homesteadJsonPath))
else
abort "Homestead settings file not found in #{confDir}"
end
Homestead.configure(config, settings)
...
Homestead.configure
The method defined in above-incorporated scripts/homestead.rb
documents, Homestead.yaml
in all configurations are here parsed and mapped onto the corresponding Vagrant configuration, a virtual machine implementing a custom configuration, since Vagrant based Ruby implementation, the code here are prepared by Ruby.
Homestead natively supports the following types of sites:
Does not contain Swoole, so we need to configure Homestead support swoole type sites, sites of different types of databases and directories mapping configuration is the same, except that Nginx virtual host configuration, so we focus on sitesparsing the configuration items. In Homestead.configure
find the following line method:
# Install All The Configured Nginx Sites
if settings.include? 'sites'
Nginx site configuration initialization start from here, Homestead will cycle through all the sites
configuration starts to initialize each site:
settings['sites'].each do |site|
The other sharing processes are the same, mainly to see how different types of sites handle them:
# Convert the site & any options to an array of arguments passed to the
# specific site type script (defaults to laravel)
s.path = script_dir + "/site-types/#{type}.sh"
s.args = [
site['map'], # $1
site['to'], # $2
site['port'] ||= http_port, # $3
site['ssl'] ||= https_port, # $4
site['php'] ||= '7.3', # $5
params ||= '', # $6
site['xhgui'] ||= '', # $7
site['exec'] ||= 'false', # $8
headers ||= '', # $9
rewrites ||= '' # $10
]
Here’s #{type}
corresponding precisely Homestead.yaml
the sites
type of site configuration items in the configuration type, all supported site type configuration scripts are located in scripts/site-types
the directory:
Homestead will be Homestead.yaml
the site configuration items in the configuration file is transferred to read different types of sites in the script file, creating and initializing Nginx virtual host file, and each configuration item corresponds to the parameters of a number to refer to in the script file, with this understanding, you should know how to customize your new site type in Homestead.
We follow suit, and in scripts/site-types
the new directory a swoole.sh
file, and write the script reads as follows:
#!/usr/bin/env bash
declare -A params=$6 # Create an associative array
declare -A headers=${9} # Create an associative array
declare -A rewrites=${10} # Create an associative array
paramsTXT=""
if [ -n "$6" ]; then
for element in "${!params[@]}"
do
paramsTXT="${paramsTXT}
fastcgi_param ${element} ${params[$element]};"
done
fi
headersTXT=""
if [ -n "${9}" ]; then
for element in "${!headers[@]}"
do
headersTXT="${headersTXT}
add_header ${element} ${headers[$element]};"
done
fi
rewritesTXT=""
if [ -n "${10}" ]; then
for element in "${!rewrites[@]}"
do
rewritesTXT="${rewritesTXT}
location ~ ${element} { if (!-f \$request_filename) { return 301 ${rewrites[$element]}; } }"
done
fi
if [ "$7" = "true" ]
then configureXhgui="
location /xhgui {
try_files \$uri \$uri/ /xhgui/index.php?\$args;
}
"
else configureXhgui=""
fi
# 设置 WebSocket 服务器名称
websocketServer=`echo "${1}" | sed "s/^\(.*\)\.test$/\1/g"`
block="map \$http_upgrade \$connection_upgrade {
default upgrade;
'' close;
}
upstream $websocketServer {
# Connect IP:Port
server 127.0.0.1:5200 weight=5 max_fails=3 fail_timeout=30s;
keepalive 16;
}
server {
listen ${3:-80};
listen ${4:-443} ssl http2;
server_name $1;
root \"$2\";
index index.html index.htm index.php;
charset utf-8;
$rewritesTXT
location / {
try_files \$uri @$websocketServer;
$headersTXT
}
$configureXhgui
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
access_log off;
error_log /var/log/nginx/$1-error.log error;
sendfile off;
client_max_body_size 100m;
location ~ \.php$ {
return 404;
}
# Handle WebSocket communication
location ^~ /ws/ {
# proxy_connect_timeout 60s;
# proxy_send_timeout 60s;
# proxy_read_timeout: Nginx will close the connection if the proxied server does not send data to Nginx in 60 seconds; At the same time, this close behavior is also affected by heartbeat setting of Swoole.
# proxy_read_timeout 60s;
proxy_http_version 1.1;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Real-PORT \$remote_port;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header Host \$http_host;
proxy_set_header Scheme \$scheme;
proxy_set_header Server-Protocol \$server_protocol;
proxy_set_header Server-Name \$server_name;
proxy_set_header Server-Addr \$server_addr;
proxy_set_header Server-Port \$server_port;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection \$connection_upgrade;
proxy_pass http://$websocketServer;
}
location @$websocketServer {
# proxy_connect_timeout 60s;
# proxy_send_timeout 60s;
# proxy_read_timeout 60s;
proxy_http_version 1.1;
proxy_set_header Connection \"\";
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Real-PORT \$remote_port;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header Host \$http_host;
proxy_set_header Scheme \$scheme;
proxy_set_header Server-Protocol \$server_protocol;
proxy_set_header Server-Name \$server_name;
proxy_set_header Server-Addr \$server_addr;
proxy_set_header Server-Port \$server_port;
proxy_pass http://$websocketServer;
}
location ~ /\.ht {
deny all;
}
ssl_certificate /etc/nginx/ssl/$1.crt;
ssl_certificate_key /etc/nginx/ssl/$1.key;
}
"
echo "$block" > "/etc/nginx/sites-available/$1"
ln -fs "/etc/nginx/sites-available/$1" "/etc/nginx/sites-enabled/$1"
The main logic here is to create the Nginx virtual host configuration of the Swoole type site. In order to facilitate expansion, we will set the reverse proxy server name by resolving the domain name of the site to set:
# Set Websocket server name
websocketServer=`echo "${1}" | sed "s/^\(.*\)\.test$/\1/g"`
Of course, there are some hard-coded here. For example, the domain name suffix is only supported *.test
, and the reverse proxy server IP and port number are also written:
upstream $websocketServer {
# Connect IP:Port
server 127.0.0.1:5200 weight=5 max_fails=3 fail_timeout=30s;
keepalive 16;
}
This is generally sufficient for coping with local development. If you want to make it more scalable, you can refer to the above site configuration analysis and initialization process to introduce new parameters to configure these options.
Next, we can open Homestead.yaml
the configuration file, configuration swoole
type of site:
folders:
... // Other directory mapping
- map: ~/Docker/wwwroot/webchat
to: /home/vagrant/webchat
sites:
... // other site mapping
- map: webchat.test
to: /home/vagrant/webchat/public
- map: webchats.test
to: /home/vagrant/webchat/public
type: swoole
databases:
... // other databases
- webchat
Note that here we have created both Nginx virtual host configuration based on PHP-FPM and Swoole as PHP reverse proxy server.
In the host /etc/hosts
to add a virtual domain name webchat.test
and webchats.test
:
192.168.10.10 webchat.test
192.168.10.10 webchats.test
At this point, we have completed all Swoole development environment configurations based on the Homestead virtual machine.
Next, we can vagrant reload --provision
let Swoole type of site configuration to take effect restart the virtual machine, and then modify the webchat
project’s environmental profile .env
is as follows:
APP_URL=http://webchats.test
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=webchat
DB_USERNAME=homestead
DB_PASSWORD=secret
LARAVELS_LISTEN_IP=127.0.0.1
LARAVELS_LISTEN_PORT=5200
Log on to the virtual machine, in the webchat
run directory following command to start Swoole HTTP server:
Run functional test scripts to access Home http://webchats.test
Success:
In this way, we completed the integration of the Swoole-driven Laravel + Vue chat room project into the Homestead development environment for development testing.
#laravel #swoole #vue