diff --git a/docs/TODO b/docs/TODO index 2736bea..cdf0c41 100644 --- a/docs/TODO +++ b/docs/TODO @@ -1,7 +1,5 @@ - wstelnet: support CSI L and CSI M -- mod_websockify module for Apache - - create gevent version: http://nichol.as/benchmark-of-python-web-servers http://n01se.net/paste/QXO diff --git a/docs/latency_results.txt b/docs/latency_results.txt index a5932e6..4fc4b97 100644 --- a/docs/latency_results.txt +++ b/docs/latency_results.txt @@ -16,6 +16,14 @@ firefox 4.0b9 - WebSockets enabled Minimum Latency: 5.00 Maximum Latency: 119.00 +Opera 11 - WebSockets enabled + Packets sent: 3065 + Packets Received: 3064 + Average Latency: 9.56 + 40 Frame Running Average Latency: 8.15 + Minimum Latency: 4.00 + Maximum Latency: 53.00 + --- firefox 4.0b9 - no WebSockets diff --git a/include/websock.js b/include/websock.js index 4901faf..b9f52d7 100644 --- a/include/websock.js +++ b/include/websock.js @@ -169,7 +169,7 @@ function flush() { if (websocket.bufferedAmount !== 0) { Util.Debug("bufferedAmount: " + websocket.bufferedAmount); } - if (websocket.bufferedAmount < 1000) { + if (websocket.bufferedAmount < api.maxBufferedAmount) { //Util.Debug("arr: " + arr); //Util.Debug("sQ: " + sQ); if (sQ) { @@ -281,6 +281,9 @@ function close() { } function constructor() { + // Configuration settings + api.maxBufferedAmount = 200; + // Direct access to send and receive queues api.get_sQ = get_sQ; api.get_rQ = get_rQ; diff --git a/include/wsirc.js b/include/wsirc.js new file mode 100644 index 0000000..bef8f8d --- /dev/null +++ b/include/wsirc.js @@ -0,0 +1,235 @@ +/* + * WebSockets IRC client + * Copyright (C) 2011 Joel Martin + * Licensed under LGPL-3 (see LICENSE.txt) + * + * Includes VT100.js from: + * http://code.google.com/p/sshconsole + * Which was modified from: + * http://fzort.org/bi/o.php#vt100_js + + * IRC Client protocol: + * http://www.faqs.org/rfcs/rfc2812.html + */ + + +function IRC(target, connect_callback, disconnect_callback) { + +var that = {}, // Public API interface + vt100, ws, sQ = [], + state = "unconnected", + irc_nick, irc_channel, + termType = "VT100"; + + +Array.prototype.pushStr = function (str) { + var n = str.length; + for (var i=0; i < n; i++) { + this.push(str.charCodeAt(i)); + } +} + +function do_send() { + if (sQ.length > 0) { + Util.Debug("Sending " + sQ); + ws.send(sQ); + sQ = []; + } +} + +function do_recv() { + console.log(">> do_recv"); + var rQ, rQi, i; + + while (ws.rQlen() > 1) { + rQ = ws.get_rQ(); + rQi = ws.get_rQi(); + for (i = rQi; i < rQ.length; i++) { + if (rQ[i] === 10) { + break; + } + } + if (i >= rQ.length) { + // No line break found + break; + } + recvMsg(ws.rQshiftStr((i-rQi) + 1)); + } + //console.log("<< do_recv"); +} + +// Handle an IRC message +function recvMsg(msg) { + Util.Debug(">> recvMsg('" + msg + "')"); + + var tokens = msg.split(' '), in_params = true, + prefix, command, params = [], trailing = []; + + Util.Info(" tokens: " + tokens); + + if (tokens[0].charAt(0) === ":") { + prefix = tokens.shift(); + } + + command = tokens.shift(); + + while (tokens.length > 0) { + if (tokens[0].charAt(0) === ":") { + in_params = false; + } + if (in_params) { + params.push(tokens.shift()); + } else { + trailing.push(tokens.shift()); + } + } + + Util.Info(" prefix: " + prefix); + Util.Info(" command: " + command); + Util.Info(" params: " + params); + Util.Info(" trailing: " + trailing); + + // Show raw received + vt100.write(msg); + + switch (command) { + case "004": + state = "registered"; + vt100.write("Joining channel #" + irc_channel); + sendCmd("JOIN #" + irc_channel); + break; + case "JOIN": + state = "joined"; + vt100.write("Joined channel #" + irc_channel); + break; + + } + + Util.Debug("<< recvMsg('" + msg + "')"); +} + +function sendCmd(msg) { + Util.Info("Sending: " + msg); + sQ.pushStr(msg + "\r\n"); + do_send(); +} + +that.sendMsg = function(msg) { + // TODO parse into message + sendCmd("PRIVMSG #" + irc_channel + " :" + msg); +} + + +that.connect = function(host, port, encrypt, nick, channel) { + var host = host, + port = port, + scheme = "ws://", uri; + + irc_nick = nick; + irc_channel = channel; + + Util.Debug(">> connect"); + if ((!host) || (!port)) { + alert("must set host and port"); + return false; + } + + if (ws) { + ws.close(); + } + + if (encrypt) { + scheme = "wss://"; + } + uri = scheme + host + ":" + port; + Util.Info("connecting to " + uri); + + ws.open(uri); + + Util.Debug("<< connect"); + + return true; +} + +that.disconnect = function() { + Util.Debug(">> disconnect"); + if (ws) { + ws.close(); + } + + disconnect_callback(); + Util.Debug("<< disconnect"); +} + + +function constructor() { + /* Initialize Websock object */ + ws = new Websock(); + + ws.on('message', do_recv); + ws.on('open', function(e) { + Util.Info(">> WebSockets.onopen"); + // Send registration commands + state = "connected"; + sendCmd("NICK " + irc_nick); + // TODO: how to determine this? + sendCmd("USER joelm 0 * :Joel Martin"); + connect_callback(); + Util.Info("<< WebSockets.onopen"); + }); + ws.on('close', function(e) { + Util.Info(">> WebSockets.onclose"); + that.disconnect(); + Util.Info("<< WebSockets.onclose"); + }); + ws.on('error', function(e) { + Util.Info(">> WebSockets.onerror"); + that.disconnect(); + Util.Info("<< WebSockets.onerror"); + }); + + /* Initialize the terminal emulator/renderer */ + + vt100 = new VT100(80, 24, target); + + // Show cursor + vt100.curs_set(true, false); + + /* + * Override VT100 I/O routines + */ + + // Set handler for sending characters + vt100.getch( + function send_chr(chr, vt) { + var i; + Util.Debug(">> send_chr: " + chr); + for (i = 0; i < chr.length; i++) { + sQ.push(chr.charCodeAt(i)); + } + do_send(); + vt100.getch(send_chr); + } + ); + + vt100.debug = function(message) { + Util.Debug(message + "\n"); + } + + vt100.warn = function(message) { + Util.Warn(message + "\n"); + } + + vt100.curs_set = function(vis, grab, eventist) + { + this.debug("curs_set:: vis: " + vis + ", grab: " + grab); + if (vis !== undefined) + this.cursor_vis_ = (vis > 0); + } + + return that; +} + +return constructor(); // Return the public API interface + +} // End of Telnet() diff --git a/tests/latency.html b/tests/latency.html index aedecf5..4112ae8 100644 --- a/tests/latency.html +++ b/tests/latency.html @@ -5,6 +5,7 @@ + + + + + + + + + Host:   + Port:   + Encrypt:   + +
+ Nick:   +
+ Channel: #  + +

+ +
+ > + + + + + + +