Laravel uses swoole to build websocket links

Option 1 Composer installation configuration Install the LaravelS extension package:

composer require hhxsv5/laravel-s

Laravel 5.5 and above are available, no need to manually  config/app.php register in the configuration file, run the Artisan command to publish the corresponding script and configuration file to the root directory

php artisan laravels publish

This command will publish the configuration file  laravels.php to  config the directory, and the script file to  bin the directory

You can perform some basic configurations for Swoole in the configuration file, and the script file is mainly used to manage the startup, reload, shutdown and other operations of the Swoole service.

Start LaravelS

//命令启动 LaravelS 
php bin/laravels start 

In this way, the Swoole service is started and listens to the local port 5200. If a request is sent to this port, it can be processed.

In addition  php bin/laravels , other commands are supported to manage LaravelS:

Solution 2 pecl command installation needs to install pecl first

  php swoole extension installation

pecl install swoole

Modify the php.ini configuration file

extension=swoole.so

Restart php-fpm different system commands are different

sudo service php-fpm start      # 启动php-fpm

Check that the swoole extension is installed

php -m

Install laraveltw/laravel-swoole

Use composer to install in the project root directory

composer require swooletw/laravel-swoole -vvv 

It is best to add the -vvv parameter, because the installation is very slow, and it will give people a feeling that the owner is stuck without installation. It is best not to execute it locally or in PHPstorm. Because windows does not support laravel-swoole, there will be various problems. Patience is required as the installation can be performed in the project root directory of the virtual machine. When you see the logo in the figure below in composer.josn, the installation is successful

After Swoole is installed, it is to write the server-side code, you can write the php file websocket.php by yourself

code show as below:

<?php
ignore_user_abort(); // 后台运行
set_time_limit(0); // 取消脚本运行时间的超时上限
 
//创建一个websocket服务器
$ws_server = new swoole_websocket_server('0.0.0.0', 9501);
 
//创建一个用于存储的redis
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
 
$ws_server->on('open', function ($ws, $request) use ($redis) {
    $redis->sAdd('id', $request->fd);
    $mes = '用户:'.$request->fd.'已加入聊天室';
    $redis->sAdd('mes', $mes);
    pushAll($redis,$ws,$mes);
    getAllMes($redis,$ws);
});
 
$ws_server->on('message', function ($ws, $frame) use ($redis) {
    $mes = '用户:'.$frame->fd.'<br/>'.$frame->data;
    pushAll($redis,$ws,$mes);
});
 
//监听WebSocket连接关闭事件
$ws_server->on('close', function ($ws, $fd) use ($redis) {
        $redis->srem('key:'.$id,$fd);
    $mes = '用户:'.$fd.'已退出聊天室';
    $redis->sAdd('mes', $mes);
    pushAll($redis,$ws,$mes);
});
 
$ws_server->start();
 
/**
 * 登录时获取以前的消息
 */
function getAllMes($redis,$ws){
    $mesLists = $redis->sMembers('mes');
    foreach ($mesLists as $mes){
        pushAll($redis,$ws,$mes);
    }
}
/**
 * 给所有用户发信息
 */
function pushAll($redis,$ws,$mes){
    $fds = $redis->sMembers('id');
    foreach ($fds as $fd){
            if($ws->exist($fd)){
                    $ws->push($fd,$mes);
            }
    }
}

Then linux runs

php webcoket.php

The above is a method, you can also write an automatic loading method such as

Use laravel's own method artisan

php artisan make:command Swoole

Swoole files will be generated in the app\Console\Command\ directory

<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use swoole_websocket_server;

class Swoole extends Command
{

    protected $signature = 'swoole {action}';
    protected $description = 'Command description';

    public function __construct()
    {
        parent::__construct();
    }
    /**
     * Execute the console command.
     * 这个方法中的逻辑需要自己写
     * @return mixed
     */
    public function handle()
    {
        $action = $this->argument('action');
        switch ($action) { //方法可以自己写调用
            case 'close':
                break;
            default:
                $this->start();
                break;
        }
    }
    public function start()
    {
        // 这里是监听的服务端口号
        $this->ws = new swoole_websocket_server("0.0.0.0", 9500);
        //监听WebSocket连接打开事件
        $this->ws->on('open', function ($ws, $request) {
             $this->ws->push($request->fd, "is ok\n"); //链接服务器成功返回提示
        });
        //监听WebSocket消息事件
        $this->ws->on('message', function ($ws, $frame) {
            $this->info("client is SendMessage\n" . $frame);
        });
        //监听WebSocket主动推送消息事件
        $this->ws->on('request', function ($request, $response) {
            $scene = $request->post['scene'];
            foreach ($this->ws->connections as $fd) {
                if ($this->ws->isEstablished($fd)) {
                    $this->ws->push($fd, $scene);
                }
            }
        });
        //监听WebSocket连接关闭事件
        $this->ws->on('close', function ($ws, $fd) {
            $this->info("client is close\n");
        });
        $this->ws->start();
    }
}

Register this Swoole class in the Kernel.php file

<?php

namespace App\Console;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{

    protected $commands = [
        \App\Console\Commands\Swoole::class,
    ];
    protected function schedule(Schedule $schedule)
    {
    }
    protected function commands()
    {
        $this->load(__DIR__.'/Commands');
        require base_path('routes/console.php');
    }
}

Execute in the root directory of the virtual machine

 php artisan swoole start

It will start a long-term process to complete the server and back-end code here. Now a front-end page is needed to realize the long link

The front-end code is very simple

<!doctype html>
<html>
<head>
    <title>测试WebSocket</title>
</head>
    <div id="WebSocket"></div>
<body>
    <script>
    var ws = new WebSocket("ws://ip:9500");
    ws.onopen = function(event) {
        console.log("客户端已连接上!");
        ws.send("hello server,this is client!"); //客户端给服务端推送消息
    };
    ws.onmessage = function(event) {
        var parent = document.getElementById('WebSocket');
        var div = document.createElement("div");
        div.innerHTML = event.data
        parent.appendChild(div);
        console.log("服务器传过来的数据是:" + event.data);
    }
    ws.onclose = function(event) {
        console.log("连接已关闭");
    };
    </script>
</body>

Guess you like

Origin blog.csdn.net/weixin_43695488/article/details/126134521