return store
}
+const frame_html = `<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+ "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <script type="text/javascript"><!--//--><![CDATA[//><!--
+ var since;
+ function go() {
+ var delay = 10000;
+ var xhr = new XMLHttpRequest();
+ xhr.onreadystatechange = function() {
+ if (this.readyState == this.DONE) {
+ if (this.status == 200) {
+ var rtxt = this.responseText;
+ if (rtxt != null) {
+ var r = JSON.parse(rtxt);
+ if (r != null) {
+ window.parent.postMessage(rtxt, "*");
+ delay = 40;
+ if (r.length >= 1 && "Time" in r[r.length-1]) {
+ since = r[r.length-1]["Time"];
+ }
+ }
+ }
+ }
+ window.setTimeout(go, delay);
+ }
+ }
+ var uri = "/fetch";
+ if (since) {
+ uri += '?since="' + since + '"';
+ }
+ xhr.open("GET", uri);
+ xhr.send();
+ }
+ //--><!]]></script>
+</head>
+<body onload="go()">
+</body>
+</html>
+`
+
func start_server(store Store) {
http.HandleFunc("/fetch", func(w http.ResponseWriter, r *http.Request) {
var since time.Time
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))
}
-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);
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;