1

これは私が扱ってきた古い問題であり、まだ解決策がないので、新しいアプローチを試してみてください。

どうすればSOAP応答を早期に(スクリプトの実行が終了する前に)送信できますか?

これらの問題は、プロセスが割り当てられた時間よりも完了するのに時間がかかるため、ACKファイルが30秒前に送信されない場合に発生します。

flush()が機能しない場合、次のエラーが発生します:

org.xml.sax.SAXParseException:XMLドキュメント構造は、同じエンティティ内で開始および終了する必要があります。

flash()なしでこれを取得します

org.xml.sax.SAXParseException:ファイルの終わりが早すぎます。

スクリプトプロセスが完了するまでに180秒以上かかる場合があり、応答を待機しているサーバーは、タイムアウトする前に約30秒だけ待機します(これにより、上記のエラーが発生します)。

これを修正する方法について何か考えはありますか?

コードの一部を次に示します。これは、次のSOAPリクエストのACKファイルを受け入れて送信する方法です。

$data = 'php://input';
$content = file_get_contents($data);

if($content) {
    respond('true');
} else {
    respond('false');
}

応答機能

function respond($tf) {
    $ACK = <<<ACK
<?xml version = "1.0" encoding = "utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Body>
        <notifications xmlns="http://soap.sforce.com/2005/09/outbound">
            <Ack>$tf</Ack>
        </notifications>
    </soapenv:Body>
</soapenv:Envelope>
ACK;

    print trim($ACK); 
}

PHPはシングルスレッド処理アプローチを使用しており、スレッドが処理を完了するまでACKファイルを送り返しません。ACK送信後にソケットを閉じて処理を続行し、送信サーバーでこれらのタイムアウトの問題が発生しないようにする方法はありますか?

4

2 に答える 2

1

私の知る限り、30 秒の制限については何もできず、スクリプトが終了する前に出力がフラッシュされることはありません。処理ロジックを 2 つに分割してみてください。

  1. メッセージを受け取り、実行するジョブをログに記録し、即座に ACK を送信して終了する「リスナー」スクリプト。
  2. お客様側での実際の処理には時間がかかる場合があります。

「実行するジョブ」は、新しく生成されたプロセス ( pcntl_fork()関数のコメントを確認してください。ただし、私にはあまり期待できません)、またはデータをファイルまたはデータベースに保存して定期的に処理する何らかの方法である可能性があります。たとえば、5分ごとに実行するようにスケジュールされた別のスクリプトを使用しますか?

60 秒で解決できる場合は、送信メッセージを Apex からのコールアウトに書き直すことができます。基本的には、独自の SOAP エンベロープを作成し、それを任意の http アドレスに送信します。トリガーに入れることができます。ただし、このアプローチの制限については、こちらを参照してください。


その他の暴言:

  1. あなたのACKがセールスフォースにとって本当に「重要」だとは思いません。送信メッセージは単なる通知です。アプリケーションのどこかで Ack = true/false に依存していますか? そうでない場合 - やみくもに ack=true を送信し、ジョブをスケジュールするリスナーが本当に良い方法かもしれません;)
  2. 他の質問から、基本的には更新をDBに保存するだけでよいことがわかりました。監査目的で OM を使用するべきではないことを理解していますよね? (リンク、「監査」を検索)。
  3. PHP をアクティブ側にする方が簡単ではないでしょうか? Salesforce に [SELECT Id, Name FROM Account WHERE LastModifiedDate > :lastTimeYouQueried] をクエリさせますか? そうすれば、結果を処理するために常に時間をかけることができます:)
于 2010-06-28T19:31:49.113 に答える
1

a) (オプション) set_time_limit() を使用して、実行時間の制限時間を増やすことができます。

b) 次のように、wsdl クライアント オブジェクトまでの時間を増やす必要があります。

$clientwsdl->setOpt('timeout', 300); // if you are using PEAR:SOAP.

ほとんどの wsdl クラスでは、タイムアウトを定義できます。

c) そうではなく、少なくとも 1 つの呼び出しを使用して、SOAP を使用して早期に応答することはできません。SOAP が XML を返すことを考慮してください。そのため、部分的な XML は通常無効です (終了タグがありません)。

d) 別の方法として、URL の読み取りなど、SOAP 以外の方法を使用することもできます。

$fp=fopen("http://www.mysite.com/url.php","r");

url.php は列 (または xml を使用しない何らかの値を返します:

30|50|70|80|20 
30|50|70|80|20
30|50|70|80|20
于 2010-06-28T15:36:19.573 に答える