Home >PHP Framework >ThinkPHP >Implementing Websocket broadcast using ThinkPHP6

Implementing Websocket broadcast using ThinkPHP6

WBOY
WBOYOriginal
2023-06-20 08:41:341720browse

With the continuous development of modern web applications, real-time communication has become one of the necessary functions. WebSocket technology is one of the most popular real-time communication methods, which can establish a persistent two-way connection between the server and the client to achieve real-time communication.

ThinkPHP is a very popular PHP framework. ThinkPHP 6 comes with the Swoole extension package, making it very simple to use WebSocket technology. This article will introduce how to use the ThinkPHP 6 framework to implement a WebSocket broadcast function.

Environment requirements

Before you start, you need to prepare the following environment:

  • PHP 7.2
  • Swoole extension
  • Composer
  • Basic Web development knowledge

Create project

First, we need to create a new project:

composer create-project topthink/think my-project

Then, for the convenience of using WebSocket , we need to add the Swoole extension in the composer.json file of the project:

"require": {
    "topthink/think-swoole": "^2.0",
    "swoole/swoole": "^4.7"
}

After completion, run the following command to install:

composer install

Create controller

Next, we need to create a controller to handle WebSocket requests. Create a file named Websocket.php in the app/controller directory and write the following code:

<?php

declare(strict_types=1);

namespace appcontroller;

use thinkswooleWebsocket as SwooleWebsocket;
use SwooleWebSocketFrame;

class Websocket extends SwooleWebsocket
{
    /**
     * 监听连接事件
     * @param SwooleWebSocketServer $server
     * @param SwooleHttpRequest $request
     */
    public function onOpen($server, $request)
    {
    }

    /**
     * 监听接收消息事件
     * @param SwooleWebSocketServer $server
     * @param Frame $frame
     */
    public function onMessage($server, Frame $frame)
    {
    }

    /**
     * 监听关闭事件
     * @param SwooleWebSocketServer $server
     * @param int $fd
     */
    public function onClose($server, $fd)
    {
    }
}

In the above code, we inheritedthinkswooleWebsocket class and override three of its methods:

  • onOpen method is used to listen for connection events;
  • The onMessage method is used to listen to receive message events; the
  • onClose method is used to listen to close events.

Currently, these methods do not do anything. Next, we will add the logic of WebSocket communication to these methods.

Register routing

After the controller is created, we need to register it in the routing. Add the following content in the app/route.php file:

use thinkacadeRoute;

Route::post('/ws', 'Websocket@onMessage')->middleware(    hinkmiddlewareAllowCrossDomain::class);

The Route::post method is used here to register the route. The request method of this route is POST, the path is /ws, and the request is mapped to the onMessage method of the Websocket controller.

Writing WebSocket communication logic

Now, we have completed the creation and registration of WebSocket routes and controllers. Next, we need to add the logic for WebSocket communication in the controller. We will use Swoole's WebSocket server to implement WebSocket communication.

In the onOpen method, we can obtain the client's connection object and store it for subsequent use. In the onMessage method, we can get the message sent by the client and broadcast this message to other clients. In the onClose method, we need to remove the client from the connection pool.

Create a file named WebSocketServer.php in the app/controller directory and write the following code:

<?php

declare(strict_types=1);

namespace appcontroller;

use SwooleHttpResponse;
use SwooleWebSocketFrame;
use SwooleWebSocketServer;
use thinkswoolewebsocketHandlerInterface;

class WebSocketServer implements HandlerInterface
{
    /**
     * @var array $connections
     */
    private $connections = [];

    /**
     * 监听连接事件
     * @param Server $server
     * @param SwooleHttpRequest $request
     */
    public function onOpen(Server $server, SwooleHttpRequest $request): void
    {
        $this->connections[$request->fd] = $request->fd;

        echo "client-{$request->fd} is connected
";
    }

    /**
     * 监听消息事件
     * @param Server $server
     * @param Frame $frame
     */
    public function onMessage(Server $server, Frame $frame): void
    {
        foreach ($this->connections as $fd) {
            $info = $server->getClientInfo((int)$fd);
            if ($info && isset($info['websocket_status']) && $info['websocket_status'] == WEBSOCKET_STATUS_FRAME) {
                $server->push($fd, $frame->data);
            } else {
                unset($this->connections[$fd]);
            }
        }

        echo "received message from client-{$frame->fd}: {$frame->data}
";
    }

    /**
     * 监听关闭事件
     * @param Server $server
     * @param int $fd
     * @param int $reactorId
     */
    public function onClose(Server $server, int $fd, int $reactorId): void
    {
        unset($this->connections[$fd]);

        echo "client-{$fd} is closed
";
    }

    /**
     * @param Response $response
     */
    public function onHandShake(Request $request, Response $response): bool
    {
        // Do nothing
        return true;
    }
}

Configure WebSocket service

Before writing the WebSocket service code, we need to create a configuration file named swoole.php in the config directory and write the following content:

return [
    'socket_type' => 'websocket',
    'host'        => '0.0.0.0',
    'port'        => 9501,
    'mode'        => SWOOLE_PROCESS,
    'sock_type'   => SWOOLE_SOCK_TCP,
    'settings' => [
        'worker_num' => swoole_cpu_num(),
    ],
    'handler' => ppcontrollerWebSocketServer::class,
];

In the above code, we tell the application how to start the Swoole WebSocket service through the configuration file. We start the websocket socket type, bind it on 0.0.0.0:9501, and enable multi-process mode, using the TCP protocol. worker_num The configuration item sets the number of processes of the server. swoole_cpu_num() is used here to return the number of system CPUs; handler The configuration item specifies what we have mentioned above. Created WebSocketServer class.

Run the WebSocket service

After completing the code to create and configure the WebSocket service, we need to run the code to start the WebSocket service. Just execute the following command on the command line:

php think swoole start --mode=websocket

The Websocket service has been started and you can test it by accessing your application. You can use this address: ws://your-domain:9501/ws. Open multiple tabs in the browser to test the WebSocket connection, message sending and receiving functions respectively.

Summary

This article introduces how to use the ThinkPHP 6 framework to implement a WebSocket broadcast function. We accomplish this by creating controllers, registering routes and writing WebSocket communication logic, and configuring the WebSocket service. This example can be used as a simple WebSocket best practice and provides a reference for us to develop more advanced WebSocket functions.

The above is the detailed content of Implementing Websocket broadcast using ThinkPHP6. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn