-1

Yaws:クライアントへのデータのストリーミングについて読みました。以下に示す簡単な例を作成しましたが、機能しません。エラーが発生し、プロセスが終了します。

これが私のyawsファイルです:

<erl>
out(A) ->
    Self = self(),  
    spawn(fun() ->
        yaws_api:stream_chunk_deliver_blocking(Self, "Hello"),
        yaws_api:stream_chunk_end(Self, "Thanks"),
        exit(normal)
    end),
    {streamcontent, "text/html; charset=utf-8", "First\r\n"}.
</erl>

私も試してみましyaws_api:stream_chunk_deliver/2たが、同じエラーが発生しました。コマンドプロンプトに表示されるエラーメッセージは次のとおりです。

=ERROR REPORT==== 13-Feb-2012::09:23:30 ===
Error in process <0.117.0> with exit value: {undef,[{yaws_api,stream_chunk_end,[
\n"],[]}]}"Thanks

1>
=ERROR REPORT==== 13-Feb-2012::09:24:00 ===
Yaws process died: {stream_timeout,
                       [{yaws_server,stream_loop_send,5,
                            [{file,"yaws_server.erl"},{line,2821}]},
                        {yaws_server,aloop,3,
                            [{file,"yaws_server.erl"},{line,1167}]},
                        {yaws_server,acceptor0,2,
                            [{file,"yaws_server.erl"},{line,1025}]},
                        {proc_lib,init_p_do_apply,3,
                            [{file,"proc_lib.erl"},{line,227}]}]}
1>

最後のチャンクはクライアントに送信されていないようです:

HTTP/1.1 200 OK
Server: Yaws 1.92
Date: Mon, 13 Feb 2012 07:31:18 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked

7
First

7
Hello

XDomainRequestを使用して使用するJavaScriptクライアントコード(IE8およびIE9でのみ機能)は次のとおりです。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<script>
window.onload = function() {
    var el = document.getElementById("requestbutton");
    if(el.attachEvent) {
        el.attachEvent('onclick', doXDR);
    }
}

function writeStatus(message) {
    var html = document.createElement("div");
    html.setAttribute("class", "message");
    html.innerHTML = message;
    document.getElementById("status").appendChild(html);
}

function doXDR() {
    if(!window.XDomainRequest) {
        writeStatus("No XDR support in your browser");
        return;
    }

    writeStatus("Beginning XDR");
    try {
        var xdr = new XDomainRequest();
        xdr.open("GET", "http://localhost:8090/stream.yaws");
        xdr.send();
        xdr.onload = function() {
            writeStatus("XDR response: " + xdr.responseText);
        };
        xdr.onerror = function() {
            writeStatus("XDR error");
        };
        xdr.onprogress = function() {
            writeStatus("XDR intermediate: " + xdr.responseText);
        };
    } catch (e) {
        writeStatus("XDR Exception: " + e);
    }
}
</script>
</head>
<body>
<h1>Test page</h1>
<button id="requestbutton">Send request</button><br>
<div id="status"></div>
</body>
</html>

JavaScriptクライアントでは、xdr.onerror = function()メソッドが呼び出されます。この例では、2kのプレリュードが必要なため、クライアントはデータを表示しないはずですが、私が理解しているように、データを送信する必要があります。


アップデート

Steve Vinoskiによって指摘されたErlangの問題を修正し\r\n、私のデータを削除した後、Yawsサーバーは正しいデータを送信します。しかしxdr.onerror = function()、JavaScriptクライアントでエラーが発生します。そして、 XDomainRequest ObjectAccess-Control-Allow-Origin: *に記載されているように、応答に別のヘッダーを追加する必要があるようです。

ドキュメントは、originの値を含むOriginヘッダーを送信することにより、ドメインのサーバーにデータを要求します。サーバーが*または要求元のドキュメントの正確なURLのいずれかのAccess-Control-Allow-Originヘッダーで応答した場合にのみ、接続が完了します。この動作は、XDomainRequestオブジェクトが統合されるクライアント側のクロスドメイン通信に関するWorld Wide Webコンソーシアム(W3C)のWebアプリケーションワーキンググループのドラフトフレームワークの一部です。

このヘッダーをHTTP応答に追加するにはどうすればよいですか?戻り値にMIMEタイプしか設定できないよう{streamcontent, MimeType, FirstChunk}です。

4

1 に答える 1

3

undef上に示したようなエラーが表示されたときはいつでも:

Error in process <0.117.0> with exit value: {undef,[{yaws_api,stream_chunk_end,

これは、ロードパス上にないモジュール内の関数を呼び出しているか、存在しない関数を呼び出していることを意味します。あなたのコードではyaws_api:stream_chunK_end/2、存在しないを呼び出しています。代わりに必要なのはですyaws_api:stream_chunk_end/1。コードを次のように変更します。

<erl>
  out(A) ->
    Self = self(),  
      spawn(fun() ->
        yaws_api:stream_chunk_deliver_blocking(Self, "Hello\r\n"),
        yaws_api:stream_chunk_deliver_blocking(Self, "Thanks\r\n"),
        yaws_api:stream_chunk_end(Self),
        exit(normal)
      end),
    {streamcontent, "text/html; charset=utf-8", "First\r\n"}.
</erl>

そして、あなたの例はうまくいくと思います。

アップデート:

質問の新しい部分に答えるには、単一のタプルではなくリストの戻り値を使用して、streamcontentタプルがリストの最後にあることを確認します。

[{header, {"Access-Control-Allow-Origin", "*"}},
 {streamcontent, "text/html; charset=utf-8", "First"}].
于 2012-02-13T15:35:20.517 に答える