NathanaelA / nativescript-websockets

Websockets for NativeScript
83 stars 43 forks source link

truncates returned bytes using iOS 13 #75

Closed ineiti closed 4 years ago

ineiti commented 4 years ago

Our app works correctly on iOS12, but since iOS13, any message received through websockets is truncated. To try it out, do the following:

tns --version
# returns: 6.1.2
tns create iostest --ts
cd iostest
npm i -s nativescript-websockets

Then add the following lines to app/main-view-model.ts::HelloWorldModel.onTap:

        console.log("creating socket");
        const w = new WS("wss://conode.c4dt.org:7771/Status/Request");
        w.binaryType = "arraybuffer";
        w.open();

        w.on("open", () => {
            console.log("opened - sending message");
            const s = Buffer.alloc(0);
            console.log("Sending", s);
            w.send(s);
        });
        w.on("message", (socket, msg:ArrayBuffer) => {
            console.log("received message:", Buffer.from(msg).toString("hex"));
        });

and finally run it:

tns run ios

On an iOS 12 simulator the returned value is correctly filled with (seemingly random) numbers, but in an iOS 13 simulator, all values but the first 36 bytes are filled with 00...

Any help is greatly appreciated.

ineiti commented 4 years ago

Fiddling around with websockets.ios.js, it seems that the message.toString() doesn't behave as before. Where it returned something like

<0ab5030a 02446212 ae030a11 0a0c5065 6e64696e 67506167 654e1201 350a0c0a 074f7065 6e54784e 1201300a 160a0c54 782e4e6f 6465436f 756e7412 06383539 3435370a 110a0c54 782e4e6f...

It now returns:

{length = 4499, bytes = 0x0ab11b0a 0747656e 65726963 12a51b0a ... 6f72673a 37373731 }

This is the full string returned! The total length is not 2 * 4499 here. So some smart programmer at Apple decided that toString should print a nice, user-friendly string. And now the wrapper fails.

I'm currently trying to figure out how to get bytes from a NSConcreteMutableData, but so far no luck...

ineiti commented 4 years ago

I blindly tried some methods of message. Unfortunately, the only one that I managed to make work is message.base64Encoding(). Which is stupid, because now I have to convert it back to a u8int... And my first implementation had an off-by-one error, which meant that I needed to take the slice of the interpreted array.

Perhaps this helps someone, else I'll try to create a PR in the next couple of days.

ineiti commented 4 years ago

Finally figured out how to use getBytes. #76