Swoole从入门到入土(17)——WebSocket服务器[成员函数与配置选项]

摘要:
此函数与现有方法不同。现有方法仅确定它是否为TCP连接,但无法确定它是否是已完成握手的WebSocket客户端。·WebSocket_Subprotocol:设置WebSocket子协议。

这一节,我们重点了解websocket server的成员函数以及相关的配置选项。

1、成员函数

push:向 WebSocket 客户端连接推送数据,长度最大不得超过 2M。

SwooleWebSocketServer->push(int $fd, string $data, int $opcode = WEBSOCKET_OPCODE_TEXT, bool $finish = true): bool

// v4.4.12版本改为了flags参数
SwooleWebSocketServer->push(int $fd, string $data, int $opcode = WEBSOCKET_OPCODE_TEXT, int $flags = SWOOLE_WEBSOCKET_FLAG_FIN): bool

$fd:客户端连接的 ID 【如果指定的 $fd 对应的 TCP 连接并非 WebSocket 客户端,将会发送失败】

$data:要发送的数据内容,Swoole 版本 >= v4.2.0 传入的 $data,如果是 SwooleWebSocketFrame 对象则其后续参数会被忽略

$opcode:指定发送数据内容的格式 【默认为WEBSOCKET_OPCODE_TEXT。发送二进制内容 $opcode 参数需要设置为 WEBSOCKET_OPCODE_BINARY】

Swoole从入门到入土(17)——WebSocket服务器[成员函数与配置选项]第1张

 $finish:是否发送完成

注意:

自 v4.4.12 版本起,finish 参数(bool 型)改为 flags 参数(int 型)以支持 WebSocket 压缩,finish 对应 SWOOLE_WEBSOCKET_FLAG_FIN 值为 1,原有 bool 型值会隐式转换为 int 型,此改动向下兼容无影响。 此外压缩 flag 为 SWOOLE_WEBSOCKET_FLAG_COMPRESS。

exist:判断 WebSocket 客户端是否存在,并且状态为 Active 状态。

SwooleWebSocketServer->exist(int $fd): bool

返回值:连接存在,并且已完成 WebSocket 握手,返回 true;连接不存在或尚未完成握手,返回 false

注意:v4.3.0 以后,此 API 仅用于判断连接是否存在,请使用 isEstablished 判断是否为 WebSocket 连接。

pack:打包 WebSocket 消息。

SwooleWebSocketServer::pack(string $data, int $opcode = WEBSOCKET_OPCODE_TEXT, bool $finish = true, bool $mask = false): string

// v4.4.12版本改为了flags参数
SwooleWebSocketServer::pack(string $data, int $opcode = WEBSOCKET_OPCODE_TEXT, int $flags = SWOOLE_WEBSOCKET_FLAG_FIN): string

$data:消息内容

$opcode:指定发送数据内容的格式 【默认为WEBSOCKET_OPCODE_TEXT。发送二进制内容 $opcode 参数需要设置为 WEBSOCKET_OPCODE_BINARY】

$finish:帧是否完成 。自 v4.4.12 版本起,finish 参数(bool 型)改为 flags 参数(int 型)以支持 WebSocket 压缩,finish 对应 SWOOLE_WEBSOCKET_FLAG_FIN 值为 1,原有 bool 型值会隐式转换为 int 型,此改动向下兼容无影响。

$mask:是否设置掩码【v4.4.12 已移除此参数】

返回值:返回打包好的 WebSocket 数据包,可通过 SwooleServer 基类的 send() 发送给对端

$ws = new SwooleServer('127.0.0.1', 9501 , SWOOLE_BASE);

$ws->set(array(
    'log_file' => '/dev/null'
));

$ws->on('WorkerStart', function (SwooleServer $serv) {
});

$ws->on('receive', function ($serv, $fd, $threadId, $data) {
    $sendData = "HTTP/1.1 101 Switching Protocols
";
    $sendData .= "Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: IFpdKwYy9wdo4gTldFLHFh3xQE0=
";
    $sendData .= "Sec-WebSocket-Version: 13
Server: swoole-http-server

";
    $sendData .= SwooleWebSocketServer::pack("hello world
");
    $serv->send($fd, $sendData);
});

$ws->start();

unpack:解析 WebSocket 数据帧。

SwooleWebSocketServer::unpack(string $data): SwooleWebSocketFrame|false;

$data:消息内容

返回值:解析失败返回 false,解析成功返回 SwooleWebSocketFrame 对象

disconnect:主动向 WebSocket 客户端发送关闭帧并关闭该连接。

SwooleWebSocketServer->disconnect(int $fd, int $code = SWOOLE_WEBSOCKET_CLOSE_NORMAL, string $reason = ''): bool

$fd:客户端连接的 ID【如果指定的 $fd 对应的 TCP 连接并非 WebSocket 客户端,将会发送失败】

$code:关闭连接的状态码【根据 RFC6455,对于应用程序关闭连接状态码,取值范围为 1000 或 4000-4999 之间】

$reason:关闭连接的原因【utf-8 格式字符串,字节长度不超过 125】

返回值:发送成功返回 true,发送失败或状态码非法时返回 false

注意:Swoole 版本 >= v4.0.3 可用

isEstablished:检查连接是否为有效的 WebSocket 客户端连接。此函数与 exist 方法不同,exist 方法仅判断是否为 TCP 连接,无法判断是否为已完成握手的 WebSocket 客户端。

SwooleWebSocketServer->isEstablished(int $fd): bool

$fd:客户端连接的 ID【如果指定的 $fd 对应的 TCP 连接并非 WebSocket 客户端,将会发送失败】

2、配置选项

WebSocketServer 是 Server 的子类,可以使用 Server->set() 方法传入配置选项,设置配置选项参数。

· websocket_subprotocol:设置 WebSocket 子协议。设置后握手响应的 HTTP 头会增加 Sec-WebSocket-Protocol: {$websocket_subprotocol}。

示例代码:

$server->set([
    'websocket_subprotocol' => 'chat',
]);

· open_websocket_close_frame:启用 WebSocket 协议中关闭帧(opcode 为 0x08 的帧)在 onMessage 回调中接收,默认为 false。开启后,可在 SwooleWebSocketServer 中的 onMessage 回调中接收到客户端或服务端发送的关闭帧,开发者可自行对其进行处理。

示例代码:

$server = new SwooleWebSocketServer("0.0.0.0", 9501);
$server->set(array("open_websocket_close_frame" => true));
$server->on('open', function (SwooleWebSocketServer $server, $request) {
});

$server->on('message', function (SwooleWebSocketServer $server, $frame) {
    if ($frame->opcode == 0x08) {
        echo "Close frame received: Code {$frame->code} Reason {$frame->reason}
";
    } else {
        echo "Message received: {$frame->data}
";
    }
});

$server->on('close', function ($ser, $fd) {
});

$server->start();

· open_websocket_ping_frame:启用 WebSocket 协议中 Ping 帧(opcode 为 0x09 的帧)在 onMessage 回调中接收,默认为 false。开启后,可在 SwooleWebSocketServer 中的 onMessage 回调中接收到客户端或服务端发送的 Ping 帧,开发者可自行对其进行处理。值为 false 时底层会自动回复 Pong 帧,但如果设为 true 后则需要开发者自行回复 Pong 帧。Swoole 版本 >= v4.5.4 可用。

$server = new SwooleWebSocketServer("0.0.0.0", 9501);
$server->set(array("open_websocket_ping_frame" => true));
$server->on('open', function (SwooleWebSocketServer $server, $request) {
});

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

$server->on('close', function ($ser, $fd) {
});

$server->start();

· open_websocket_pong_frame:启用 WebSocket 协议中 Pong 帧(opcode 为 0x0A 的帧)在 onMessage 回调中接收,默认为 false。开启后,可在 SwooleWebSocketServer 中的 onMessage 回调中接收到客户端或服务端发送的 Pong 帧,开发者可自行对其进行处理。Swoole 版本 >= v4.5.4 可用

示例代码:

$server = new SwooleWebSocketServer("0.0.0.0", 9501);
$server->set(array("open_websocket_pong_frame" => true));
$server->on('open', function (SwooleWebSocketServer $server, $request) {
});

$server->on('message', function (SwooleWebSocketServer $server, $frame) {
    if ($frame->opcode == 0xa) {
        echo "Pong frame received: Code {$frame->opcode}
";
    } else {
        echo "Message received: {$frame->data}
";
    }
});

$server->on('close', function ($ser, $fd) {
});

$server->start();

· websocket_compression:启用数据压缩。为 true 时允许对帧进行 zlib 压缩,具体是否能够压缩取决于客户端是否能够处理压缩(根据握手信息决定,参见 RFC-7692) 需要配合 flags 参数 SWOOLE_WEBSOCKET_FLAG_COMPRESS 来真正地对具体的某个帧进行压缩。Swoole 版本 >= v4.4.12 可用

use SwooleWebSocketFrame;
use SwooleWebSocketServer;

$server = new Server('127.0.0.1', 9501);
$server->set(['websocket_compression' => true]);
$server->on('message', function (Server $server, Frame $frame) {
    $server->push(
        $frame->fd,
        'Hello Swoole',
        SWOOLE_WEBSOCKET_OPCODE_TEXT,
        SWOOLE_WEBSOCKET_FLAG_FIN | SWOOLE_WEBSOCKET_FLAG_COMPRESS
    );
    // $server->push($frame->fd, $frame); // 或者 服务端可以直接原封不动转发客户端的帧对象
});
$server->start();

---------------------------  我是可爱的分割线  ----------------------------

最后博主借地宣传一下,漳州编程小组招新了,这是一个面向漳州青少年信息学/软件设计的学习小组,有意向的同学点击链接,联系我吧

设置 WebSocket 子协议。

免责声明:文章转载自《Swoole从入门到入土(17)——WebSocket服务器[成员函数与配置选项]》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇tp配置+路由+基本操作利用sys.sysprocesses检查SqlServer的阻塞和死锁下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Signalr入门系列:Signalr简介(二)

一、SignalR和WebSocket SignalR是在WebSocket的基础上进一步的封装,可以实现除了WebSocket原有功能上更多的功能,例如回退到其他transports,修改应用程序以更新WebSocket implementations。SignalR可以自动判断传输方式,在可以用的情况下使用新的WebSocket传输,并在必要时使用旧的...

WebSocket 详解教程

目录   概述  WebSocket 客户端  WebSocket 服务端  WebSocket 代理  FAQ  完整示例  资料 概述 WebSocket 是什么? WebSocket 是一种网络通信协议。RFC6455 定义了它的通信标准。 WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。 为什么...

保障接口安全的5种常见方式

一般有五种方式:1、Token授权认证,防止未授权用户获取数据;2、时间戳超时机制;3、URL签名,防止请求参数被篡改;4、防重放,防止接口被第二次请求,防采集;5、采用HTTPS通信协议,防止数据明文传输; 所有的安全措施都用上的话有时候难免太过复杂,在实际项目中需要根据自身情况作出取舍,比如可以只使用签名机制就可以保证信息不会被篡改,或者定向提供服务的...

IOS网络编程之Socket详解

Socket描述了一个IP、端口对。它简化了程序员的操作,知道对方的IP以及PORT就可以给对方发送消息,再由服务器端来处理发送的这些消息。所以,Socket一定包含了通信的双发,即客户端(Client)与服务端(server)。1)服务端利用Socket监听端口;2)客户端发起连接;3)服务端返回信息,建立连接,开始通信;4)客户端,服务端断开连接。 1...

WebSocket入门及使用指南

最近在一个项目中,需要使用到websocket,于是就花了一点时间来熟悉websocket并总结写篇blog。 为何使用websocket 在浏览器与服务器通信间,传统的 HTTP 请求在某些场景下并不理想,比如实时聊天、实时性的小游戏等等, 其面临主要两个缺点: 无法做到消息的「实时性」; 服务端无法主动推送信息; 其基于 HTTP 的主要解决方案...

从浏览器输入网址到页面显示的全过程

【前言】从全局来讲,当键入一个url时,肯定是需要从服务器请求某个页面或某条数据然后显示到用户自己的电脑屏幕上。这个过程中其实包括:DNS对url域名的解析(在url中解析出服务器所在的IP地址,有的url也包括端口),计算机网络中的五层协议层传输,代理服务器的响应、缓存或者负载均衡、最终html/css/js文件的解析与展现。从后端到前端,这只是概括,接...