isMasked函数:
//判断是否是经过掩码处理的帧
function isMasked($byte) {
return (ord($byte) & 0x80) > 0;
}
getPayloadLen函数:
//获取负载的长度
//首字节如果小于126,则长度为首字节的值
//首字节如果等于126,则长度为后面紧跟的两个字节表示的字节数
//如果首字节是127,则长度为后面紧跟8字节表示的字节数
function getPayloadLen($data) {
$first = ord($data[0]) & 0x7F;
$second = (ord($data[1])
getPayLoad函数:
//获取负载的内容,根据帧的结构
//第0字节为结束标记及帧类型
//第1字节是否掩码标识位及负载长度的首字节
//根据协议要求,浏览器发送的数据必须经过掩码处理,所以偏移量至少是1字节的帧首字节+4字节的掩码长度
//根据帧长度的不同,表示长度的字节数可能为1、3或9
//所以根据不同的情况截取不同长度的数据即为负载内容
function getPayload($data, $len) {
$offset = 5;
if ($len
getMask函数:
//获取掩码的值
//仍然是根据不同的偏移位置截取
function getMask($data, $len) {
$offset = 1;
if ($len
getFrameType函数:
//获取帧类型
function getFrameType($byte) {
return ord($byte) & 0x0F;
}
isFin函数:
//判断是否为结束帧
function isFin($byte) {
return (ord($byte[0]) & 0x80) > 0;
}
isControlFrame函数:
//判断是否为控制帧,控制帧包含关闭帧、PING帧和PONG帧
function isControlFrame($frameType) {
return $frameType === self::FRAME_CLOSE || $frameType === self::FRAME_PING || $frameType === self::FRAME_PONG;
}
parseBinaryFrame、parseTextFrame、parseRawFrame函数:
//处理负载的掩码,将其还原
function parseRawFrame($payload, $mask) {
$payloadLen = strlen($payload);
$dest = '';
$maskArr = array();
for ($i = 0; $i parseRawFrame($payload, $mask);
}
function parseBinaryFrame($payload, $mask) {
return $this->parseRawFrame($payload, $mask);
}
closeFrame函数:
//创建并发送关闭帧
function closeFrame($socketId, $closeCode = 1000, $closeMsg = 'goodbye') {
$closeCode = chr(intval($closeCode / 256)) . chr($closeCode % 256);
$frame = $this->createFrame($closeCode . $closeMsg, self::FRAME_CLOSE);
$this->socketSend($socketId, $frame);
$this->disconnect($socketId);
}
sendPing、sendPong函数:
function sendPing($socketId, $data = 'ping') {
$frame = $this->createFrame($data, self::FRAME_PING);
$this->socketSend($socketId, $frame);
}
function sendPong($socketId, $data = 'pong') {
$frame = $this->createFrame($data, self::FRAME_PONG);
$this->socketSend($socketId, $frame);
}
createFrame函数:
//封装帧头的相关标识位、长度等信息
function createFrame($data, $type, $fin = 0x01) {
$dataLen = strlen($data);
$frame = chr(($fin