Building a Live Online Chat Room Based on Laravel + Swoole + Vue (P5)

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.

Install Swoole Extension

Installation script

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.

Check if the installation was successful

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:

Homestead

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.

Automatically configure Swoole type sites

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.

Homestead Site Initialization Process

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:

  • laravel (default)
  • apache
  • apigility
  • expressive
  • proxy
  • SilverStripe
  • statamic
  • Symfony2
  • symfony4
  • zf

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

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.

Create Swoole Site Script

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.

Configure Swoole Site

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.

Start Laravel + Swoole Chat Room Project

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:

This is image title

Run functional test scripts to access Home http://webchats.test Success:

This is image title

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

Building a Live Online Chat Room Based on Laravel + Swoole + Vue (P5)
10.50 GEEK