Laravel6 uses Workerman’s Gateway-worker for long-term connection communication

1. Install gateway-worker

gateway-worker which has been introduced workerman/workerman.

composer require worker/gateway-worker
composer require worker/gatewayclient

2. Create Workerman startup file

Create an artisan command line tool to start the Socket server, and create a command line file in the app/Console/Commands directory.

php artisan make:command GatewayWorkerServer

use GatewayWorker\BusinessWorker;
use GatewayWorker\Gateway;
use GatewayWorker\Register;
use Workerman\Worker;

class GatewayWorkerServer extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = ‘workman {action} {–d}’;

/**
* The console command description.
*
* @var string
*/
protected $description = ‘Start a Workerman server.’;

/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}

/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
//
global $argv;
$action = $this->argument(‘action’);

$argv[0] = ‘artisan workman’;
$argv[1] = $action;
$argv[2] = $this->option(‘d’) ? ‘-d’ : ”; //Must be a -, the command above defines two –, two are used for background startup indivual–

$this->start();
}

//Three services can be started under Linux and split into three services under Windows.
private function start()
{
$this->startGateWay();
$this->startBusinessWorker();
$this->startRegister();
Worker::runAll();
}

private function startBusinessWorker()
{
$worker = new BusinessWorker();
$worker->name = ‘BusinessWorker’;
$worker->count = 1;
$worker->registerAddress = ‘127.0.0.1:1236’;
$worker->eventHandler = \App\GatewayWorker\Events::class;
}

private function startGateWay()
{
$gateway = new Gateway(“websocket://0.0.0.0:2346”);
$gateway->name = ‘Gateway’;
$gateway->count = 1;
$gateway->lanIp = ‘127.0.0.1’;
$gateway->startPort = 2300;
$gateway->pingInterval = 30;
$gateway->pingNotResponseLimit = 0;
$gateway->pingData = ‘{“type”:”ping”}’;
$gateway->registerAddress = ‘127.0.0.1:1236’;
}

private function startRegister()
{
new Register(‘text://0.0.0.0:1236’);
}

//php artisan workman start –d After that, open the browser F12 and copy the content to the console and return
/* ws = new WebSocket(“ws://*.*.*.*:2346”);
ws.onopen = function() {
ws . send(‘{“name”:”one”,”user_id”:”111″}’);
ws . send(‘{“name”:”two”,”user_id”:”222″}’);
};
ws.onmessage = function(e) {
console.log(“Message received from the server:” + e.data);
};
ws.onclose = function(e) {
console.log(“Service has been disconnected” );
};*/

}

Related documents Usage of Gateway class-gateway-worker manual

3. Create event listening file

Create an app/GatewayWorker/Events.php file to listen and process various events of workman.

/**
* Created by PhpStorm.
*User:ls
* Date: 2020/3/25
* Time: 16:09
*/
namespace App\GatewayWorker;

use GatewayWorker\Lib\Gateway;
use Illuminate\Support\Facades\Log;

class events
{

public static function onWorkerStart($businessWorker)
{
echo “onWorkerStart\r\\
“;
}

public static function onConnect($client_id)
{
Gateway::sendToClient($client_id, json_encode([‘type’ => ‘onConnect’, ‘client_id’ => $client_id]));
echo “onConnect\r\\
“;
}

public static function onWebSocketConnect($client_id, $data)
{
echo “onWebSocketConnect\r\\
“;
}

public static function onMessage($client_id, $message)
{
Gateway::sendToClient($client_id, json_encode([‘type’ => ‘onMessage’, ‘client_id’ => $client_id, ‘name’ => json_decode($message)->name] ));

echo “onMessage\r\\
“;
}

public static function onClose($client_id)
{
Log::info(‘Workerman close connection’ . $client_id);
echo “onClose\r\\
“;
}

}

4. Test. Start the Workerman server

Executed in the command line, the supported commands are probably start|stop|restart, where –d means daemon mode, background daemon process.

Note that the port number in the service must be added to the whitelist to allow access.

php artisan workman start –d //Formal environment development command
php artisan workman start //Test environment development command

ls@ls-virtual-machine:/var/www/html/socket/socket$ php artisan workman start –d
Workerman[artisan workman] start in DAEMON mode
———————————————– WORKERMAN —– —————————————-
Workerman version:4.0.2 PHP version:7.2.24-0ubuntu0.18.04.3
—————————————- WORKERS —- ——————————————
proto user worker listen processes status
tcp ls Gateway websocket://0.0.0.0:2346 1 [OK]
tcp ls BusinessWorker none 1 [OK]
tcp ls Register text://0.0.0.0:1236 1 [OK]
————————————————– ————————————————–
Input “php artisan workman stop” to stop. Start success.

Open debugging mode in the browser F12 and enter in the Console

ws = new WebSocket(“ws://*.*.*.*:2346”);
ws.onopen = function() {
ws . send(‘{“name”:”one”,”user_id”:”111″}’);
ws . send(‘{“name”:”two”,”user_id”:”222″}’);
};
ws.onmessage = function(e) {
console.log(“Message received from the server:” + e.data);
};
ws.onclose = function(e) {
console.log(“Service has been disconnected” );
}

5. Things to note when upgrading http from https to websocket

Scenario: When upgrading the system, the front end uses websocket to update data in real time. The previous websocket connection used IP plus port mode:

var ws = new WebSocket(“ws://127.0.0.1:12151”); This mode is for normal access. However, when the project access is upgraded from http to https, it is found that the websocket cannot be connected and an error is reported. .

Solution: Check the documentation and find that there are two ways to connect websocket.

var ws = new WebSocket("ws://192.163.10.63:12151/socket")
 
var ws = new WebSocket("wss://domain name/socket/")

Points to note:

  1. If the website uses HTTPS, WebSocket must use the wss protocol;
  2. Connection requests using the wss protocol must only write domain names, not IP + ports;
  3. It is recommended to define a path for websocket after the URL domain name, in this case /socket/

nginx configuration

You only need to add a location to the HTTPS configured server.

# websockets
    location /socket/ {
        proxy_pass http://127.0.0.1:12151;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-IP $remote_addr;
    }

As shown below

Notice:

1. Location /socket/ {…} Pay special attention here!

The URL in HTML is wss://http://www.aabb.com/socket/, so the Nginx configuration must be /socket/

If the front end is wss://http://www.aabb.com/socket, the corresponding Nginx is /socket

2. The best proxy_pass corresponds to the public IP plus port number, ‘localhost:12151’, ‘127.0.0.1:12151’

3. proxy_http_version 1.1 The version number must be 1.1, this configuration is required

Description: Nginx reverse proxy, whether it is HTTP/S or WebSocket, will use port 443, and will be distributed by Nginx to each project server.

The knowledge points of the article match the official knowledge files, and you can further learn related knowledge. Network Skill TreeHomepageOverview 41515 people are learning the system