상세 컨텐츠

본문 제목

WebSocket bytearray 또는 receiving 관련

WEB/html5

by AlrepondTech 2020. 9. 15. 15:50

본문

반응형

 

 

 

 

=================================

=================================

=================================

 

 

 

 

 

출처: http://stackoverflow.com/questions/15040126/receiving-websocket-arraybuffer-data-in-the-browser-receiving-string-instead

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

browser

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);
}

server

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);
        }
    });

 

 

=================================

=================================

=================================

 

 

 

반응형


관련글 더보기

댓글 영역