【问题标题】:Unable to connect to websocket using wss:// in php无法在 php 中使用 wss:// 连接到 websocket
【发布时间】:2019-05-28 02:42:27
【问题描述】:

首先,如果我的帖子中有一些错误,我想道歉,我不是母语英语(法语)。 因此,我在尝试将自己连接到具有 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 成功的握手,但现在的问题是,一旦握手成功,脚本就会结束,所以我永远不会得到我想要的信息,也许有一种方法可以让脚本保持监听通过网络套接字?我在文档中没有找到任何内容...

代码:

$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);

    }
}

【问题讨论】:

  • WebSocket client in PHP?的可能重复
  • 我看到了这篇文章,但没有帮助,因为问题来自地址,而 php 7 具有连接到 websocket 所需的工具,无需像他们在你的帖子中所说的那样连接到库.. .
  • 看到你的问题,这不是 websockets 的工作方式。也许你需要先阅读websockets
  • @Binar Web 我看到了你的链接,但我无法在 php 中了解更多关于 websockets 的信息,问题是我接近获得连接,因为 hanshake 成功但之后它关闭了连接,我在 rfc 文档中阅读了很多内容,但如果可以,我将不胜感激

标签: php sockets http websocket get


【解决方案1】:

默认情况下 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

祝你好运!

【讨论】:

  • 非常感谢您的回答!写完我的答案后,我会立即查看您的链接。但我想知道:我得到了网络套接字的 ip 地址,然后我在 php 中做了一行:echo socket_connect($socket ,"35.198.217.124",443)?"true":"non",我得到了真实的结果,但是当我尝试向那种 websocket 发送一些东西(标题可能错误)之后,我得到了400 错误“BAD REQUEST”是否意味着我成功连接但我发送了错误的请求?
  • @CYRUS 是的,确实是这个意思。您连接成功,但是在您向 35.198.217.124 发送 HTTP 请求后,您使用了错误的域名 www.example.com。这就是它失败的原因。
  • 感谢您的回答,这显然是正确的,但是在多次尝试使用其他主机名后,我仍然收到错误的请求响应,您知道错误可能来自哪里吗?
  • @CYRUS 如果将 socket_connect() 行更改为: echo socket_connect($socket, "93.184.216.34", 80) ? “真假”;使用“主机:www.example.com”时它确实有效。 93.184.216.34 是 www.example.com 的 IP 地址。如果您在端口 443 上进行连接,则您使用的是 HTTPS,并且您需要额外的步骤来设置 SSL 连接。不幸的是,我现在不手动设置 HTTPS/SSL。
  • @CYRUS 也许下面的链接会对你有所帮助:devdungeon.com/content/how-use-ssl-sockets-php
【解决方案2】:

我已使您的第二个代码块正常工作(带有 stream_context_create() 的代码块)。 下面的代码检索 ETH 和 BTC 之间的汇率。 我认为您不再需要实现 wss://,因为他们的 api 似乎也可以在 https://

上使用
$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 /api/v1/dp?symbol=ETH_BTC  HTTP/1.1\r\n" .
        "Host: 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);
}

返回:

{"symbol":"ETH_BTC","asks":[["0.03698000","0.12000000"],["0.03705000","0.12000000"],["0.03715000","0.12000000"], .....

【讨论】:

  • 嗨@EvE 谢谢你的回答,你说得对,这很好用,但问题是在这种情况下,请求是一个常规的http请求,我永远不会得到关于更改的通知网站,直到我发出 http 请求。此外,网站 http 请求成本为 1 个单位的单位系统,而 websocket 成本为 0 个单位,这就是我想使用它们的原因,我编辑了这篇文章,我认为我们正在接近工作代码:)
  • @CYRUS 我目前没有时间进一步研究它,但出于好奇:这个网站怎么会收取 1 个单位的费用?因为我什至不是这个网站的成员,我也可以使用 https:// 请求。
猜你喜欢
  • 1970-01-01
  • 2016-07-09
  • 1970-01-01
  • 2014-07-06
  • 1970-01-01
  • 2016-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多