ThinkPHP 6.0 swoole extended websocket tutorial

Time:2019-11-6

Preface

ThinkPHP is about to usher in the latest version 6.0. For the current more and more popular swoole, ThinkPHP also launched the latest extension think swoole 3.0.

introduce

Tp6.0, which is about to be launched, has been adapted to swoole. It has also launched think swoole 3.0, and is adapted to socketio by default. There are some differences between version 2.0 and 2.0.

Websocket inherits http. An HTTP request is required before websocket connection. If the current address supports websocket, 101 is returned, and then the connection is made. That is to say, after my service supports websocket, every connection address can be connected to websocket, but it needs to be pre adapted to connect.

Parameter configuration

1

2

3

4

5

6

7

8

9

10

11

12

13

14

'server'           => [        'host'      => '0.0.0.0', //Monitor address

        'port'      => 808, //Listening port

        'mode'      => SWOOLE_PROCESS, //The operation mode is swoole? Process by default

        'sock_type' => SWOOLE_SOCK_TCP, //The default value of the sock type is swoole? Sock? TCP

        'options'   => [            'pid_file'              => runtime_path() . 'swoole.pid',            'log_file'              => runtime_path() . 'swoole.log',            'daemonize'             => false,            // Normally this value should be 1~4 times larger according to your cpu cores.

            'reactor_num'           => swoole_cpu_num(),            'worker_num'            => swoole_cpu_num(),            'task_worker_num'       => 4,//swoole_cpu_num(),

            'enable_static_handler' => true,            'document_root'         => root_path('public'),            'package_max_length'    => 20 * 1024 * 1024,            'buffer_output_size'    => 10 * 1024 * 1024,            'socket_buffer_size'    => 128 * 1024 * 1024,            'max_request'           => 3000,            'send_yield'            => true,

        ],

    ],    'websocket'        => [        'enabled'       => true,//Open websocket

        'handler'       => Handler::class//Custom wbesocket binding class

        'parser'        => Parser::class, //Custom parsing class

        'route_file'    => base_path() . 'websocket.php',        'ping_interval' => 25000,        'ping_timeout'  => 60000,        'room'          => [            'type'        => TableRoom::class,            'room_rows'   => 4096,            'room_size'   => 2048,            'client_rows' => 8192,            'client_size' => 2048,

        ],

    ],    'auto_reload'      => true,    'enable_coroutine' => true,    'resetters'        => [],    'tables'           => [],

Handler and parser greatly facilitate the customization of websocket services, and the default system integrates socketio.

This paper mainly introduces how to use socketio. It is assumed that you have a certain understanding and use of socketio.

By default, socketio will add corresponding parameters after the request address

At the same time, by default, socket IO will think that http://url/socket.io/ is the address that supports websocket service.

The address request has been processed in tp-swoole3.0.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

use think\Config;use think\Cookie;use think\Request;class Controller{    protected $transports = ['polling', 'websocket'];    public function upgrade(Request $request, Config $config, Cookie $cookie)

    {        if (!in_array($request->param('transport'), $this->transports)) {            return json(

                [                    'code'    => 0,                    'message' => 'Transport unknown',

                ],                400

            );

        }        if ($request->has('sid')) {

            $response = response('1:6');

        } else {

            $sid     = base64_encode(uniqid());

            $payload = json_encode(

                [                    'sid'          => $sid,                    'upgrades'     => ['websocket'],                    'pingInterval' => $config->get('swoole.websocket.ping_interval'),                    'pingTimeout'  => $config->get('swoole.websocket.ping_timeout'),

                ]

            );

            $cookie->set('io', $sid);

            $response = response('97:0' . $payload . '2:40');

        }        return $response->contentType('text/plain');

    }    public function reject(Request $request)

    {        return json(

            [                'code'    => 3,                'message' => 'Bad request',

            ],            400

        );

    }

}

In tp6.0, plug-in registration adopts service mode. You can view the route registration information in the TP swoole service registration file. If you want to customize the link rules, you can override the route.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

// +----------------------------------------------------------------------// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]// +----------------------------------------------------------------------// | Copyright (c) 2006-2018 http://thinkphp.cn All rights reserved.// +----------------------------------------------------------------------// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )// +----------------------------------------------------------------------// | Author: yunwuxin <[email protected]>// +----------------------------------------------------------------------namespace think\swoole;use Swoole\Http\Server as HttpServer;use Swoole\Websocket\Server as WebsocketServer;use think\App;use think\Route;use think\swoole\command\Server as ServerCommand;use think\swoole\facade\Server;use think\swoole\websocket\socketio\Controller;use think\swoole\websocket\socketio\Middleware;class Service extends \think\Service{    protected $isWebsocket = false;    /**

     * @var HttpServer | WebsocketServer

     */

    protected static $server;    public function register()

    {        $this->isWebsocket = $this->app->config->get('swoole.websocket.enabled', false);        $this->app->bind(Server::class, function () {            if (is_null(static::$server)) {                $this->createSwooleServer();

            }            return static::$server;

        });        $this->app->bind('swoole.server', Server::class);        $this->app->bind(Swoole::class, function (App $app) {            return new Swoole($app);

        });        $this->app->bind('swoole', Swoole::class);

    }    public function boot(Route $route)

    {        $this->commands(ServerCommand::class);        if ($this->isWebsocket) {

            $route->group(function () use ($route) {

                $route->get('socket.io/', '@upgrade');

                $route->post('socket.io/', '@reject');

            })->prefix(Controller::class)->middleware(Middleware::class);

        }

    }    /**

     * Create swoole server.

     */

    protected function createSwooleServer()

    {

        $server     = $this->isWebsocket ? WebsocketServer::class : HttpServer::class;

        $config     = $this->app->config;

        $host       = $config->get('swoole.server.host');

        $port       = $config->get('swoole.server.port');

        $socketType = $config->get('swoole.server.socket_type', SWOOLE_SOCK_TCP);

        $mode       = $config->get('swoole.server.mode', SWOOLE_PROCESS);        static::$server = new $server($host, $port, $mode, $socketType);

        $options = $config->get('swoole.server.options');        static::$server->set($options);

    }

}

Socketio uses demo by default

1

2

3

4

5

6

7

"en">

    "UTF-8">

    Title

    <code>"./static/js/socket.io.js"</code><code>></code></p>
<p><code>    </code><code>const</code> <code>socket = io(</code><code>'http://localhost:808'</code><code>);</code></p>
<p><code>    </code><code>socket.emit(</code><code>"test"</code><code>, </code><code>"your message"</code><code>);</code></p>
<p><code>    </code><code>socket.on(</code><code>"test"</code><code>,</code><code>function</code><code>(res){console.log(res)});

Configuration method of websocket routing

Create a new websocket.php file in the app directory. Note that the closure parameter name cannot be defined at will because of reflection, or it cannot be injected. The first parameter is websocket, which is the server object of the current websocket. The second parameter data is the data sent by the client. The first parameter of socketio emit is the same as the first parameter of websocket:: on as the event name.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

/**

 * Author:Xavier Yang

 * Date:2019/6/5

 * Email:[email protected]

 */use \think\swoole\facade\Websocket;

Websocket::on("test", function (\think\swoole\Websocket $websocket, $data) {    //var_dump($class);

    $websocket->emit("test", "asd");

});

Websocket::on("test1", function ($websocket, $data) {

    $websocket->emit("test", "asd");

});

Websocket::on("join", function (\think\swoole\Websocket $websocket, $data) {

    $websocket->join("1");

});

2128369977-5d172fd1aa6af_articlex.gif

Refer to the above method to use the new websocket service. Of course, tp-swoole3.0 also has many other new functions, which need to be explored and tried.
I will also share my use process with you in the next article.