Я читал о Челюсти: потоковая передача данных клиенту . Я создал простой пример, показанный ниже, но он не работает. Я получаю сообщение об ошибке, и процесс умирает.
Вот мой файл зевков:
<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
Вот код клиента JavaScript, который я использую (работает только с IE8 и IE9), используя XDomainRequest :
<!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 прелюдия , но его следует отправлять, как я понимаю.
Обновление
После исправления проблем Эрланга, указанных Стивом Виноски, и удаления \r\n
в моих данных, сервер Yaws отправляет правильные данные. Но я все еще получаю xdr.onerror = function()
ошибку на клиенте JavaScript. И кажется, что мне нужно добавить еще один заголовок к ответу Access-Control-Allow-Origin: *
, как описано в XDomainRequest Object :
Документ запросит данные с сервера домена, отправив заголовок Origin со значением источника. Соединение будет завершено, только если сервер ответит заголовком Access-Control-Allow-Origin либо *, либо точным URL-адресом запрашивающего документа. Такое поведение является частью черновой структуры рабочей группы по веб-приложениям, разработанной Консорциумом всемирной паутины (W3C) по междоменной связи на стороне клиента, с которой интегрируется объект XDomainRequest.
Как добавить этот заголовок в ответ HTTP? Похоже, я могу только установить тип MIME в возвращаемом значении: {streamcontent, MimeType, FirstChunk}
?