=================================
=================================
=================================
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>
<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.
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
I've been playing with websockets recently and at least this seems to work:
if(event.data instanceof ArrayBuffer)
{
var wordarray = new Uint16Array(event.data);
for (var i = 0; i < wordarray.length; i++)
{
console.log(wordarray[i]);
wordarray[i]=wordarray[i]+1;
}
console.log("End of binary message");
console.log("sending changes");
ws.send(wordarray.buffer);
}
=================================
=================================
=================================
출처: https://gist.github.com/atsuya/1437249
websocket binary data test - websocket-node
var socket = null;
$(function() {
socket = new WebSocket('ws://localhost:3000');
socket.binaryType = 'arraybuffer';
socket.onmessage = function(message) {
receiveBinary(message);
};
setTimeout(sendBinary, 1000);
});
function sendBinary() {
var byteArray = new Uint8Array(4);
byteArray[0] = 0x01;
byteArray[1] = 0x10;
byteArray[2] = 0xff;
byteArray[3] = 0xde;
socket.send(byteArray.buffer);
}
function receiveBinary(message) {
console.dir(message);
var buffer = new Uint8Array(message.data);
console.dir(buffer);
}
var connection = request.accept(null, request.origin);
console.log((new Date()) + " Connection accepted.");
connection.on('message', function(message) {
if (message.type === 'utf8') {
console.log("Received Message: " + message.utf8Data);
connection.sendUTF(message.utf8Data);
}
else if (message.type === 'binary') {
console.log("Received Binary Message of " + message.binaryData.length + " bytes");
console.log(Buffer.isBuffer(message.binaryData));
console.log(message.binaryData);
for (var i = 0; i < message.binaryData.byteLength; i++) {
console.log(data.readUInt8(i));
}
var buf = new Buffer(5);
buf.writeUInt8(0x3, 0);
buf.writeUInt8(0x4, 1);
buf.writeUInt8(0x23, 2);
buf.writeUInt8(0x42, 3);
buf.writeUInt8(0xff, 4)
connection.sendBytes(buf);
}
});
=================================
=================================
=================================
'WEB > html5' 카테고리의 다른 글
자바스크립트 js 압축 "gz" 을 사용하기위한 iis 설정 관련 (0) | 2020.09.15 |
---|---|
html 의 imports 하기 관련 (0) | 2020.09.15 |
브라우저에서 바로 프로그램 실행 관련 (플래시, Custom URL schemes 등등) (0) | 2018.12.06 |
Html5의 네트워크 | Node.JS, WebSocket, Socket.io, Tcp, Udp 관련 (0) | 2018.04.10 |
[WebGL] Three.js - sound test example with Three.js . Three 사운드 예제 (0) | 2018.01.10 |