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 ($lengetMask函数:
//获取掩码的值 //仍然是根据不同的偏移位置截取 function getMask($data, $len) { $offset = 1; if ($lengetFrameType函数:
//获取帧类型 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