I have a node.js server application and a browser client. Sending ArrayBuffer
data browser -> server works perfectly, but server -> browser results in a string "[object ArrayBuffer]"
being received. This happens in the latest versions of both Chrome and Firefox.
Server:
var serverPort = 9867;
// dependencies
var webSocketServer = require('websocket').server;
var http = require('http');
var players = {};
var nextPlayerId = 0;
// create http server
var server = http.createServer(function(request, response) { });
server.listen(serverPort, function() {
console.log((new Date()) + " Server is listening on port " + serverPort);
});
// create websocket server
var wServer = new webSocketServer({ httpServer: server });
// connection request callback
wServer.on('request', function(request) {
var connection = request.accept(null, request.origin);
connection.binaryType = "arraybuffer";
var player = {};
player.connection = connection;
player.id = nextPlayerId;
nextPlayerId++;
players[player.id] = player;
console.log((new Date()) + ' connect: ' + player.id);
// message received callback
connection.on('message', function(message) {
if (message.type == 'binary' && 'binaryData' in message && message.binaryData instanceof Buffer) {
// this works!
console.log('received:');
console.log(message);
}
});
// connection closed callback
connection.on('close', function(connection) {
console.log((new Date()) + ' disconnect: ' + player.id);
delete players[player.id];
});
});
function loop() {
var byteArray = new Uint8Array(2);
byteArray[0] = 1;
byteArray[0] = 2;
for (var index in players) {
var player = players[index];
console.log('sending: ');
console.log(byteArray.buffer);
player.connection.send(byteArray.buffer);
}
}
timerId = setInterval(loop, 500);
Client:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script type="text/javascript">
window.WebSocket = window.WebSocket || window.MozWebSocket;
var connection = new WebSocket('ws://127.0.0.1:9867');
connection.binaryType = "arraybuffer";
// most important part - incoming messages
connection.onmessage = function (event) {
document.getElementById("log").innerHTML += typeof(event.data) + ' ';
document.getElementById("log").innerHTML += event.data + ' ';
if (event.data instanceof ArrayBuffer) {
// string received instead of a buffer
}
};
window.onkeydown = function(e) {
var byteArray = new Uint8Array(2);
byteArray[0] = 1;
byteArray[1] = e.keyCode;
connection.send(byteArray.buffer);
};
</script>
<div id='log'>Log: </div>
</body>
</html>
What am I doing wrong?
Edit:
From the node.js websocket source:
WebSocketConnection.prototype.send = function(data, cb) {
if (Buffer.isBuffer(data)) {
this.sendBytes(data, cb);
}
else if (typeof(data['toString']) === 'function') {
this.sendUTF(data, cb);
}
So if you use an Uint8Array
, it sends the data as a string, instead of using sendBytes
, as sendBytes
needs a Buffer
object. As in the answer below, I need sendBytes
. As I can't pass an ArrayBuffer
to sendBytes
, I did this on the server:
function loop() {
var buffer = new Buffer(2);
buffer[0] = 1;
buffer[1] = 2;
for (var index in players) {
var player = players[index];
console.log('sending: ');
console.log(buffer);
player.connection.send(buffer);
}
}
Now it works.
Conclusion:
While Chrome and Firefox websockets .send()
a Uint8Array
buffer as binary data, it seems node.js websockets send it as string
data, and you need a Buffer
buffer to send binary.
First, you need to copy your web browser's header to here and use json. dumps to convert it into the string format. After that, create the connection to the server by using create_connection . Then, perform the handshake by sending the message, and you will be able to see the data on your side.
send() The WebSocket. send() method enqueues the specified data to be transmitted to the server over the WebSocket connection, increasing the value of bufferedAmount by the number of bytes needed to contain the data.
The only way to know the client received the webSocket message for sure is to have the client send your own custom message back to the server to indicate you received it and for you to wait for that message on the server.
Data Types and ExtensionsWebSockets support sending binary messages, too. To send binary data, one can use either Blob or ArrayBuffer object. Instead of calling the send method with string, you can simply pass an ArrayBuffer or a Blob .
send binary data use sendBytes()
method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With