--- /dev/null
+package {
+
+import flash.events.*;
+import flash.external.*;
+import flash.utils.*;
+
+[Event(name="message", type="FABTestMessageEvent")]
+public class FABTest extends EventDispatcher {
+
+ private var main:FABTestMain;
+ private var intervalID:int;
+ private var seqCnt:int;
+
+ public function FABTest(main:FABTestMain) {
+ this.main = main;
+ ExternalInterface.call("console.log", "[FABTest] FABTest()");
+ }
+
+ public function start(eventDelay:int):void {
+ ExternalInterface.call("console.log", "[FABTest] start()");
+ seqCnt = 0;
+ intervalID = setInterval(sendEvent, eventDelay);
+ }
+
+ public function stop():void {
+ ExternalInterface.call("console.log", "[FABTest] stop()");
+ clearInterval(intervalID);
+ }
+
+ private function sendEvent():void {
+ //ExternalInterface.call("console.log", "[FABTest] sendEvent " + seqCnt);
+ dispatchEvent(new FABTestMessageEvent("message", encodeURIComponent(seqCnt.toString())));
+ seqCnt = seqCnt + 1;
+ }
+}
+
+}
--- /dev/null
+package {
+
+import flash.display.*;
+import flash.events.*;
+import bridge.FABridge;
+
+public class FABTestMain extends Sprite {
+
+ public function FABTestMain() {
+
+ // This is to avoid "You are trying to call recursively into the Flash Player ..."
+ // error which (I heard) happens when you pass bunch of messages.
+ // This workaround was written here:
+ // http://www.themorphicgroup.com/blog/2009/02/14/fabridge-error-you-are-trying-to-call-recursively-into-the-flash-player-which-is-not-allowed/
+ FABridge.EventsToCallLater["flash.events::Event"] = "true";
+ FABridge.EventsToCallLater["FABTestMessageEvent"] = "true";
+
+ var fab:FABridge = new FABridge();
+ fab.rootObject = this;
+ //log("Flash initialized");
+ }
+
+ public function create():FABTest {
+ return new FABTest(this);
+ }
+}
+
+}
--- /dev/null
+package {\r
+\r
+import flash.events.*;\r
+\r
+public class FABTestMessageEvent extends Event {\r
+ public var data:String;\r
+ \r
+ public function FABTestMessageEvent(type:String, data:String) {\r
+ super(type);\r
+ this.data = data;\r
+ }\r
+}\r
+\r
+}\r
--- /dev/null
+../../web-socket-js/flash-src/bridge/FABridge.as
\ No newline at end of file
--- /dev/null
+// Copyright: Hiroshi Ichikawa <http://gimite.net/en/>
+// Lincense: New BSD Lincense
+
+(function() {
+
+ var console = window.console;
+ if (!console) console = {log: function(){ }, error: function(){ }};
+
+ function hasFlash() {
+ if ('navigator' in window && 'plugins' in navigator && navigator.plugins['Shockwave Flash']) {
+ return !!navigator.plugins['Shockwave Flash'].description;
+ }
+ if ('ActiveXObject' in window) {
+ try {
+ return !!new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version');
+ } catch (e) {}
+ }
+ return false;
+ }
+
+ if (!hasFlash()) {
+ console.error("Flash Player is not installed.");
+ return;
+ }
+
+ FABTest = function() {
+ var self = this;
+ FABTest.__addTask(function() {
+ self.__flash =
+ FABTest.__flash.create();
+
+ self.__flash.addEventListener("message", function(fe) {
+ var data = decodeURIComponent(fe.getData());
+ try {
+ if (self.onmessage) {
+ var e;
+ if (window.MessageEvent) {
+ e = document.createEvent("MessageEvent");
+ e.initMessageEvent("message", false, false, data, null, null, window);
+ } else { // IE
+ e = {data: data};
+ }
+ self.onmessage(e);
+ }
+ } catch (e) {
+ console.error(e.toString());
+ }
+ });
+
+ //console.log("[FABTest] Flash object is ready");
+ });
+ }
+
+ FABTest.prototype.start = function(eventDelay) {
+ if (!this.__flash) {
+ throw "INVALID_STATE_ERR: FABTest connection has not been established";
+ }
+ var result = this.__flash.start(eventDelay);
+ if (result < 0) { // success
+ return true;
+ } else {
+ return false;
+ }
+ };
+
+ FABTest.prototype.stop = function() {
+ if (!this.__flash) return;
+ this.__flash.stop();
+ };
+
+
+
+ FABTest.__tasks = [];
+
+ FABTest.__initialize = function() {
+ if (!FABTest.__swfLocation) {
+ console.error("[FABTest] set FABTest.__swfLocation to location of FABTestMain.swf");
+ return;
+ }
+ var container = document.createElement("div");
+ container.id = "fabTestContainer";
+ // Puts the Flash out of the window. Note that we cannot use display: none or visibility: hidden
+ // here because it prevents Flash from loading at least in IE.
+ container.style.position = "absolute";
+ container.style.left = "-100px";
+ container.style.top = "-100px";
+ var holder = document.createElement("div");
+ holder.id = "fabTestFlash";
+ container.appendChild(holder);
+ document.body.appendChild(container);
+ swfobject.embedSWF(
+ FABTest.__swfLocation, "fabTestFlash", "8", "8", "9.0.0",
+ null, {bridgeName: "fabTest"}, null, null,
+ function(e) {
+ if (!e.success) console.error("[FABTest] swfobject.embedSWF failed");
+ }
+ );
+ FABridge.addInitializationCallback("fabTest", function() {
+ try {
+ console.log("[FABTest] FABridge initializad");
+ FABTest.__flash = FABridge.fabTest.root();
+ for (var i = 0; i < FABTest.__tasks.length; ++i) {
+ FABTest.__tasks[i]();
+ }
+ FABTest.__tasks = [];
+ } catch (e) {
+ console.error("[FABTest] " + e.toString());
+ }
+ });
+ };
+
+ FABTest.__addTask = function(task) {
+ if (FABTest.__flash) {
+ task();
+ } else {
+ FABTest.__tasks.push(task);
+ }
+ }
+
+ // called from Flash
+ function fabTestLog(message) {
+ console.log(decodeURIComponent(message));
+ }
+
+ // called from Flash
+ function fabTestError(message) {
+ console.error(decodeURIComponent(message));
+ }
+
+ if (window.addEventListener) {
+ window.addEventListener("load", FABTest.__initialize, false);
+ } else {
+ window.attachEvent("onload", FABTest.__initialize);
+ }
+
+})();
--- /dev/null
+<html>
+
+ <head><title>FABridge Event Test</title></head>
+
+ <body>
+
+ Event Delay (ms): <input id='eventDelay' style='width:50' value="100">
+ <input id='startButton' type='button' value='Start' style='width:100px'
+ onclick="start();">
+
+ <br><br>
+ <table border=1>
+ <tr>
+ <th align="right">Good Events Received:</th>
+ <td align="right"><div id='received'>0</div></td>
+ </tr><tr>
+ <th align="right">Errors (Bad Events Received:)</th>
+ <td align="right"><div id='errors'>0</div></td>
+ </tr>
+ </table>
+
+ <br>
+ Errors:<br>
+ <textarea id="error" style="font-size: 9;" cols=80 rows=25></textarea>
+ </body>
+
+
+ <!-- Uncomment to activate firebug lite -->
+ <!--
+ <script type='text/javascript'
+ src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
+ -->
+
+ <script src="../include/mootools.js"></script>
+ <script src="../include/util.js"></script>
+
+ <script>
+
+ function error(str) {
+ console.error(str);
+ cell = $('error');
+ cell.innerHTML += errors + ": " + str + "\n";
+ cell.scrollTop = cell.scrollHeight;
+ }
+
+ var eventDelay = 0;
+ var fab = null;
+ var recv_seq = 0, received = 0, errors = 0;
+
+ function check_event(data) {
+ //console.log(">> check_event");
+ var got_seq = parseInt(data, 10);
+ if (got_seq !== recv_seq) {
+ error("got event " + got_seq + ", expecting " + recv_seq);
+ errors = errors + 1;
+ } else {
+ received = received + 1;
+ }
+ recv_seq = got_seq + 1;
+ //console.log("<< check_event");
+ }
+
+ function update_stats() {
+ $('received').innerHTML = received;
+ $('errors').innerHTML = errors;
+ }
+
+ function start() {
+ console.log(">> start");
+ eventDelay = parseInt($('eventDelay').value, 10);
+ recv_seq = 0;
+
+ fab.onmessage = function(e) {
+ //console.log(">> FABTest.onmessage");
+ check_event(e.data);
+ //console.log("<< FABTest.onmessage");
+ };
+ fab.start(eventDelay);
+ update_ref = update_stats.periodical(1);
+
+ $('startButton').value = "Stop";
+ $('startButton').onclick = stop;
+ console.log("<< start");
+ }
+
+ function stop() {
+ console.log(">> stop");
+ fab.stop();
+ $clear(update_ref);
+ update_stats(); // Final numbers
+ recv_seq = 0;
+
+ $('startButton').value = "Start";
+ $('startButton').onclick = start;
+ console.log("<< stop");
+ }
+
+
+ /* If no builtin websockets then load web_socket.js */
+ console.log("Loading FABridge event test object");
+ var extra = "<script src='../include/web-socket-js/swfobject.js'><\/script>";
+ extra += "<script src='../include/web-socket-js/FABridge.js'><\/script>";
+ extra += "<script src='../include/fab-test/fab-test.js'><\/script>";
+ document.write(extra);
+
+ window.onload = function() {
+ console.log("onload");
+ FABTest.__swfLocation = "../include/fab-test/FABTestMain.swf";
+ console.log("creating FABridge event test object");
+ fab = new FABTest(eventDelay);
+ }
+ </script>
+
+</html>
--- /dev/null
+<html>
+
+ <head><title>WebSockets Test</title></head>
+
+ <body>
+
+ Host: <input id='host' style='width:100'>
+ Port: <input id='port' style='width:50'>
+ Encrypt: <input id='encrypt' type='checkbox'>
+ Send Delay (ms): <input id='sendDelay' style='width:50' value="100">
+ <input id='connectButton' type='button' value='Start' style='width:100px'
+ onclick="connect();">
+
+ <br><br>
+ <table border=1>
+ <tr>
+ <th align="right">Packets sent:</th>
+ <td align="right"><div id='sent'>0</div></td>
+ </tr><tr>
+ <th align="right">Good Packets Received:</th>
+ <td align="right"><div id='received'>0</div></td>
+ </tr><tr>
+ <th align="right">Errors (Bad Packets Received:)</th>
+ <td align="right"><div id='errors'>0</div></td>
+ </tr>
+ </table>
+
+ <br>
+ Errors:<br>
+ <textarea id="error" style="font-size: 9;" cols=80 rows=25></textarea>
+ </body>
+
+
+ <!-- Uncomment to activate firebug lite -->
+ <!--
+ <script type='text/javascript'
+ src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
+ -->
+
+ <script src="../include/mootools.js"></script>
+ <script src="../include/base64.js"></script>
+ <script src="../include/util.js"></script>
+
+ <script>
+
+ function error(str) {
+ console.error(str);
+ cell = $('error');
+ cell.innerHTML += errors + ": " + str + "\n";
+ cell.scrollTop = cell.scrollHeight;
+ }
+
+ var host = null, port = null, sendDelay = 0;
+ var ws = null, update_ref = null, send_ref = null;
+ var sent = 0, received = 0, errors = 0;
+ var max_send = 2000;
+ var recv_seq = 0, send_seq = 0;
+
+ Array.prototype.pushStr = function (str) {
+ var n = str.length;
+ for (var i=0; i < n; i++) {
+ this.push(str.charCodeAt(i));
+ }
+ }
+
+
+
+ function add (x,y) {
+ return parseInt(x,10)+parseInt(y,10);
+ }
+
+ function check_respond(data) {
+ //console.log(">> check_respond");
+ var decoded, first, last, str, length, chksum, nums, arr;
+ decoded = Base64.decode(data);
+ first = String.fromCharCode(decoded.shift());
+ last = String.fromCharCode(decoded.pop());
+
+ if (first != "^") {
+ errors++;
+ error("Packet missing start char '^'");
+ return;
+ }
+ if (last != "$") {
+ errors++;
+ error("Packet missing end char '$'");
+ return;
+ }
+ arr = decoded.map(function(num) {
+ return String.fromCharCode(num);
+ } ).join('').split(':');
+ seq = arr[0];
+ length = arr[1];
+ chksum = arr[2];
+ nums = arr[3];
+
+ //console.log(" length:" + length + " chksum:" + chksum + " nums:" + nums);
+ if (seq != recv_seq) {
+ errors++;
+ error("Expected seq " + recv_seq + " but got " + seq);
+ recv_seq = parseInt(seq,10) + 1; // Back on track
+ return;
+ }
+ recv_seq++;
+ if (nums.length != length) {
+ errors++;
+ error("Expected length " + length + " but got " + nums.length);
+ return;
+ }
+ //real_chksum = nums.reduce(add);
+ real_chksum = 0;
+ for (var i=0; i < nums.length; i++) {
+ real_chksum += parseInt(nums.charAt(i), 10);
+ }
+ if (real_chksum != chksum) {
+ errors++
+ error("Expected chksum " + chksum + " but real chksum is " + real_chksum);
+ return;
+ }
+ received++;
+ //console.log(" Packet checks out: length:" + length + " chksum:" + chksum);
+ //console.log("<< check_respond");
+ }
+
+ function send() {
+ if (ws.bufferedAmount > 0) {
+ console.log("Delaying send");
+ return;
+ }
+ var length = Math.floor(Math.random()*(max_send-9)) + 10; // 10 - max_send
+ var numlist = [], arr = [];
+ for (var i=0; i < length; i++) {
+ numlist.push( Math.floor(Math.random()*10) );
+ }
+ //chksum = numlist.reduce(add);
+ chksum = 0;
+ for (var i=0; i < numlist.length; i++) {
+ chksum += parseInt(numlist[i], 10);
+ }
+ var nums = numlist.join('');
+ arr.pushStr("^" + send_seq + ":" + length + ":" + chksum + ":" + nums + "$")
+ send_seq ++;
+ ws.send(Base64.encode(arr));
+ sent++;
+ }
+
+ function update_stats() {
+ $('sent').innerHTML = sent;
+ $('received').innerHTML = received;
+ $('errors').innerHTML = errors;
+ }
+
+ function init_ws() {
+ console.log(">> init_ws");
+ var scheme = "ws://";
+ if ($('encrypt').checked) {
+ scheme = "wss://";
+ }
+ var uri = scheme + host + ":" + port + "/?b64encode";
+ //if (RFB.use_seq) {
+ // uri += "&seq_num";
+ //}
+ console.log("connecting to " + uri);
+ ws = new WebSocket(uri);
+
+ ws.onmessage = function(e) {
+ //console.log(">> WebSockets.onmessage");
+ check_respond(e.data);
+ //console.log("<< WebSockets.onmessage");
+ };
+ ws.onopen = function(e) {
+ console.log(">> WebSockets.onopen");
+ send_ref = send.periodical(sendDelay);
+ console.log("<< WebSockets.onopen");
+ };
+ ws.onclose = function(e) {
+ console.log(">> WebSockets.onclose");
+ $clear(send_ref);
+ console.log("<< WebSockets.onclose");
+ };
+ ws.onerror = function(e) {
+ console.log(">> WebSockets.onerror");
+ console.log(" " + e);
+ console.log("<< WebSockets.onerror");
+ };
+
+ console.log("<< init_ws");
+ }
+
+ function connect() {
+ console.log(">> connect");
+ host = $('host').value;
+ port = $('port').value;
+ sendDelay = parseInt($('sendDelay').value, 10);
+ if ((!host) || (!port)) {
+ console.log("must set host and port");
+ return;
+ }
+
+ if (ws) {
+ ws.close();
+ }
+ init_ws();
+ update_ref = update_stats.periodical(1);
+
+ $('connectButton').value = "Stop";
+ $('connectButton').onclick = disconnect;
+ console.log("<< connect");
+ }
+
+ function disconnect() {
+ console.log(">> disconnect");
+ if (ws) {
+ ws.close();
+ }
+
+ $clear(update_ref);
+ update_stats(); // Final numbers
+ recv_seq = 0;
+ send_seq = 0;
+
+ $('connectButton').value = "Start";
+ $('connectButton').onclick = connect;
+ console.log("<< disconnect");
+ }
+
+
+ /* If no builtin websockets then load web_socket.js */
+ if (! window.WebSocket) {
+ console.log("Loading web-socket-js flash bridge");
+ var extra = "<script src='include/web-socket-js/swfobject.js'><\/script>";
+ extra += "<script src='include/web-socket-js/FABridge.js'><\/script>";
+ extra += "<script src='include/web-socket-js/web_socket.js'><\/script>";
+ document.write(extra);
+ }
+
+ window.onload = function() {
+ console.log("onload");
+ WebSocket.__swfLocation = "include/web-socket-js/WebSocketMain.swf";
+ var url = document.location.href;
+ $('host').value = (url.match(/host=([^&#]*)/) || ['',''])[1];
+ $('port').value = (url.match(/port=([^&#]*)/) || ['',''])[1];
+ }
+ </script>
+
+</html>
--- /dev/null
+#!/usr/bin/python
+
+'''
+WebSocket server-side load test program. Sends and receives traffic
+that has a random payload (length and content) that is checksummed and
+given a sequence number. Any errors are reported and counted.
+'''
+
+import sys, os, socket, ssl, time, traceback
+import random, time
+from base64 import b64encode, b64decode
+from select import select
+
+sys.path.insert(0,os.path.dirname(__file__) + "/../")
+from websocket import *
+
+buffer_size = 65536
+recv_cnt = send_cnt = 0
+
+
+def check(buf):
+ global recv_cnt
+
+ try:
+ data_list = decode(buf)
+ except:
+ print "\n<BOF>" + repr(buf) + "<EOF>"
+ return "Failed to decode"
+
+ err = ""
+ for data in data_list:
+ if data.count('$') > 1:
+ raise Exception("Multiple parts within single packet")
+ if len(data) == 0:
+ traffic("_")
+ continue
+
+ if data[0] != "^":
+ err += "buf did not start with '^'\n"
+ continue
+
+ try:
+ cnt, length, chksum, nums = data[1:-1].split(':')
+ cnt = int(cnt)
+ length = int(length)
+ chksum = int(chksum)
+ except:
+ print "\n<BOF>" + repr(data) + "<EOF>"
+ err += "Invalid data format\n"
+ continue
+
+ if recv_cnt != cnt:
+ err += "Expected count %d but got %d\n" % (recv_cnt, cnt)
+ recv_cnt = cnt + 1
+ continue
+
+ recv_cnt += 1
+
+ if len(nums) != length:
+ err += "Expected length %d but got %d\n" % (length, len(nums))
+ continue
+
+ inv = nums.translate(None, "0123456789")
+ if inv:
+ err += "Invalid characters found: %s\n" % inv
+ continue
+
+ real_chksum = 0
+ for num in nums:
+ real_chksum += int(num)
+
+ if real_chksum != chksum:
+ err += "Expected checksum %d but real chksum is %d\n" % (chksum, real_chksum)
+ return err
+
+
+def generate():
+ global send_cnt, rand_array
+ length = random.randint(10, 100000)
+ numlist = rand_array[100000-length:]
+ # Error in length
+ #numlist.append(5)
+ chksum = sum(numlist)
+ # Error in checksum
+ #numlist[0] = 5
+ nums = "".join( [str(n) for n in numlist] )
+ data = "^%d:%d:%d:%s$" % (send_cnt, length, chksum, nums)
+ send_cnt += 1
+
+ return encode(data)
+
+def responder(client, delay=10):
+ global errors
+ cqueue = []
+ cpartial = ""
+ socks = [client]
+ last_send = time.time() * 1000
+
+ while True:
+ ins, outs, excepts = select(socks, socks, socks, 1)
+ if excepts: raise Exception("Socket exception")
+
+ if client in ins:
+ buf = client.recv(buffer_size)
+ if len(buf) == 0: raise Exception("Client closed")
+ #print "Client recv: %s (%d)" % (repr(buf[1:-1]), len(buf))
+ if buf[-1] == '\xff':
+ if cpartial:
+ err = check(cpartial + buf)
+ cpartial = ""
+ else:
+ err = check(buf)
+ if err:
+ traffic("}")
+ errors = errors + 1
+ print err
+ else:
+ traffic(">")
+ else:
+ traffic(".>")
+ cpartial = cpartial + buf
+
+ now = time.time() * 1000
+ if client in outs and now > (last_send + delay):
+ last_send = now
+ #print "Client send: %s" % repr(cqueue[0])
+ client.send(generate())
+ traffic("<")
+
+def test_handler(client):
+ global errors, delay, send_cnt, recv_cnt
+
+ send_cnt = 0
+ recv_cnt = 0
+
+ try:
+ responder(client, delay)
+ except:
+ print "accumulated errors:", errors
+ errors = 0
+ raise
+
+
+if __name__ == '__main__':
+ errors = 0
+ try:
+ if len(sys.argv) < 2: raise
+ listen_port = int(sys.argv[1])
+ if len(sys.argv) == 3:
+ delay = int(sys.argv[2])
+ else:
+ delay = 10
+ except:
+ print "Usage: <listen_port> [delay_ms]"
+ sys.exit(1)
+
+ print "Prepopulating random array"
+ rand_array = []
+ for i in range(0, 100000):
+ rand_array.append(random.randint(0, 9))
+
+ start_server(listen_port, test_handler)
+++ /dev/null
-<html>
-
- <head><title>WebSockets Test</title></head>
-
- <body>
-
- Host: <input id='host' style='width:100'>
- Port: <input id='port' style='width:50'>
- Encrypt: <input id='encrypt' type='checkbox'>
- Send Delay (ms): <input id='sendDelay' style='width:50' value="100">
- <input id='connectButton' type='button' value='Start' style='width:100px'
- onclick="connect();">
-
- <br><br>
- <table border=1>
- <tr>
- <th align="right">Packets sent:</th>
- <td align="right"><div id='sent'>0</div></td>
- </tr><tr>
- <th align="right">Good Packets Received:</th>
- <td align="right"><div id='received'>0</div></td>
- </tr><tr>
- <th align="right">Errors (Bad Packets Received:)</th>
- <td align="right"><div id='errors'>0</div></td>
- </tr>
- </table>
-
- <br>
- Errors:<br>
- <textarea id="error" style="font-size: 9;" cols=80 rows=25></textarea>
- </body>
-
-
- <!-- Uncomment to activate firebug lite -->
- <!--
- <script type='text/javascript'
- src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
- -->
-
- <script src="include/mootools.js"></script>
- <script src="include/base64.js"></script>
- <script src="include/util.js"></script>
-
- <script>
-
- function error(str) {
- console.error(str);
- cell = $('error');
- cell.innerHTML += errors + ": " + str + "\n";
- cell.scrollTop = cell.scrollHeight;
- }
-
- var host = null, port = null, sendDelay = 0;
- var ws = null, update_ref = null, send_ref = null;
- var sent = 0, received = 0, errors = 0;
- var max_send = 2000;
- var recv_seq = 0, send_seq = 0;
-
- Array.prototype.pushStr = function (str) {
- var n = str.length;
- for (var i=0; i < n; i++) {
- this.push(str.charCodeAt(i));
- }
- }
-
-
-
- function add (x,y) {
- return parseInt(x,10)+parseInt(y,10);
- }
-
- function check_respond(data) {
- //console.log(">> check_respond");
- var decoded, first, last, str, length, chksum, nums, arr;
- decoded = Base64.decode(data);
- first = String.fromCharCode(decoded.shift());
- last = String.fromCharCode(decoded.pop());
-
- if (first != "^") {
- errors++;
- error("Packet missing start char '^'");
- return;
- }
- if (last != "$") {
- errors++;
- error("Packet missing end char '$'");
- return;
- }
- arr = decoded.map(function(num) {
- return String.fromCharCode(num);
- } ).join('').split(':');
- seq = arr[0];
- length = arr[1];
- chksum = arr[2];
- nums = arr[3];
-
- //console.log(" length:" + length + " chksum:" + chksum + " nums:" + nums);
- if (seq != recv_seq) {
- errors++;
- error("Expected seq " + recv_seq + " but got " + seq);
- recv_seq = parseInt(seq,10) + 1; // Back on track
- return;
- }
- recv_seq++;
- if (nums.length != length) {
- errors++;
- error("Expected length " + length + " but got " + nums.length);
- return;
- }
- //real_chksum = nums.reduce(add);
- real_chksum = 0;
- for (var i=0; i < nums.length; i++) {
- real_chksum += parseInt(nums.charAt(i), 10);
- }
- if (real_chksum != chksum) {
- errors++
- error("Expected chksum " + chksum + " but real chksum is " + real_chksum);
- return;
- }
- received++;
- //console.log(" Packet checks out: length:" + length + " chksum:" + chksum);
- //console.log("<< check_respond");
- }
-
- function send() {
- if (ws.bufferedAmount > 0) {
- console.log("Delaying send");
- return;
- }
- var length = Math.floor(Math.random()*(max_send-9)) + 10; // 10 - max_send
- var numlist = [], arr = [];
- for (var i=0; i < length; i++) {
- numlist.push( Math.floor(Math.random()*10) );
- }
- //chksum = numlist.reduce(add);
- chksum = 0;
- for (var i=0; i < numlist.length; i++) {
- chksum += parseInt(numlist[i], 10);
- }
- var nums = numlist.join('');
- arr.pushStr("^" + send_seq + ":" + length + ":" + chksum + ":" + nums + "$")
- send_seq ++;
- ws.send(Base64.encode(arr));
- sent++;
- }
-
- function update_stats() {
- $('sent').innerHTML = sent;
- $('received').innerHTML = received;
- $('errors').innerHTML = errors;
- }
-
- function init_ws() {
- console.log(">> init_ws");
- var scheme = "ws://";
- if ($('encrypt').checked) {
- scheme = "wss://";
- }
- var uri = scheme + host + ":" + port + "/?b64encode";
- //if (RFB.use_seq) {
- // uri += "&seq_num";
- //}
- console.log("connecting to " + uri);
- ws = new WebSocket(uri);
-
- ws.onmessage = function(e) {
- //console.log(">> WebSockets.onmessage");
- check_respond(e.data);
- //console.log("<< WebSockets.onmessage");
- };
- ws.onopen = function(e) {
- console.log(">> WebSockets.onopen");
- send_ref = send.periodical(sendDelay);
- console.log("<< WebSockets.onopen");
- };
- ws.onclose = function(e) {
- console.log(">> WebSockets.onclose");
- $clear(send_ref);
- console.log("<< WebSockets.onclose");
- };
- ws.onerror = function(e) {
- console.log(">> WebSockets.onerror");
- console.log(" " + e);
- console.log("<< WebSockets.onerror");
- };
-
- console.log("<< init_ws");
- }
-
- function connect() {
- console.log(">> connect");
- host = $('host').value;
- port = $('port').value;
- sendDelay = parseInt($('sendDelay').value, 10);
- if ((!host) || (!port)) {
- console.log("must set host and port");
- return;
- }
-
- if (ws) {
- ws.close();
- }
- init_ws();
- update_ref = update_stats.periodical(1);
-
- $('connectButton').value = "Stop";
- $('connectButton').onclick = disconnect;
- console.log("<< connect");
- }
-
- function disconnect() {
- console.log(">> disconnect");
- if (ws) {
- ws.close();
- }
-
- $clear(update_ref);
- update_stats(); // Final numbers
- recv_seq = 0;
- send_seq = 0;
-
- $('connectButton').value = "Start";
- $('connectButton').onclick = connect;
- console.log("<< disconnect");
- }
-
-
- /* If no builtin websockets then load web_socket.js */
- if (! window.WebSocket) {
- console.log("Loading web-socket-js flash bridge");
- var extra = "<script src='include/web-socket-js/swfobject.js'><\/script>";
- extra += "<script src='include/web-socket-js/FABridge.js'><\/script>";
- extra += "<script src='include/web-socket-js/web_socket.js'><\/script>";
- document.write(extra);
- }
-
- window.onload = function() {
- console.log("onload");
- WebSocket.__swfLocation = "include/web-socket-js/WebSocketMain.swf";
- var url = document.location.href;
- $('host').value = (url.match(/host=([^&#]*)/) || ['',''])[1];
- $('port').value = (url.match(/port=([^&#]*)/) || ['',''])[1];
- }
- </script>
-
-</html>
+++ /dev/null
-#!/usr/bin/python
-
-'''
-WebSocket server-side load test program. Sends and receives traffic
-that has a random payload (length and content) that is checksummed and
-given a sequence number. Any errors are reported and counted.
-'''
-
-import sys, socket, ssl, time, traceback
-import random, time
-from base64 import b64encode, b64decode
-from select import select
-from websocket import *
-
-buffer_size = 65536
-recv_cnt = send_cnt = 0
-
-
-def check(buf):
- global recv_cnt
-
- try:
- data_list = decode(buf)
- except:
- print "\n<BOF>" + repr(buf) + "<EOF>"
- return "Failed to decode"
-
- err = ""
- for data in data_list:
- if data.count('$') > 1:
- raise Exception("Multiple parts within single packet")
- if len(data) == 0:
- traffic("_")
- continue
-
- if data[0] != "^":
- err += "buf did not start with '^'\n"
- continue
-
- try:
- cnt, length, chksum, nums = data[1:-1].split(':')
- cnt = int(cnt)
- length = int(length)
- chksum = int(chksum)
- except:
- print "\n<BOF>" + repr(data) + "<EOF>"
- err += "Invalid data format\n"
- continue
-
- if recv_cnt != cnt:
- err += "Expected count %d but got %d\n" % (recv_cnt, cnt)
- recv_cnt = cnt + 1
- continue
-
- recv_cnt += 1
-
- if len(nums) != length:
- err += "Expected length %d but got %d\n" % (length, len(nums))
- continue
-
- inv = nums.translate(None, "0123456789")
- if inv:
- err += "Invalid characters found: %s\n" % inv
- continue
-
- real_chksum = 0
- for num in nums:
- real_chksum += int(num)
-
- if real_chksum != chksum:
- err += "Expected checksum %d but real chksum is %d\n" % (chksum, real_chksum)
- return err
-
-
-def generate():
- global send_cnt, rand_array
- length = random.randint(10, 100000)
- numlist = rand_array[100000-length:]
- # Error in length
- #numlist.append(5)
- chksum = sum(numlist)
- # Error in checksum
- #numlist[0] = 5
- nums = "".join( [str(n) for n in numlist] )
- data = "^%d:%d:%d:%s$" % (send_cnt, length, chksum, nums)
- send_cnt += 1
-
- return encode(data)
-
-def responder(client, delay=10):
- global errors
- cqueue = []
- cpartial = ""
- socks = [client]
- last_send = time.time() * 1000
-
- while True:
- ins, outs, excepts = select(socks, socks, socks, 1)
- if excepts: raise Exception("Socket exception")
-
- if client in ins:
- buf = client.recv(buffer_size)
- if len(buf) == 0: raise Exception("Client closed")
- #print "Client recv: %s (%d)" % (repr(buf[1:-1]), len(buf))
- if buf[-1] == '\xff':
- if cpartial:
- err = check(cpartial + buf)
- cpartial = ""
- else:
- err = check(buf)
- if err:
- traffic("}")
- errors = errors + 1
- print err
- else:
- traffic(">")
- else:
- traffic(".>")
- cpartial = cpartial + buf
-
- now = time.time() * 1000
- if client in outs and now > (last_send + delay):
- last_send = now
- #print "Client send: %s" % repr(cqueue[0])
- client.send(generate())
- traffic("<")
-
-def test_handler(client):
- global errors, delay, send_cnt, recv_cnt
-
- send_cnt = 0
- recv_cnt = 0
-
- try:
- responder(client, delay)
- except:
- print "accumulated errors:", errors
- errors = 0
- raise
-
-
-if __name__ == '__main__':
- errors = 0
- try:
- if len(sys.argv) < 2: raise
- listen_port = int(sys.argv[1])
- if len(sys.argv) == 3:
- delay = int(sys.argv[2])
- else:
- delay = 10
- except:
- print "Usage: <listen_port> [delay_ms]"
- sys.exit(1)
-
- print "Prepopulating random array"
- rand_array = []
- for i in range(0, 100000):
- rand_array.append(random.randint(0, 9))
-
- start_server(listen_port, test_handler)