From: Scott Worley Date: Mon, 30 Jul 2012 03:58:58 +0000 (-0700) Subject: Bidirectional communication! X-Git-Url: http://git.scottworley.com/reliable-chat/commitdiff_plain/f0e385c76e0529768ad9339a4ddf1467bbb38453?ds=inline Bidirectional communication! This is actually pretty awful. In order to fetch _data_ cross-origin, I have to run foreign _code_ and have it window.parent.postMessage(). This seems really, really wrong. --- diff --git a/server/server.go b/server/server.go index 8ce9678..5c5ef50 100644 --- a/server/server.go +++ b/server/server.go @@ -95,6 +95,48 @@ func start_store() Store { return store } +const frame_html = ` + + + + + + + + +` + func start_server(store Store) { http.HandleFunc("/fetch", func(w http.ResponseWriter, r *http.Request) { var since time.Time @@ -128,6 +170,10 @@ func start_server(store Store) { r.FormValue("text")} }) + http.HandleFunc("/frame", func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(frame_html)); + }) + log.Fatal(http.ListenAndServe(":"+strconv.Itoa(*port), nil)) } diff --git a/webclient/rc.css b/webclient/rc.css index c878e19..9459fa8 100644 --- a/webclient/rc.css +++ b/webclient/rc.css @@ -3,3 +3,7 @@ html, body, #outer-table, #history { width: 99.9%; height: 100%; margin: 0; padd #say { width: 100% } #history { vertical-align: bottom } img { width: 1px; height: 1px; } +iframe { display: none } +#status span { margin-right: 2em } +#status span.sad { background-color: #fee } +#status span.happy { background-color: #efe } diff --git a/webclient/rc.html b/webclient/rc.html index bc38d0b..7430f3e 100644 --- a/webclient/rc.html +++ b/webclient/rc.html @@ -8,7 +8,7 @@ - + diff --git a/webclient/rc.js b/webclient/rc.js index 8e565c5..6dc527e 100644 --- a/webclient/rc.js +++ b/webclient/rc.js @@ -1,23 +1,72 @@ -var servers = ['chkno.net', 'localhost'] +var servers = ['chkno.net', 'localhost']; var session = Math.random(); +var seen = {}; -function addport(server) { +function rcserverbase(server) { // Add the default port if server doesn't contain a port number already if (server.indexOf(":") == -1) { - return server + ":21059"; + return "http://" + server + ":21059"; } else { - return server; + return "http://" + server; + } +} + +function rcaddmessagetohistory(message) { + var d = document.createElement("div"); + d.appendChild(document.createTextNode(message)); + var h = document.getElementById("history"); + h.appendChild(d); + window.scrollTo(0, document.body.scrollHeight); + return d; +} + +function make_seen_key(id, text) { + return id.replace(/@/g, "@@") + "_@_" + text.replace(/@/g, "@@"); +} + +function receiveMessage(server, time, id, text) { + var seen_key = make_seen_key(id, text); + if (!(seen_key in seen)) { + seen[seen_key] = true; + rcaddmessagetohistory(text); + } +} + +function receiveMessageEvent(event) +{ + for (i in servers) { + if (event.origin === rcserverbase(servers[i])) { + messages = JSON.parse(event.data); + for (j in messages) { + if ('Time' in messages[j] && + 'ID' in messages[j] && + 'Text' in messages[j]) { + receiveMessage(servers[i], messages[j]['Time'], messages[j]['ID'], messages[j]['Text']); + } + } + } + } +} + +function rcconnect() { + window.addEventListener("message", receiveMessageEvent, false); + for (i in servers) { + // Create a hidden iframe for same-origin workaround + var iframe = document.createElement("iframe"); + iframe.setAttribute("src", rcserverbase(servers[i]) + "/frame"); + document.body.insertBefore(iframe, document.body.firstChild); } } function rcsend(d, message) { var id = new Date().getTime() + "-" + session + "-" + Math.random(); + seen[make_seen_key(id, message)] = true; var path = "/speak" + "?id=" + encodeURIComponent(id) + "&text=" + encodeURIComponent(message); for (i in servers) { - var uri = "http://" + addport(servers[i]) + path; + var uri = rcserverbase(servers[i]) + path; var img = document.createElement("img"); img.setAttribute("src", uri); d.appendChild(img); @@ -26,11 +75,7 @@ function rcsend(d, message) { function rckeydown(event) { if (event.keyCode == 13) { - var d = document.createElement("div"); - d.appendChild(document.createTextNode(document.input.say.value)); - var h = document.getElementById("history"); - h.appendChild(d); - window.scrollTo(0, document.body.scrollHeight); + var d = rcaddmessagetohistory(document.input.say.value); rcsend(d, document.input.say.value); document.input.say.value = ""; return false;