comparison rlgterm.js @ 105:a9371002aecc

RLG-Web client: use WebSockets for game lists. Use the WebSocket connection to /status to create the list of current games.
author John "Elwin" Edwards <elwin@sdf.org>
date Sat, 14 Jul 2012 09:46:26 -0700
parents e59d68082664
children dc1414faee19
comparison
equal deleted inserted replaced
104:7d444ba4739e 105:a9371002aecc
73 "name": "Super-Rogue", 73 "name": "Super-Rogue",
74 "uname": "srogue" 74 "uname": "srogue"
75 } 75 }
76 }; 76 };
77 77
78 var wsHost = "localhost:8080";
79
78 var session = { 80 var session = {
79 /* The session id assigned by the server. */ 81 /* The session id assigned by the server. */
80 id: null, 82 id: null,
81 /* Login name and key */ 83 /* Login name and key */
82 lname: null, 84 lname: null,
89 91
90 /* The interval ID for checking the status of current games. */ 92 /* The interval ID for checking the status of current games. */
91 var statInterval = null; 93 var statInterval = null;
92 /* How frequently to check. */ 94 /* How frequently to check. */
93 var statDelta = 8000; 95 var statDelta = 8000;
96 /* A WebSocket to listen for status events. */
97 var statsock = null;
94 98
95 function writeData(hexstr) { 99 function writeData(hexstr) {
96 var codenum; 100 var codenum;
97 var codes = []; 101 var codes = [];
98 var nc; 102 var nc;
464 req.open('POST', '/login', true); 468 req.open('POST', '/login', true);
465 req.send(JSON.stringify(loginmsg)); 469 req.send(JSON.stringify(loginmsg));
466 return; 470 return;
467 } 471 }
468 472
473 function tableCurrent(gamelist) {
474 var gamediv = document.getElementById("gametable");
475 while (gamediv.children.length > 2)
476 gamediv.removeChild(gamediv.children[2]);
477 if (gamelist.length === 0) {
478 gamediv.style.display = "none";
479 document.getElementById("nogames").style.display = "block";
480 }
481 else {
482 gamediv.style.display = "table";
483 document.getElementById("nogames").style.display = "none";
484 }
485 for (var i = 0; i < gamelist.length; i++) {
486 var row = document.createElement("div");
487 var cell1 = document.createElement("div");
488 var cell2 = document.createElement("div");
489 var cell3 = document.createElement("div");
490 var cell4 = document.createElement("div");
491 cell1.appendChild(document.createTextNode(gamelist[i].p));
492 var uname = gamelist[i].g;
493 if (uname in games)
494 cell2.appendChild(document.createTextNode(games[uname].name));
495 else {
496 continue;
497 }
498 cell3.appendChild(document.createTextNode(idlestr(gamelist[i].i)));
499 var button = document.createElement("span");
500 button.appendChild(document.createTextNode("Watch"));
501 button.onclick = makeWatcher(gamelist[i].n);
502 button.className = "ibutton";
503 cell4.appendChild(button);
504 row.appendChild(cell1);
505 row.appendChild(cell2);
506 row.appendChild(cell3);
507 row.appendChild(cell4);
508 gamediv.appendChild(row);
509 }
510 }
511
512 /* Handles the status socket, opening and closing it when necessary. */
513 function wsCurrent() {
514 if (!WebSocket)
515 return;
516 if (session.id) {
517 /* Don't bother with status if already playing/watching. */
518 if (statsock) {
519 statsock.close();
520 statsock = null;
521 }
522 return;
523 }
524 if (statsock)
525 return;
526 statsock = new WebSocket("ws://" + wsHost + "/status");
527 statsock.onmessage = function (ev) {
528 var msg;
529 try {
530 msg = JSON.parse(ev.data);
531 } catch (e) {
532 if (e instanceof SyntaxError)
533 return;
534 }
535 if (msg.t != "t") {
536 return;
537 }
538 tableCurrent(msg.g);
539 };
540 statsock.onclose = function (ev) {
541 statsock = null;
542 }
543 }
544
469 function getcurrent(clear) { 545 function getcurrent(clear) {
470 if (session.id || clear) { 546 if (session.id || clear) {
471 if (statInterval) { 547 if (statInterval) {
472 window.clearInterval(statInterval); 548 window.clearInterval(statInterval);
473 statInterval = null; 549 statInterval = null;
474 } 550 }
475 return; 551 return;
476 } 552 }
477 if (!statInterval) { 553 if (!statInterval) {
478 statInterval = window.setInterval(getcurrent, statDelta); 554 statInterval = window.setInterval(getcurrent, statDelta);
555 }
556 if (session.lcred)
557 getchoices();
558 if (WebSocket) {
559 return;
479 } 560 }
480 var req = new XMLHttpRequest(); 561 var req = new XMLHttpRequest();
481 req.onerror = errHandler; 562 req.onerror = errHandler;
482 req.onreadystatechange = function () { 563 req.onreadystatechange = function () {
483 if (req.readyState != 4 || req.status != 200) 564 if (req.readyState != 4 || req.status != 200)
490 return; 571 return;
491 } 572 }
492 if (!reply.s) { 573 if (!reply.s) {
493 return; 574 return;
494 } 575 }
495 var gamediv = document.getElementById("gametable"); 576 tableCurrent(reply.g);
496 while (gamediv.children.length > 2)
497 gamediv.removeChild(gamediv.children[2]);
498 if (reply.g.length === 0) {
499 gamediv.style.display = "none";
500 document.getElementById("nogames").style.display = "block";
501 }
502 else {
503 gamediv.style.display = "table";
504 document.getElementById("nogames").style.display = "none";
505 }
506 for (var i = 0; i < reply.g.length; i++) {
507 var row = document.createElement("div");
508 var cell1 = document.createElement("div");
509 var cell2 = document.createElement("div");
510 var cell3 = document.createElement("div");
511 var cell4 = document.createElement("div");
512 cell1.appendChild(document.createTextNode(reply.g[i].p));
513 var uname = reply.g[i].g;
514 if (uname in games)
515 cell2.appendChild(document.createTextNode(games[uname].name));
516 else {
517 debug(1, "Unrecognized game: " + uname);
518 continue;
519 }
520 cell3.appendChild(document.createTextNode(idlestr(reply.g[i].i)));
521 var button = document.createElement("span");
522 button.appendChild(document.createTextNode("Watch"));
523 button.onclick = makeWatcher(reply.g[i].n);
524 button.className = "ibutton";
525 cell4.appendChild(button);
526 row.appendChild(cell1);
527 row.appendChild(cell2);
528 row.appendChild(cell3);
529 row.appendChild(cell4);
530 gamediv.appendChild(row);
531 }
532 }; 577 };
533 req.open('GET', '/status', true); 578 req.open('GET', '/status', true);
534 req.send(); 579 req.send();
535 if (session.lcred)
536 getchoices();
537 return; 580 return;
538 } 581 }
539 582
540 function getchoices() { 583 function getchoices() {
541 if (session.id != null || !session.lcred) 584 if (session.id != null || !session.lcred)
697 } 740 }
698 return watcher; 741 return watcher;
699 } 742 }
700 743
701 function wsWatch(gamenumber) { 744 function wsWatch(gamenumber) {
702 var sockurl = "ws://localhost:8080/watch/" + String(gamenumber); 745 var sockurl = "ws://" + wsHost + "/watch/" + String(gamenumber);
703 var ws = new WebSocket(sockurl); 746 var ws = new WebSocket(sockurl);
704 ws.onopen = function (event) { 747 ws.onopen = function (event) {
705 session.id = true; 748 session.id = true;
706 session.sock = ws; 749 session.sock = ws;
707 setmode("watch"); 750 setmode("watch");
869 document.getElementById("startgame").style.display = "none"; 912 document.getElementById("startgame").style.display = "none";
870 document.getElementById("login").style.display = "none"; 913 document.getElementById("login").style.display = "none";
871 document.getElementById("register").style.display = "block"; 914 document.getElementById("register").style.display = "block";
872 document.getElementById("current").style.display = "none"; 915 document.getElementById("current").style.display = "none";
873 } 916 }
917 wsCurrent();
874 } 918 }
875 919
876 function toggleBlock(id) { 920 function toggleBlock(id) {
877 var element = document.getElementById(id); 921 var element = document.getElementById(id);
878 if (!element) 922 if (!element)