如何编写一个 websocket 客户端
Posted
技术标签:
【中文标题】如何编写一个 websocket 客户端【英文标题】:How to write a websocket client 【发布时间】:2010-12-12 13:42:23 【问题描述】:我正在尝试在 node.js 上对我的 websocket 进行单元测试,并想模拟一个 websocket 客户端。我可以创建一个仅连接到我的服务器的 html 文件,但我无法在服务器上运行单个测试。
我将如何(使用http.Client
或net.Stream
)创建一个websocket 客户端并让它与我的服务器交互。
我的目标是 websocket 规范的(即将失效的)草案 76。
我使用的服务器端实现是this
【问题讨论】:
【参考方案1】:由于您已经知道所有当前的 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)
;
欢迎在 cmets 中提问。
PS:有关其工作原理的信息,请阅读规范:P
【讨论】:
【参考方案2】:看看wiki上的modules page,它有一些websocket clients的模块在npm中可用。
【讨论】:
而不是仅仅说“这里有一个列表”,您可以为使用 0.4.8 并实现更新的 06 协议的稳定/最新/良好测试的 websocket 客户端修剪列表。以上是关于如何编写一个 websocket 客户端的主要内容,如果未能解决你的问题,请参考以下文章
Java WebSocket:如何在不编写客户端的情况下测试服务器 WebSocket 端点 [关闭]
如何编写自己的 TCP/IP 或 ISO/OSI 堆栈以使用 WebSockets 而无需每次都使用握手?