Mercurial > hg > rlgwebd
comparison shterm.js @ 140:789c094675f4
WebTTY: use WebSockets when possible.
| author | John "Elwin" Edwards |
|---|---|
| date | Mon, 22 Jul 2013 07:51:53 -0700 |
| parents | a497ecd116d9 |
| children | c4a32007d2dc |
comparison
equal
deleted
inserted
replaced
| 139:dcd07c1d846a | 140:789c094675f4 |
|---|---|
| 4 | 4 |
| 5 var isalive = false; // Whether the session is currently active. | 5 var isalive = false; // Whether the session is currently active. |
| 6 var nsend = 0; // The number of the next packet to send. | 6 var nsend = 0; // The number of the next packet to send. |
| 7 var nrecv = 0; // The next packet expected. | 7 var nrecv = 0; // The next packet expected. |
| 8 var msgQ = []; // Queue for out-of-order messages. | 8 var msgQ = []; // Queue for out-of-order messages. |
| 9 var conn = null; // WebSocket | |
| 9 | 10 |
| 10 // A state machine that keeps track of polling the server. | 11 // A state machine that keeps track of polling the server. |
| 11 var ajaxstate = { | 12 var ajaxstate = { |
| 12 state: 0, | 13 state: 0, |
| 13 timerID: null, | 14 timerID: null, |
| 200 } | 201 } |
| 201 } | 202 } |
| 202 | 203 |
| 203 function sendback(str) { | 204 function sendback(str) { |
| 204 /* For responding to terminal queries. */ | 205 /* For responding to terminal queries. */ |
| 205 var formdata = {"t": "d", "n": nsend++, "d": str}; | 206 if (conn) { |
| 206 var datareq = new XMLHttpRequest(); | 207 var msgObj = {"t": "d", "d": str}; |
| 207 datareq.onreadystatechange = postResponseHandler; | 208 conn.send(JSON.stringify(msgObj)); |
| 208 datareq.open('POST', '/feed', true); | 209 } |
| 209 datareq.send(JSON.stringify(formdata)); | 210 else { |
| 211 var formdata = {"t": "d", "n": nsend++, "d": str}; | |
| 212 var datareq = new XMLHttpRequest(); | |
| 213 datareq.onreadystatechange = postResponseHandler; | |
| 214 datareq.open('POST', '/feed', true); | |
| 215 datareq.send(JSON.stringify(formdata)); | |
| 216 } | |
| 210 return; | 217 return; |
| 211 } | 218 } |
| 212 | 219 |
| 213 function sendkey(ev) { | 220 function sendkey(ev) { |
| 221 if (!isalive) | |
| 222 return; | |
| 214 var keynum = ev.keyCode; | 223 var keynum = ev.keyCode; |
| 215 var code; | 224 var code; |
| 216 if (keynum >= 65 && keynum <= 90) { | 225 if (keynum >= 65 && keynum <= 90) { |
| 217 /* Letters. */ | 226 /* Letters. */ |
| 218 if (ev.ctrlKey) | 227 if (ev.ctrlKey) |
| 243 } | 252 } |
| 244 else { | 253 else { |
| 245 debug(1, "Ignoring keycode " + keynum); | 254 debug(1, "Ignoring keycode " + keynum); |
| 246 return; | 255 return; |
| 247 } | 256 } |
| 248 if (isalive) | 257 ev.preventDefault(); |
| 249 ev.preventDefault(); | 258 if (conn) { |
| 250 var formdata = {"t": "d", "n": nsend++, "d": code}; | 259 var msgObj = {"t": "d", "d": code}; |
| 251 var datareq = new XMLHttpRequest(); | 260 conn.send(JSON.stringify(msgObj)); |
| 252 datareq.onreadystatechange = postResponseHandler; | 261 } |
| 253 datareq.open('POST', '/feed', true); | 262 else { |
| 254 datareq.send(JSON.stringify(formdata)); | 263 var formdata = {"t": "d", "n": nsend++, "d": code}; |
| 264 var datareq = new XMLHttpRequest(); | |
| 265 datareq.onreadystatechange = postResponseHandler; | |
| 266 datareq.open('POST', '/feed', true); | |
| 267 datareq.send(JSON.stringify(formdata)); | |
| 268 } | |
| 255 //dkey(code); | 269 //dkey(code); |
| 256 return; | 270 return; |
| 257 } | 271 } |
| 258 | 272 |
| 259 var charshifts = { '-': "5f", '=': "2b", '[': "7b", ']': "7d", '\\': "7c", | 273 var charshifts = { '-': "5f", '=': "2b", '[': "7b", ']': "7d", '\\': "7c", |
| 263 var kpkeys = { "KP1": "1b4f46", "KP2": "1b4f42", "KP3": "1b5b367e", | 277 var kpkeys = { "KP1": "1b4f46", "KP2": "1b4f42", "KP3": "1b5b367e", |
| 264 "KP4": "1b4f44", "KP5": "1b5b45", "KP6": "1b4f43", | 278 "KP4": "1b4f44", "KP5": "1b5b45", "KP6": "1b4f43", |
| 265 "KP7": "1b4f48", "KP8": "1b4f41", "KP9": "1b5b357e" }; | 279 "KP7": "1b4f48", "KP8": "1b4f41", "KP9": "1b5b357e" }; |
| 266 | 280 |
| 267 function vkey(c) { | 281 function vkey(c) { |
| 282 if (!isalive) | |
| 283 return; | |
| 268 var keystr; | 284 var keystr; |
| 269 if (c.match(/^[a-z]$/)) { | 285 if (c.match(/^[a-z]$/)) { |
| 270 if (termemu.ctrlp()) { | 286 if (termemu.ctrlp()) { |
| 271 var n = c.charCodeAt(0) - 96; | 287 var n = c.charCodeAt(0) - 96; |
| 272 keystr = n.toString(16); | 288 keystr = n.toString(16); |
| 302 keystr = kpkeys[c]; | 318 keystr = kpkeys[c]; |
| 303 } | 319 } |
| 304 else | 320 else |
| 305 return; | 321 return; |
| 306 //writeData("Sending " + keystr); | 322 //writeData("Sending " + keystr); |
| 307 var formdata = {"t": "d", "n": nsend++, "d": keystr}; | 323 if (conn) { |
| 308 var datareq = new XMLHttpRequest(); | 324 var msgObj = {"t": "d", "d": keystr}; |
| 309 datareq.onreadystatechange = postResponseHandler; | 325 conn.send(JSON.stringify(msgObj)); |
| 310 datareq.open('POST', '/feed', true); | 326 } |
| 311 datareq.send(JSON.stringify(formdata)); | 327 else { |
| 328 var formdata = {"t": "d", "n": nsend++, "d": keystr}; | |
| 329 var datareq = new XMLHttpRequest(); | |
| 330 datareq.onreadystatechange = postResponseHandler; | |
| 331 datareq.open('POST', '/feed', true); | |
| 332 datareq.send(JSON.stringify(formdata)); | |
| 333 } | |
| 312 return; | 334 return; |
| 313 } | 335 } |
| 314 | 336 |
| 315 function setup() { | 337 function setup() { |
| 316 keyHexCodes.init(); | 338 keyHexCodes.init(); |
| 337 else | 359 else |
| 338 keydiv.className = "key"; | 360 keydiv.className = "key"; |
| 339 return; | 361 return; |
| 340 } | 362 } |
| 341 | 363 |
| 364 function loginWS(h, w) { | |
| 365 if (conn) | |
| 366 return; | |
| 367 var sockurl = "ws://" + window.location.host + "/sock?w=" + w + "&h=" + h; | |
| 368 conn = new WebSocket(sockurl); | |
| 369 conn.onopen = function (event) { | |
| 370 isalive = true; | |
| 371 setTitle("Logged in"); | |
| 372 debug(1, "Logged in via WebSocket"); | |
| 373 } | |
| 374 conn.onmessage = function (event) { | |
| 375 var msgObj = JSON.parse(event.data); | |
| 376 if (msgObj.t == 'l') { | |
| 377 termemu.resize(msgObj.h, msgObj.w); | |
| 378 } | |
| 379 else if (msgObj.t == 'd') { | |
| 380 debug(0, msgObj.d); | |
| 381 writeData(msgObj.d); | |
| 382 } | |
| 383 else if (msgObj.t == 'q') { | |
| 384 debug(0, "Quit message!"); | |
| 385 conn.close(); | |
| 386 } | |
| 387 } | |
| 388 conn.onclose = function (event) { | |
| 389 conn = null; | |
| 390 isalive = false; | |
| 391 debug(1, "WebSocket connection closed."); | |
| 392 setTitle("Not connected."); | |
| 393 } | |
| 394 } | |
| 395 | |
| 342 function login(h, w) { | 396 function login(h, w) { |
| 343 if (isalive) | 397 if (isalive) |
| 344 return; | 398 return; |
| 399 if (window.WebSocket) { | |
| 400 loginWS(h, w); | |
| 401 return; | |
| 402 } | |
| 345 params = {"login": true, "h": h, "w": w}; | 403 params = {"login": true, "h": h, "w": w}; |
| 346 var req = new XMLHttpRequest(); | 404 var req = new XMLHttpRequest(); |
| 347 req.onreadystatechange = function () { | 405 req.onreadystatechange = function () { |
| 348 if (req.readyState == 4 && req.status == 200) { | 406 if (req.readyState == 4 && req.status == 200) { |
| 349 var logindict = JSON.parse(req.responseText); | 407 var logindict = JSON.parse(req.responseText); |
| 366 //req.send("login=login&h=" + String(h) + "&w=" + String(w)); | 424 //req.send("login=login&h=" + String(h) + "&w=" + String(w)); |
| 367 return; | 425 return; |
| 368 } | 426 } |
| 369 | 427 |
| 370 function stop() { | 428 function stop() { |
| 429 if (conn) { | |
| 430 conn.close(); | |
| 431 return; | |
| 432 } | |
| 371 var req = new XMLHttpRequest(); | 433 var req = new XMLHttpRequest(); |
| 372 req.onreadystatechange = function () { | 434 req.onreadystatechange = function () { |
| 373 if (req.readyState == 4 && req.status == 200) { | 435 if (req.readyState == 4 && req.status == 200) { |
| 374 /* Figure out whether or not it worked. */ | 436 /* Figure out whether or not it worked. */ |
| 375 /* FIXME the server might respond with output. */ | 437 /* FIXME the server might respond with output. */ |
