Mercurial > urweb
changeset 1447:17393c5e2b90
Send newly created sources with messages to clients
author | Adam Chlipala <adam@chlipala.net> |
---|---|
date | Sat, 09 Apr 2011 20:00:52 -0400 |
parents | 36f7d1debb37 |
children | 37599e85bba8 |
files | lib/js/urweb.js src/c/http.c src/c/urweb.c tests/ms.ur tests/ms.urp tests/ms.urs |
diffstat | 6 files changed, 87 insertions(+), 27 deletions(-) [+] |
line wrap: on
line diff
--- a/lib/js/urweb.js Sat Apr 09 14:36:47 2011 -0400 +++ b/lib/js/urweb.js Sat Apr 09 20:00:52 2011 -0400 @@ -817,7 +817,7 @@ } catch (e) { } if (isok) { - var text = xhr.responseText + var text = xhr.responseText; if (text == "") return; var lines = text.split("\n"); @@ -827,36 +827,47 @@ return; } - for (var i = 0; i+1 < lines.length; i += 2) { - var chn = lines[i]; - var msg = lines[i+1]; + var messageReader = function(i) { + if (i+1 >= lines.length) { + xhrFinished(xhr); + connect(); + } + else { + var chn = lines[i]; + var msg = lines[i+1]; - if (chn < 0) - whine("Out-of-bounds channel in message from remote server"); + if (chn == "E") { + eval(msg); + window.setTimeout(function() { messageReader(i+2); }, 0); + } else { + if (chn < 0) + whine("Out-of-bounds channel in message from remote server"); - var ch; + var ch; - if (chn >= channels.length || channels[chn] == null) { - ch = newChannel(); - channels[chn] = ch; - } else - ch = channels[chn]; + if (chn >= channels.length || channels[chn] == null) { + ch = newChannel(); + channels[chn] = ch; + } else + ch = channels[chn]; - var listener = dequeue(ch.listeners); - if (listener == null) { - enqueue(ch.msgs, msg); - } else { - try { - listener(msg); - } catch (v) { - doExn(v); + var listener = dequeue(ch.listeners); + if (listener == null) { + enqueue(ch.msgs, msg); + } else { + try { + listener(msg); + } catch (v) { + doExn(v); + } + } + + messageReader(i+2); } } } - xhrFinished(xhr); - - connect(); + messageReader(0); } else { try {
--- a/src/c/http.c Sat Apr 09 14:36:47 2011 -0400 +++ b/src/c/http.c Sat Apr 09 20:00:52 2011 -0400 @@ -198,7 +198,7 @@ on_success, on_failure, NULL, log_error, log_debug, sock, uw_really_send, close); - uw_send(ctx, sock); + if (rr != KEEP_OPEN) uw_send(ctx, sock); if (rr == SERVED || rr == FAILED) close(sock);
--- a/src/c/urweb.c Sat Apr 09 14:36:47 2011 -0400 +++ b/src/c/urweb.c Sat Apr 09 20:00:52 2011 -0400 @@ -311,16 +311,25 @@ return ch; } -static void client_send(client *c, uw_buffer *msg) { +static void client_send(client *c, uw_buffer *msg, const char *script, int script_len) { pthread_mutex_lock(&c->lock); if (c->sock != -1) { c->send(c->sock, on_success, strlen(on_success)); c->send(c->sock, begin_msgs, sizeof(begin_msgs) - 1); + if (script_len > 0) { + c->send(c->sock, "E\n", 2); + c->send(c->sock, script, script_len); + c->send(c->sock, "\n", 1); + } c->send(c->sock, msg->start, uw_buffer_used(msg)); c->close(c->sock); c->sock = -1; - } else if (uw_buffer_append(&c->msgs, msg->start, uw_buffer_used(msg))) + } else if ((script_len > 0 + && (c->send(c->sock, "E\n", 2) + || c->send(c->sock, script, script_len) + || c->send(c->sock, "\n", 1))) + || uw_buffer_append(&c->msgs, msg->start, uw_buffer_used(msg))) fprintf(stderr, "Client message buffer size exceeded"); pthread_mutex_unlock(&c->lock); @@ -3167,7 +3176,7 @@ assert (c != NULL && c->mode == USED); - client_send(c, &d->msgs); + client_send(c, &d->msgs, ctx->script.start, uw_buffer_used(&ctx->script)); } if (ctx->client)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/ms.ur Sat Apr 09 20:00:52 2011 -0400 @@ -0,0 +1,35 @@ +table ms : {Client : client, Channel : channel xbody} + +val hitMe = + me <- self; + ch <- oneRowE1 (SELECT (ms.Channel) + FROM ms + WHERE ms.Client = {[me]}); + + s <- source 0; + send ch <xml> + <dyn signal={n <- signal s; return <xml>{[n]}</xml>}/> + <button value="Inc" onclick={n <- get s; set s (n + 1)}/> + </xml> + +fun main' () = + me <- self; + ch <- channel; + dml (INSERT INTO ms (Client, Channel) VALUES ({[me]}, {[ch]})); + + s <- source <xml/>; + + return <xml><body onload={let + fun loop () = + x <- recv ch; + set s x; + loop () + in + loop () + end}> + <button value="Another" onclick={rpc hitMe}/> + <dyn signal={signal s}/> + </body></xml> + +fun main () = + return <xml><body><form><submit action={main'}/></form></body></xml>