2

次のような非同期接続が失敗した場合に、エラー情報(Cのgetsockopt SO_ERRORなど)を取得できるかどうかは誰でも知っています。ソケット拡張を使用していない場合、ストリームはsslラッパーを提供します。

<?php
$ctx = stream_context_create();
stream_context_set_params($ctx, array("notification" => "stream_notification_callback"));
$destination = "tcp://92.247.12.242:8081";
$socket = stream_socket_client($destination, $errno, $errstr,
                                         10, STREAM_CLIENT_CONNECT | STREAM_CLIENT_ASYNC_CONNECT, $ctx);a
// plain socket
var_dump($socket);
// no error as expected
var_dump($errno);
var_dump($errstr);

stream_set_blocking($socket, false);

/* Prepare the read array */
$read   = array($socket);
$write  = array($socket);
$except = NULL;
if (false === ($num_changed_streams = stream_select($read, $write, $except, 10))) {
    var_dump("select failed?");
    /* Error handling */
} elseif ($num_changed_streams > 0) {

    /* At least on one of the streams something interesting happened */
    var_dump("event");
    // read fails, so the connect fails but why?
    $result = stream_socket_recvfrom($socket, 1024);
    var_dump($result);
    // no error again
    var_dump($errno);
    var_dump($errstr);
    // nothing interesting
    var_dump(stream_get_meta_data($socket));
}
// wont get called
function stream_notification_callback($notification_code, $severity, $message, $message_code, $bytes_transferred, $bytes_max) {
    $args = func_get_args();
    var_dump($args);
}

どうも

4

3 に答える 3

1

説明と同じ問題が発生しています。私は少し回避策を見つけました:

各「ストリーム」をクラスでラップしStream、タイムアウトプロパティを設定します。connectを呼び出す前に、タイムアウトが発生するタイミングのタイムスタンプを生成します。Manager次に、を呼び出すクラスにループがありますstream_select()

成功した接続は$writeアレイに配置されます。ループの下部に、を呼び出す別の呼び出しがあります$stream->checkTimeout()。その中に、stream_select()とに0が設定された呼び出しがtv_secありtv_usecます。$ this-> connが内に表示されない場合$writeは、タイムアウトしたと考えられます。

于 2010-11-06T18:29:23.073 に答える
0

私が理解している限り、ストリーム関数のエラーはPHP警告メッセージを生成するはずです。唯一の方法は、set_error_handler()を使用してこれらをトラップし、そこで処理することだと思います。

于 2010-07-26T13:25:29.483 に答える
0

私もこの問題に遭遇しました。私が見つけた解決策は、stream_socket_get_nameを使用することです。これをすべて素敵なライブラリチェックアウトhttp://drupal.org/project/httprlにまとめたい場合。それでもdrupalが必要ですが、主に設定とエラー処理のためです。コードを少し変更することができ、それはそれ自体で実行されるはずです。

于 2012-02-22T01:01:51.117 に答える