Error: TypeError: First argument to DataView constructor must be an ArrayBuffer

console.log(“New message”);
data = message.data
var l = data.byteLength;
var dvu = new DataView(data.buffer);
let position = 0;

here in websocket New message is writing in console but same time showing below error:

Error: TypeError: First argument to DataView constructor must be an ArrayBuffer

But same code working with node.js

Hi @sanjoy.dasgupta, use below code to create data view of given ByteBuffer packet.

let len = packet.length;
let arrayBuffer = new ArrayBuffer(len);
let dv = new Int8Array(arrayBuffer);
for (let i = 0; i < len; ++i) {
    dv[i] = packet[i];
}
let dataView = new DataView(arrayBuffer);
1 Like

what is “ab” in last line: let dataView = new DataView(ab);

Hi @sanjoy.dasgupta, last line would be


let dataView = new DataView(arrayBuffer);

Here is updated script
` socket.addEventListener(“message”, function(message) {
try {
console.log(“New message”);
let len = message.length;
let arrayBuffer = new ArrayBuffer(len);
let dv = new Int8Array(arrayBuffer);
for (let i = 0; i < len; ++i) {
dv[i] = packet[i];
}
let dvu = new DataView(arrayBuffer);
let position = 0;

			while (position != len) {
				var type = dvu.getInt8(position);
				position = position + 1;
				switch (type) {
					case 61:
						console.log("LtpPacket")
						processLtpPacket(dvu);
						break;						
					default:
						//console.log("Default")
						break;
				}
			}
	
			function processLtpPacket(dvu) {
				var last_trade_price = dvu.getFloat32(position, true);
				var last_trade_time = dvu.getInt32(position + 4, true);
				var security_id = dvu.getInt32(position + 8, true);
				var traded = dvu.getInt8(position + 12, true);
				var mode = dvu.getInt8(position + 13, true);
				var changeAbsolute = dvu.getFloat32(position + 14, true);
				var changePercent = dvu.getFloat32(position + 18, true);
				
				
				
				console.log("last_trade_price: " + dvu.getFloat32(position, true))
				console.log("last_trade_time: " + dvu.getInt32(position + 4, true))
				console.log("security id: " + dvu.getInt32(position + 8, true))
				console.log("traded: " + dvu.getInt8(position + 12, true))
				console.log("Mode: " + dvu.getInt8(position + 13, true))
				console.log("changeAbsolute: " + dvu.getFloat32(position + 14, true))
				console.log("changePercent: " + dvu.getFloat32(position + 18, true))
				position += 22;
			}
		
		} catch (e) {
			console.log("Error: " + e);
		}
	});`

now new error appearing :
Error: RangeError: Offset is outside the bounds of the DataView

HI @sanjoy.dasgupta, the server can send you either an error message (in string format) or data packet (in ByteBuffer format). You need to check the message type before performing the decoding logic. Please find below the code implementation -

socket.addEventListener("message", function(packet) {
    if (typeof packet === “string”)
        console.log(packet); // to handle error message sent by server
    else
        console.log(parseBinary(packet)); // to handle ByteBuffer packets sent by server
})

/**
 * This method parses the packets received from Broadcast Server (in ByteBuffer) to human-readable format
 * @param {ArrayByteBuffer} packet ByteBuffer response packet received from Broadcast server
 * @returns {Array} response parsed in human-readable format 
 */
parseBinary(packet) {
    let len = packet.length, response = [];
    let ab = new ArrayBuffer(len);
    let dv = new Int8Array(ab);
    for (let i = 0; i < len; ++i) {
        dv[i] = packet[i];
    }
    let dvu = new DataView(ab);
    let position = 0;
    while (position != len) {
        let type = dvu.getInt8(position);
        position = position + 1;
        switch (type) {
            case 64:
                processIndexLtpPacket();
                break;
            case 65:
                processIndexQuotePacket();
                break;
            case 66:
                processIndexFullPacket();
                break;
            case 61:
                processLtpPacket();
                break;
            case 62:
                processQuotePacket();
                break;
            case 63:
                processFullPacket();
                break;
        }
    }

    function processLtpPacket() {
        response.push({
            last_price: dvu.getFloat32(position, true).toFixed(2),
            last_trade_time: epochConverterUtil.EpochConverter(dvu.getInt32(position + 4, true)),
            security_id: dvu.getInt32(position + 8, true),
            tradable: dvu.getInt8(position + 12, true),
            mode: dvu.getInt8(position + 13, true),
            change_absolute: dvu.getFloat32(position + 14, true).toFixed(2),
            change_percent: dvu.getFloat32(position + 18, true).toFixed(2)
        });
        position = position + 22;
    }

    function processIndexLtpPacket() {
        response.push({
            last_price: dvu.getFloat32(position, true).toFixed(2),
            last_update_time: epochConverterUtil.EpochConverter(dvu.getInt32(position + 4, true)),
            security_id: dvu.getInt32(position + 8, true),
            tradable: dvu.getInt8(position + 12, true),
            mode: dvu.getInt8(position + 13, true),
            change_absolute: dvu.getFloat32(position + 14, true).toFixed(2),
            change_percent: dvu.getFloat32(position + 18, true).toFixed(2)
        });
        position = position + 22;
    }

    function processQuotePacket() {
        response.push({
            last_price: dvu.getFloat32(position, true).toFixed(2),
            last_trade_time: epochConverterUtil.EpochConverter(dvu.getInt32(position + 4, true)),
            security_id: dvu.getInt32(position + 8, true),
            tradable: dvu.getInt8(position + 12, true),
            mode: dvu.getInt8(position + 13, true),
            last_traded_quantity: dvu.getInt32(position + 14, true),
            average_traded_price: dvu.getFloat32(position + 18, true).toFixed(2),
            volume_traded: dvu.getInt32(position + 22, true),
            total_buy_quantity: dvu.getInt32(position + 26, true),
            total_sell_quantity: dvu.getInt32(position + 30, true),
            open: dvu.getFloat32(position + 34, true).toFixed(2),
            close: dvu.getFloat32(position + 38, true).toFixed(2),
            high: dvu.getFloat32(position + 42, true).toFixed(2),
            low: dvu.getFloat32(position + 46, true).toFixed(2),
            change_percent: dvu.getFloat32(position + 50, true).toFixed(2),
            change_absolute: dvu.getFloat32(position + 54, true).toFixed(2),
            fifty_two_week_high: dvu.getFloat32(position + 58, true).toFixed(2),
            fifty_two_week_low: dvu.getFloat32(position + 62, true).toFixed(2)
        });
        position = position + 66;
    }

    function processIndexQuotePacket() {
        response.push({
            last_price: dvu.getFloat32(position, true).toFixed(2),
            security_id: dvu.getInt32(position + 4, true),
            tradable: dvu.getInt8(position + 8, true),
            mode: dvu.getInt8(position + 9, true),
            open: dvu.getFloat32(position + 10, true).toFixed(2),
            close: dvu.getFloat32(position + 14, true).toFixed(2),
            high: dvu.getFloat32(position + 18, true).toFixed(2),
            low: dvu.getFloat32(position + 22, true).toFixed(2),
            change_percent: dvu.getFloat32(position + 26, true).toFixed(2),
            change_absolute: dvu.getFloat32(position + 30, true).toFixed(2),
            fifty_two_week_high: dvu.getFloat32(position + 34, true).toFixed(2),
            fifty_two_week_low: dvu.getFloat32(position + 38, true).toFixed(2)
        });
        position = position + 42;
    }

    function processFullPacket() {
        let depth_size = 20;
        let depthPacket = {}
        for (let i = 0; i < 5; i++) {
            let depth = “depth_packet_ #” + (i + 1);
            let depthObj = {}
            depthObj.buy_quantity = dvu.getInt32(position + (i * depth_size), true);
            depthObj.sell_quantity = dvu.getInt32(position + 4 + (i * depth_size), true);
            depthObj.buy_order = dvu.getInt16(position + 8 + (i * depth_size), true);
            depthObj.sell_order = dvu.getInt16(position + 10 + (i * depth_size), true);
            depthObj.buy_price = dvu.getFloat32(position + 12 + (i * depth_size), true).toFixed(2);
            depthObj.sell_price = dvu.getFloat32(position + 16 + (i * depth_size), true).toFixed(2);
            depthPacket[depth] = depthObj;
        }
        let tick = {}
        tick.depthPacket = depthPacket
        position += 100

        tick.last_price = dvu.getFloat32(position, true).toFixed(2),
        tick.last_trade_time = epochConverterUtil.EpochConverter(dvu.getInt32(position + 4, true)),
        tick.security_id = dvu.getInt32(position + 8, true),
        tick.tradable = dvu.getInt8(position + 12, true),
        tick.mode = dvu.getInt8(position + 13, true),
        tick.last_traded_quantity = dvu.getInt32(position + 14, true),
        tick.average_traded_price = dvu.getFloat32(position + 18, true).toFixed(2),
        tick.volume_traded = dvu.getInt32(position + 22, true),
        tick.total_buy_quantity = dvu.getInt32(position + 26, true),
        tick.total_sell_quantity = dvu.getInt32(position + 30, true),
        tick.open = dvu.getFloat32(position + 34, true).toFixed(2),
        tick.close = dvu.getFloat32(position + 38, true).toFixed(2),
        tick.high = dvu.getFloat32(position + 42, true).toFixed(2),
        tick.low = dvu.getFloat32(position + 46, true).toFixed(2),
        tick.change_percent = dvu.getFloat32(position + 50, true).toFixed(2),
        tick.change_absolute = dvu.getFloat32(position + 54, true).toFixed(2),
        tick.fifty_two_week_high = dvu.getFloat32(position + 58, true).toFixed(2),
        tick.fifty_two_week_low = dvu.getFloat32(position + 62, true).toFixed(2),
        tick.OI = dvu.getInt32(position + 66, true),
        tick.OI_change = dvu.getInt32(position + 70, true)

        response.push(tick);

        position += 74
    }

    function processIndexFullPacket() {
        response.push({
            last_price: dvu.getFloat32(position, true).toFixed(2),
            security_id: dvu.getInt32(position + 4, true),
            tradable: dvu.getInt8(position + 8, true),
            mode: dvu.getInt8(position + 9, true),
            open: dvu.getFloat32(position + 10, true).toFixed(2),
            close: dvu.getFloat32(position + 14, true).toFixed(2),
            high: dvu.getFloat32(position + 18, true).toFixed(2),
            low: dvu.getFloat32(position + 22, true).toFixed(2),
            change_percent: dvu.getFloat32(position + 26, true).toFixed(2),
            change_absolute: dvu.getFloat32(position + 30, true).toFixed(2),
            last_update_time: epochConverterUtil.EpochConverter(dvu.getInt32(position + 34, true)),
        });
        position = position + 38;
    }

    return response;
}
1 Like