//复制即可使用 需要注意主机ip或者域名 端口 路径是否一致
$host = '198.126.0.101';
$port = 80;
$path = '/ws';
$key = base64_encode(openssl_random_pseudo_bytes(16));
$header = "GET $path HTTP/1.1\r\n" .
"Host: $host:$port\r\n" .
"Upgrade: websocket\r\n" .
"Connection: Upgrade\r\n" .
"Sec-WebSocket-Key: $key\r\n" .
"Sec-WebSocket-Protocol: /ws\r\n".
"Sec-WebSocket-Version: 13\r\n\r\n";
$socket = fsockopen($host, $port, $errno, $errstr, 2);
if (!$socket)
{
die($this->outJsonError(1001,"$errstr ($errno)"));
}
// dd($header);
@fwrite($socket, $header);
$response = fread($socket, 1500);
// dd($response);
if (strpos($response, '101') === false) {
die($this->outJsonError(1001,"连接失败"));
}
// echo "连接成功\n";
$video_device_id = $device_result['video_deviceid'];
$device_key = $device_result['video_devicekey'];
$sn = time()* 1000;
// 发送消息
$message = 'cmd=publish&topic=test&device_id=test&device_key=test&message={"cmd":3,"pv":0,"sn":"'.$sn.'","msg":{"attr":[120],"data":{"120":'.$is_open.'}}}'.
"\r\n\r\n";
fwrite($socket, web_encode($message));
// echo "发送消息: $message\n";
// 接收消息
$received = web_encode(fread($socket, 1500));
// echo "收到消息: $received\n";
// 不用则关闭连接
fclose($socket);
对数据加解密
public function web_encode($payload, $type = 'text', $masked = true)
{
$frameHead = [];
$payloadLength = strlen($payload);
switch ($type) {
case 'text':
$frameHead[0] = 129;
break;
case 'close':
$frameHead[0] = 136;
break;
case 'ping':
$frameHead[0] = 137;
break;
case 'pong':
$frameHead[0] = 138;
break;
}
if ($payloadLength > 65535) {
$frameHead[1] = ($masked === true) ? 255 : 127;
for ($i = 0; $i < 8; $i++) {
$frameHead[$i + 2] = ($payloadLength >> (56 - $i * 8)) & 255;
}
if ($frameHead[2] > 127) {
$frameHead[2] -= 128;
}
} elseif ($payloadLength > 125) {
$frameHead[1] = ($masked === true) ? 254 : 126;
$frameHead[2] = ($payloadLength >> 8) & 255;
$frameHead[3] = $payloadLength & 255;
} else {
$frameHead[1] = ($masked === true) ? $payloadLength + 128 : $payloadLength;
}
$frame = '';
foreach ($frameHead as $i => $frameHeader) {
$frame .= chr($frameHeader);
}
if ($masked === true) {
$mask = [];
for ($i = 0; $i < 4; $i++) {
$mask[$i] = mt_rand(0, 255);
$frame .= chr($mask[$i]);
}
for ($i = 0; $i < $payloadLength; $i++) {
$frame .= chr(ord($payload[$i]) ^ $mask[$i % 4]);
}
} else {
$frame .= $payload;
}
return $frame;
}
public function web_decode($data)
{
$unmaskedPayload = '';
$decodedData = [];
$firstByteBinary = sprintf('%08b', ord($data[0]));
$secondByteBinary = sprintf('%08b', ord($data[1]));
$opcode = bindec(substr($firstByteBinary, 4, 4));
$isMasked = ($secondByteBinary[0] == '1') ? true : false;
$payloadLength = ord($data[1]) & 127;
switch ($opcode) {
case 1:
$decodedData['type'] = 'text';
break;
case 2:
$decodedData['type'] = 'binary';
break;
case 8:
$decodedData['type'] = 'close';
break;
case 9:
$decodedData['type'] = 'ping';
break;
case 10:
$decodedData['type'] = 'pong';
break;
default:
return false;
}
if ($payloadLength === 126) {
$mask = substr($data, 4, 4);
$payloadOffset = 8;
$dataLength = ord($data[2]) << 8 | ord($data[3]);
} elseif ($payloadLength === 127) {
$mask = substr($data, 10, 4);
$payloadOffset = 14;
for ($i = 0; $i < 8; $i++) {
$dataLength |= (ord($data[$i + 2]) << (7 - $i) * 8);
}
} else {
$mask = substr($data, 2, 4);
$payloadOffset = 6;
$dataLength = $payloadLength;
}
if ($isMasked === true) {
for ($i = $payloadOffset; $i < $dataLength + $payloadOffset; $i++) {
$j = $i - $payloadOffset;
$unmaskedPayload .= $data[$i] ^ $mask[$j % 4];
}
} else {
$unmaskedPayload = substr($data, $payloadOffset);
}
$decodedData['payload'] = $unmaskedPayload;
return $decodedData['payload'];
}
响应: