web-dev-qa-db-ja.com

WebSockets-PHP経由でJSONデータを送信する

PHPからwebsocket aws apiゲートウェイにfire-and-forgetリクエストを送信しようとしています。

「sendmessage」というアクションを設定しました。

これは私が使用しているコードです:

$protocol = "ssl";
$Host = "<myendpoint>.amazonaws.com";
$port = 443;
$path = "/<mystage>/";
$timeout = 2000;

$socket = pfsockopen($protocol . "://" . $Host, $port,
                    $errno, $errstr, $timeout);

$content = "{'action': 'sendmessage', 'data': 'test'}";
$body = "POST $path HTTP/1.1\r\n";
$body .= "Host: $Host\r\n";
$body .= "Content-Type: application/json\r\n";
$body .= "Content-Length: " . strlen($content) . "\r\n";
$body .= "Connection: Close\r\n\r\n";
$body .= $content;
$body .= "\r\n";

fwrite($socket, $body);

ただし、何も起こりません。

私がwscatを使用する場合、次のようになります:

wscat -c wss://<my-endpoint>.amazonaws.com/<my-stage>

> {'action': 'sendmessage', 'data': 'test'}
>

それはうまくいきます。

私のphpコードで何が間違っていますか?

注:永続的なソケット接続が必要です(pfsockopen関数を使用する場合の方法)。

7
OhMad

おそらく次のようにhttp_build_query();関数を使用する必要があります。

$content = http_build_query($content);

フォームポストを使用してメッセージを送信するため、次のコードを試してソケット接続が成功したかどうかを確認します。おそらくコードが間違っているpfsockopen()@fsockopen()である必要があります

必要に応じてこれを編集します。

$protocol = "ssl";
$Host = "<myendpoint>.amazonaws.com";
$port = 443;
$path = "/<mystage>/";
$timeout = 2000;

$socket = @fsockopen($protocol . "://" . $Host, $port,
            $errno, $errstr, $timeout);

if($socket === false) { return false; };

$content = "{'action': 'sendmessage', 'data': 'test'}";
$body  = "POST $path HTTP/1.1\r\n";
$body .= "Host: $Host\r\n";
$body .= "Referer: yourClass (v.".version() .")\r\n";
$body .= "Content-type: application/json\r\n";
$body .= "Content-Length: ".strlen($content)."\r\n";
$body .= "Connection: Close\r\n\r\n";
$body .= "$content";
fwrite($socket, $body);
fclose($socket);

このコードは私のサイトで関数としてうまく機能します

$ out。= "コンテンツタイプ:application/x-www-form-urlencoded\r\n"; jsonの代わりに

function flexy_Request($url, $_data) {
    // parse the given URL
    $url = parse_url($url);
    if ($url === false || !isset($url['Host']) || !isset($url['path'])) {
        return false;
    }
    // extract Host and path:
    $Host = $url['Host'];
    $path = $url['path'];
    // open a socket connection on port 80
    // use localhost in case of issues with NATs (hairpinning)
    $fp = @fsockopen($Host, 80);

    if($fp===false) { return false; };

    $data = http_build_query($_data);
    $out  = "POST $path HTTP/1.1\r\n";
    $out .= "Host: $Host\r\n";
    $out .= "Referer: Myclass (v.". flexy_version() .")\r\n";
    $out .= "Content-type: application/json\r\n";
    $out .= "Content-Length: ".strlen($data)."\r\n";
    $out .= "Connection: Close\r\n\r\n";
    $out .= "$data";
    $number_bytes_sent = fwrite($fp, $out);
    fclose($fp);
    return $number_bytes_sent; // or false on fwrite() error
}
0
Dlk

PHP websocketクライアントを要件に使用する必要があります。以下は、要件に使用できるクライアントの1つです。

https://github.com/paragi/PHP-websocket-client

サンプル1:

if( $sp = websocket_open('echo.websocket.org',80) ) {
  websocket_write($sp,"hello server");
  echo "Server responed with: " . websocket_read($sp,$errstr);
}

サンプル2:

$headers = ["Cookie: SID=".session_id()];
$sp = websocket_open('echo.websocket.org',80,$headers,$errstr,16);
if($sp){
   $bytes_written = websocket_write($sp,"hello server");
   if($bytes_written){
     $data = websocket_read($sp,$errstr);
     echo "Server responed with: " . $errstr ? $errstr : $data;
   }
}

お役に立てれば。

0
Parth Mehta