0

This might be a duplicate of Convert byte array to numbers in JavaScript but the best answer there is quite old (maybe there is something new?) and I would also like to approach this in an open ended manner and ask a broader question regarding if there is a better way to send data in a performant way instead of what I am trying to do.

I am currently working on making a real time game using webrtc run by a C# server.

For updating the client I am currently playing around with this code converting numbers to a byte[] which I can then send to the client (to minimize the data, this turns into 50 bytes). This is important as I'll be sending several updates per second.

public static byte[] UserLocationToByte(long userId, double x, double y, double r, double dx, double dy)
{
    var msg = new List<byte[]>
    {
        BitConverter.GetBytes((short)DataMessageType.Location),
        BitConverter.GetBytes(userId),
        BitConverter.GetBytes(x),
        BitConverter.GetBytes(y),
        BitConverter.GetBytes(r),
        BitConverter.GetBytes(dx),
        BitConverter.GetBytes(dy)
    };

    var t = msg.SelectMany(a => a).ToArray();
    return t;
}

In C# I could convert this back to the number values using.

// convert it back.
var rtype = (DataMessageType)BitConverter.ToInt16(bytes, 0);
var ruserId = BitConverter.ToInt64(bytes, 2);
var rx = BitConverter.ToDouble(bytes, 2 + 8);
var ry = BitConverter.ToDouble(bytes, 2 + 8 + 8);
var rr = BitConverter.ToDouble(bytes, 2 + 8 + 8 + 8);
var rdx = BitConverter.ToDouble(bytes, 2 + 8 + 8 + 8 + 8);
var rdy = BitConverter.ToDouble(bytes, 2 + 8 + 8 + 8 + 8 + 8);

Searching around I found no simple way to do this in javascript/typescript.

I could just send strings with | separators and parse those in javascript, but that would increase the amount of data by quite alot.

Any suggestions as to how to either parse a byte[] in javascript or another way to approach this problem all together?

I have no problem just supporting firefox and chrome.

JensB
  • 6,663
  • 2
  • 55
  • 94
  • How exactly are you getting the data client side, ie what format (string, blob, etc)? Javascript itself has Typed Arrays like Int8Array which would be a byte array and the values are already numbers. – Patrick Evans Nov 03 '18 at 21:15
  • You might want to look into DataView's, one problem you might have is that Javascript doesn't support 64bit integers.. You could maybe get around this using a third party lib for this,. But does your userID have to be 64bit? – Keith Nov 03 '18 at 21:50
  • @PatrickEvans javascript is getting an int8Array, but parsing that back seems quite obtuse (looking at the other thread linked). Im worried that when javascript is receiving 50+ of these per second that might not be so great. – JensB Nov 03 '18 at 21:58
  • @Keith No I it does not, I'm quite sure that Ill have other problems before I reach Int32.MaxValue. I'll change that. – JensB Nov 03 '18 at 22:00

1 Answers1

1

Ok, assuming an unsigned int, is big enough for userid's.

You could use a DataView,

Below is an example, it will then return an ArrayBuffer that you can use to send the data etc.

The true at the end of each set is so that little endian is used, this should then be compatible with C# on windows.

If your on Chrome you can view what's in the ArrayBuffer and confirm if it looks correct..

const msgTypeLocation = 1;


function UserLocationToByte(userId, x, y, r,  dx, dy)
{
  const buffer = new ArrayBuffer(46);
  const dv = new DataView(buffer);
  let o = 0;
  dv.setInt16(0, msgTypeLocation, true); o += 2;
  dv.setUint32(o, userId, true); o += 4;
  dv.setFloat64(o, x, true); o += 8;
  dv.setFloat64(o, y, true); o += 8;
  dv.setFloat64(o, r, true); o += 8;
  dv.setFloat64(o, dx, true); o += 8;
  dv.setFloat64(o, dy, true); o += 8;
  return buffer;
}


const data = UserLocationToByte(10, 20.0, 30.0, 40.0, 10.0, 12.0);
console.log(data);
Look in Chrome Console, etc. to see the bytes.
Keith
  • 22,005
  • 2
  • 27
  • 44
  • Probably should also include examples of the `get*` versions of the methods since they are likely to want to use those on the client side in order to read the values back. – Patrick Evans Nov 03 '18 at 22:14