php - WSS 握手问题(PHP WebSocket 服务器)
问题描述
我使用 PHP 开发了一个 WebSocket 服务器,它在 ws:// 下运行良好,但在生产环境中它使用 https://,那么我必须使用 wss://。
我应该使用证书来启动套接字还是类似的东西?我无法解析标头来完成握手。
如何在 https 服务器后面执行握手?
这是一台带有 Amazon 证书的 AWS EC2 机器。
我尝试将 .pem 文件导入套接字初始化,在我的 https:// 环境后面运行 ws://,但没有任何效果:(
套接字初始化:
$socket = stream_socket_server(
"tcp://0.0.0.0:" . env("APP_WSS_PORTA"),
$errno,
$errstr
);
我也试过:
use Aws\Acm\AcmClient;
$cert = (new AcmClient(include config_path('aws.php')))->GetCertificate([
"CertificateArn" => "arn:aws:acm:sa-east-1:EDITED_TO_STACKOVERFLOW"
])["CertificateChain"];
$cert_path = "cert.pem";
file_put_contents(base_path($cert_path), $cert);
$context = stream_context_create(
["ssl" => ["local_cert"=> $cert_path]]
);
$socket = stream_socket_server(
"tcp://0.0.0.0:" . env("APP_WSS_PORTA"),
$errno,
$errstr,
STREAM_SERVER_BIND|STREAM_SERVER_LISTEN,
$context
);
我的握手功能:
function wsHandshake($data)
{
echo "> Handshake " . remoteIp() . PHP_EOL;
$lines = preg_split("/\r\n/", $data);
$headers = array();
foreach ($lines as $line) {
$line = chop($line);
if (preg_match('/\A(\S+): (.*)\z/', $line, $matches)) {
$headers[$matches[1]] = $matches[2];
}
}
var_dump($data); // to debug it :)
if (!isset($headers['Sec-WebSocket-Version']) || $headers['Sec-WebSocket-Version'] < 6) {
echo '> Versao do WebSocket nao suportada' . PHP_EOL;
return false;
}
$sec_accept = base64_encode(pack('H*', sha1($headers['Sec-WebSocket-Key'] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));
$response = "HTTP/1.1 101 Switching Protocols\r\n";
$response .= "Upgrade: websocket\r\n";
$response .= "Connection: Upgrade\r\n";
$response .= "Sec-WebSocket-Accept: " . $sec_accept . "\r\n";
$response .= "\r\n";
return $response;
}
带有 ws:// 的 var_dump
string(448) "GET / HTTP/1.1
Host: 127.0.0.1:3131
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Sec-WebSocket-Version: 13
Origin: http://localhost
Sec-WebSocket-Extensions: permessage-deflate
Sec-WebSocket-Key: PuIYHJZ4x8IyXajFf4WAsw==
Connection: keep-alive, Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
"
带有 wss:// 的 var_dump
string(517) "\000\000��}hh�հ�h����`�ݘ����O��GQ�E� S�8�@��,��=��c���C8�ǯ�G!6{<\000$�+�/̨̩�,�0�
� ��\0003\0009\000/\0005\000
\000�\000\000\000�\000\000\000
\000\000
\000\000\000\000\000\000
\000\000\000#\000\000\000\000\000
hhttp/1.1\000\000\000\000\000\000\0003\000k\000i\000\000 ��"�c��GLGX�Ƶ��:�"ŵ�)բ
E��)\000\000Al�d��#Q{��t��q>��eb���u�+�d��M�!2�-��tI����z�y�\ĉ�\000\\000-\000\000\000@\000\0"...
解决方案
推荐阅读
- google-api - 如何从 Gmail api 访问已删除的电子邮件?
- reactjs - 如何使用 Styled-Components 覆盖 CSS 类
- android - 如何防止在滚动视图中加载所有recyclerview项目?
- amazon-web-services - 模仿 s3 和 dynamo 开发环境
- php - PHP Laravel Nova 如何在数据库中保存多选值
- python - Pandas apply():如何根据字符串匹配乘以选定的列并返回完整的数据框
- spring - AuthenticationProvider 中抛出的 AuthenticationException 映射到 ExceptionTranslationFilter 中的 AccessDeniedException
- passenger - docker安装openproject:Phusion乘客安装后无法启动
- scala - 如何在任何代码点查看所有可用的隐式及其类型?
- python - 自定义身份验证后端的问题