我正在尝试在node.js上对我的websocket进行单元测试,并希望模拟出一个websocket客户端。我可以创建一个只连接到我的服务器的HTML文件,但是我无法在服务器上运行单个测试。
我将如何(使用http.Client
或net.Stream
)创建websocket客户端并让它与我的服务器进行交互。
我正在针对websocket规范的草案(很快就要死了)。
我使用的服务器端实现是this
答案 0 :(得分:11)
由于您已经知道所有当前的WebSocket版本将很快就会过时并且您正在使用支持旧75草案的WebSocket服务器,如果您已经有一些服务器代码,那么制作一个很简单,所以没有76中需要“安全”标题。
免责声明:这件事只有5分钟的测试时间,但它应该在大部分时间都有效。
var net = require('net');
function WebSocket(host, port, encoder, decoder) {
this.encoder = encoder || function(data){return data.toString()};
this.decoder = decoder || function(data){return data};
this.socket = net.createConnection(port, host);
this.connected = false;
this.header = 0;
this.bytesSend = 0;
this.dataFrames = [];
this.dataState = 0;
var that = this;
process.nextTick(function() {
that.init(host, port);
});
}
// Prototype -------------------------------------------------------------------
WebSocket.prototype = {
onConnect: function() {console.log('connect');},
onClose: function() {console.log('close');},
onData: function(data) {console.log(data)},
init: function(host, port) {
var that = this;
this.socket.addListener('connect', function() {
var data ='GET / HTTP/1.1\r\n'
+ 'Host: ' + host + ':' + port + '\r\n'
+ 'Origin: websocket.node.js\r\n'
+ 'Connection: Upgrade\r\n'
+ 'Upgrade: WebSocket\r\n\r\n';
that.socket.write(data, 'ascii');
that.socket.flush();
});
this.socket.addListener('data', function(data) {that.read(data);});
this.socket.addListener('end', function() {that.onClose();});
this.socket.addListener('error', function(e) {console.log(e.message);that.close();});
},
send: function(data, encoded) {
if (this.connected) {
return this.write(encoded ? data : this.encoder(data));
} else {
return 0;
}
},
close: function() {
if (this.connected) {
this.connected = false;
this.write(null);
this.socket.end();
this.socket.destroy();
}
},
read: function read(data) {
for(var i = 0, l = data.length; i < l; i++) {
var b = data[i];
if (this.header < 4) {
if ((this.header === 0 || this.header === 2) && b === 0x0d) {
this.header++;
} else if ((this.header === 1 || this.header === 3) && b === 0x0a) {
this.header++;
} else {
this.header = 0;
}
if (this.header === 4) {
this.connected = true;
this.onConnect();
this.header = 5;
}
} else {
if (this.dataState === 0) {
this.dataState = b & 0x80 === 0x80 ? 2 : 1;
// Low bit frame
} else if (this.dataState === 1) {
if (b === 0xff) {
var buffer = new Buffer(this.dataFrames);
this.dataFrames = [];
this.dataState = 0;
if (!this.message(buffer.toString('utf8', 0, buffer.length))) {
this.send({error: 'Invalid Message.'});
this.close();
return;
}
} else {
this.dataFrames.push(b);
}
// Unused high bit frames
} else if (this.dataState === 2) {
if (b === 0x00) {
this.close();
}
}
}
}
},
write: function(data) {
var bytes = 0;
if (!this.socket.writable) {
return bytes;
}
try {
this.socket.write('\x00', 'binary');
if (typeof data === 'string') {
this.socket.write(data, 'utf8');
bytes += Buffer.byteLength(data);
}
this.socket.write('\xff', 'binary');
this.socket.flush();
bytes += 2;
} catch(e) {}
this.bytesSend += bytes;
return bytes;
},
message: function(msg) {
if (this.decoder) {
try {
msg = this.decoder(msg);
} catch(e) {
this.close();
return false;
}
}
this.onData(msg);
return true;
}
};
我们在这里进行设置:
var bison = require('bison');
// automatically do some encoding/decoding magic
var test = new WebSocket('localhost', 28785, bison.encode, bison.decode);
test.onConnect = function() {
};
test.onData = function(data) {
};
随意在评论中提问。
PS:有关其工作原理的信息,请阅读规范:P
答案 1 :(得分:0)
查看modules page上的wiki,websocket clients中有一些npm模块。