php - 无法在 php 中使用 wss:// 连接到 websocket
问题描述
首先,如果我的帖子中有一些错误,我想道歉,我不是母语英语(法语)。所以我在尝试将自己连接到具有 wss:// 域的 websocket 时遇到了问题。域是这个:wss://engine.coss.io/api/v1/ws/v1/ht/{ETH_BTC}。URL 的最后一部分是查询字符串之王,您可以在以下位置找到详细信息:https ://api.coss.io/v1/spec
首先,我尝试通过 chrome 连接到这个地址,但我收到错误“ERR_DISALLOWED_URL_SCHEME”,我发现这与某种丢失的证书有关。但我的目标是让它与 php 一起工作,所以我尝试了几种方法来连接到这个地址,但没有任何效果,这是我尝试连接到它的方式之一:
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
echo $socket;
echo socket_connect($socket ,"35.198.217.124",443)?"true":"false";
$in = "GET / HTTP/1.1\r\n";
$in .= "Host: www.example.com\r\n";
$in .= "Connection: Close\r\n\r\n";
$out = '';
echo "Sending HTTP GET request...";
socket_write($socket, $in, strlen($in));
echo "OK.\n";
echo "Reading response:\n\n";
while ($out = socket_read($socket, 2048)) {
echo $out;
}
感谢您的帮助:) 新年快乐!
编辑 :
在多次尝试后,我遇到了这种情况,我有两段代码在机器的根上获得 200 响应,但绝对不是我想要的,第二段代码得到 400 错误错误请求,这两段代码就在这里:
根上的 200 响应(请注意,如果我将 /api 添加到路径中,则会出现 404 错误):
$contextOptions = array(
'ssl' => array(
"verify_peer" => false,
"verify_peer_name" => false
)
);
$context = stream_context_create($contextOptions);
$fp = stream_socket_client("ssl://engine.coss.io:443", $errstr, $errno, 30, STREAM_CLIENT_CONNECT, $context);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
echo "true\n";
fwrite($fp, "GET / HTTP/1.1\r\n" .
"Host: www.engine.coss.io\r\n" .
"Accept: */*\r\n" .
"Connection: Upgrade\r\n" .
"Upgrade: websocket\r\n\r\n");
while (!feof($fp)) {
echo fgets($fp, 1024);
}
fclose($fp);
}
而这个给了我一个 400 bad Request :
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
echo $socket;
echo socket_connect($socket ,"35.198.217.124",443)?"true":"false";
$in = "GET /api/v1/ws/v1/ht/{ETH_BTC} HTTP/1.1\r\n";
$in .= "Host: https://www.engine.coss.io\r\nAccept: */*\r\nConnection: Upgrade\r\nUpgrade: websocket\r\n\r\n";
//$in .= "Connection: Close\r\n\r\n";
$out = '';
echo "Sending HTTP GET request...";
socket_write($socket, $in, strlen($in));
echo "OK.\n";
echo "Reading response:\n\n";
while ($out = socket_read($socket, 2048)) {
echo $out;
}
编辑 2:
所以我给网站的支持发了邮件,他们告诉我网址有错误,正确的是:wss://engine.coss.io/ws/v1/ht/{ETH_BTC}
这似乎适用于这段代码,因为我得到了 101 个成功的握手,但现在的问题是,一旦握手成功,脚本就会结束,所以我永远不会得到我想要的信息,也许有一种方法可以让脚本通过 websocket 监听? 我在文档中没有找到任何东西......
代码 :
$contextOptions = array(
'ssl' => array(
"verify_peer"=>false,
"verify_peer_name"=>false
)
);
$context = stream_context_create($contextOptions);
$fp =stream_socket_client("ssl://engine.coss.io:443/ws/v1/ht/{COSS_ETH}",$errstr,$errno,30,STREAM_CLIENT_CONNECT,$context);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
echo "true\n";
fwrite($fp, "GET /ws/v1/ht/{COSS_ETH} HTTP/1.1\r\nHost: engine.coss.io\r\nAccept: */*\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n");
// Notez que si ici je rajoute au path /api/v1/ws/v1/ht/{ETH_BTC} j'obtiens une erreur 404 not found ...
while (!feof($fp)) {
echo fgets($fp, 2024);
}
}
解决方案
PHP 默认不支持 'wss://' 流,但您可以实现自己的 'wss://' StreamWrapper 类。
这是一个例子。在 stream_wrapper_register() 中将 'var' 更改为 'wss' 会让你开始。
http://php.net/manual/en/stream.streamwrapper.example-1.php
以下是您可以在 StreamWrapper 类中实现的所有方法,但您可能不需要全部。
http://php.net/manual/en/class.streamwrapper.php
祝你好运!
推荐阅读
- java - 为什么 intellij 会警告“IDE 内存不足,这可能会影响性能”?
- laravel - Vue 路由器无法使用 laravel 电子邮件验证 url 405 错误
- docker - 如何使用 Nginx 将 Gitlab 存储库推送到 docker 容器?
- node.js - 为什么我不应该在生产模式下使用 dotenv?
- python - 如何在 Python 中创建不确定数量的数组
- .htaccess - 301重定向消除部分URL
- python - iat() 不是单个单元格,而是用相同的对象替换 pandas 数据框列中的所有单元格
- java - Eclipse Java - 应用事件
- javascript - 为什么 MatterJS 物理坐标与 DOM 元素有偏移?
- javascript - 如何处理多参数函数中的嵌套默认值