Swoole从入门到入土(18)——WebSocket服务器[心跳ping]

        由于 WebSocket 是长连接,如果一定时间内没有通讯,连接可能会断开。这时候需要心跳机制,WebSocket 协议包含了 Ping 和 Pong 两个帧,可以定时发送 Ping 帧来保持长连接。

1、心跳原理图:

 2、websocket协议控制帧描述

Control frames are identified by opcodes where the most significant bit of the opcode is 1.

Currently defined opcodes for control frames include 0x8 (Close), 0x9 (Ping), and 0xA (Pong). Opcodes 0xB-0xF are reserved for further control frames yet to be defined.

Control frames are used to communicate state about the WebSocket.

Control frames can be interjected in the middle of a fragmented message.

All control frames MUST have a payload length of 125 bytes or less and MUST NOT be fragmented.

从原文可知,Ping的协议头是0x9,Pong的协议头是0xA,控制帧最大载荷为125bytes且不能拆分

3、代码示例:

1) 发送ping帧

use Swoole\WebSocket\Frame;
use Swoole\WebSocket\Server;

$server = new Server('127.0.0.1', 9501);
$server->on('message', function (Server $server, Frame $frame) {
    $pingFrame = new Frame;
    $pingFrame->opcode = WEBSOCKET_OPCODE_PING;
    $server->push($frame->fd, $pingFrame);
});
$server->start();

2) 响应ping帧

$server->on('message', function (Swoole\WebSocket\Server $server, $frame) {
    if ($frame->opcode == 0x09) {
        echo "Ping frame received: Code {$frame->opcode}\n";
        // 回复 Pong 帧
        $pongFrame = new Swoole\WebSocket\Frame;
        $pongFrame->opcode = WEBSOCKET_OPCODE_PONG;
        $server->push($frame->fd, $pongFrame);
    } else {
        echo "Message received: {$frame->data}\n";
    }
});

4、关于ping与pong的结论

· 心跳包中可能会携带数据
· 当收到Ping帧的时候需要立即返回一个Pong帧
· 在连接建立之后,随时都可以发送Ping帧
· 心跳是用来测试链接是否存在和对方是否在线
· 在响应Ping帧的的Pong帧中,必须携和被响应的Ping帧中相同的数据

下一篇:Swoole从入门到入土(19)——WebSocket服务器[文件传输]

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Laravel 中使用 Swoole 扩展来实现 WebSocket 长连接非常简单。以下是配置 WebSocket 长连接及实现 pingpong 的步骤: 1. 安装 Swoole 扩展 使用 Composer 安装 Swoole 扩展: ``` composer require swoole/swoole ``` 2. 创建 WebSocket 服务器 在 Laravel 中创建 WebSocket 服务器需要使用 Swoole 扩展自带的 `WebSocket\Server` 类。 在 `app/Providers/AppServiceProvider.php` 文件中,注册 Swoole WebSocket 服务器: ```php use Swoole\WebSocket\Server; public function register() { $this->app->singleton(Server::class, function ($app) { $server = new Server('0.0.0.0', 9501); $server->set([ 'worker_num' => 4, 'daemonize' => env('APP_ENV') === 'production', ]); return $server; }); } ``` 在上面的代码中,我们定义了一个 WebSocket 服务器,并设置了 `worker_num` 和 `daemonize` 参数。 3. 实现 WebSocket 长连接 在 Laravel 中,可以通过 Swoole WebSocket 服务器的 `on` 方法来实现 WebSocket 长连接。 在 `AppServiceProvider` 类中,添加以下代码: ```php use Swoole\WebSocket\Server; use Swoole\Http\Request; use Swoole\WebSocket\Frame; public function boot(Server $server) { $server->on('open', function (Server $server, Request $request) { echo "connection open: {$request->fd}\n"; }); $server->on('message', function (Server $server, Frame $frame) { echo "received message: {$frame->data}\n"; $server->push($frame->fd, "received: {$frame->data}"); }); $server->on('close', function (Server $server, $fd) { echo "connection close: {$fd}\n"; }); } ``` 在上面的代码中,我们实现了 `open`、`message` 和 `close` 事件的回调函数。 当 WebSocket 客户端与服务器建立连接时,`open` 事件被触发。我们在这里记录连接的 `$request->fd`。 当服务器接收到消息时,`message` 事件被触发。我们在这里记录接收到的消息,并将其发送回客户端。 当连接关闭时,`close` 事件被触发。我们在这里记录连接的 `$fd`。 4. 实现 pingpong WebSocket 协议规定要保持长连接,需要定期发送心跳包,也就是 pingpong 消息。 在 Laravel 中,可以使用 Swoole WebSocket 服务器的 `tick` 方法来实现定时发送心跳包。 在 `AppServiceProvider` 类中,添加以下代码: ```php use Swoole\WebSocket\Server; public function boot(Server $server) { // ... $server->on('open', function (Server $server, Request $request) { // ... // 开始定时发送心跳包 $server->tick(30000, function () use ($server, $request) { $server->push($request->fd, 'ping'); }); }); // ... } ``` 在上面的代码中,我们在 `open` 事件的回调函数中,使用 `tick` 方法实现了每 30 秒发送一个 pingpong 消息。 这样就实现了 WebSocket 长连接及实现 pingpong 的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值