WebSocket read/write binary Data

how can I read and write binary (byte array) via websocket.
that with the strings works fine.
the problem is that i cannot transfer all byte values as a string (char).
The websocket string protocol doesn't like this.

Is there an example for the binary data, similar to the chat example.

At this moment, with the current release, use base64 encoding.
We internally already did extensions to handle binary data directly and that is coming in a following update.

Yes , currently we using the base64.
Can you give me a time horizon when this will be done?
Depending on that, we still have to do it with strings.

By the way, they always answer very quickly and that's great, thank you very much

1 Like

there is already news on this topic.
Possibly already a date for the integration?

You can already send binary data with the sample server code that is included via

procedure BroadcastData(AData: TBytes);

To receive binary data, in the next rleease there will be the following method to use in WebSocketClient.OnDataReceived:

  WebSocketClient.GetDataAsBytes(SocketData.jsobject, procedure(ABytes: TBytes)
  begin
    for i := 0 to Length(ABytes) - 1 do
      console.log(ABytes[i]);
  end);

then I hope the update will come soon. ((-;

It would be great if it were:

WebSocketClient1.Send (tempStr);

equivalent

WebSocketClient1.SendBytes (tempBytes);
procedure SendBytes (ABytes: TBytes);

is the BroadcastData procedure also new?

I didn't find it in the documentation 1.6.2.0

or in which demo project does occurrence?

BroadcastData() is in the sample server of v1.6.2.0 included in the FNC Chat demo.
Demo\FNC\Chat

It's a little too far away for me.

I don't understand why I should write to a web server now, or how I should do it with a WebSocketClient.

I can't find a Connection.SendBytes (AData); Access in the WebSocketClient.

I have a WebSocketClient connection with which I want to read and write bytes.

Reading has already been implemented in the next version. The only thing still missing is writing Bytes with the WebSocketClient.

WebSocketClient.Send() has an overload with parameter type TJSArrayBuffer which is the browser type for sending an array of bytes.

Sorry

Either they don't understand me or I don't understand them.

I have a controller that runs a server that supports websocket.

This server supports websocket communication as a byte array.

Now I would like to set up a connection to this server via TMS WebSocketClient and exchange the data via byte array.

As far as I know, this means that I can read and write byte arrays with the TMS WebSocketClient.

I cannot establish communication with this server on the controller with a second server.

I call up the IP address via Firefox (192.168.200.66:30000) then

the index.html and the Web.js file are uploaded from the Server.

Then a WebSocket connection to the server is opened with the WebSocketClient component:

WebSocketClient1.HostName: = HostIPAddr;

WebSocketClient1.Port: = StrToInt (HostPort);

WebSocketClient1.Connect;

everything works and i can read and send strings and here comes the problem:

In your web socket client implementation you can only send and read strings:

WebSocketClient1DataReceived

jo := SocketData.JSObject;

Str := jo.toString;

WebSocketClient1.Send (string); // s = string

and I would need a byte function for communication with the websocket server:

WebSocketClient1DataReceived

jo := SocketData.JSObject;

byteArray := jo.toByteArray; or something like that

WebSocketClient1.Send_binary (bytearray); or something like that

I have no idea how to solve it any other way.

Especially not how I should solve this with a WebSocketServer.

Here is another example to illustrate:

websocket ws = websocket.WebSocket ()

ws.connect ("ws: // xxxxxxxxxxx")

ws.send_binary ([100, 220, 130]) send buffer à byte 1 = 100 / byte 2 = 220 / byte 3 = 130 to web socket server

ws.send ("Hello world") send buffer à byte = 72 / byte 2 = 101 / byte 3 = 108 ... etc. to websocket server

ws.close ()

Since the byte data also contain byte = 00 or 01 or 245 or 255 etc. I cannot send them as a string.

I tried to simply copy the byte array into the string, but that doesn't work because the string is interpreted.

I repeat what I said:

  1. To RECEIVE binary data, in the NEXT release there will be a helper function
WebSocketClient.GetDataAsBytes(SocketData.jsobject, procedure(ABytes: TBytes)
  begin
    for i := 0 to Length(ABytes) - 1 do
      console.log(ABytes[i]);
  end);

that can be used in the OnDataReceived event handler to get the data as byte array

  1. To SEND binary data there is already an overload of the WebSocketClient.Send() method:

WebSocketClient.Send(abuf: TJSArrayBuffer);

with which you can send an array of bytes

Is there an example similar "FNC\Chat" that transmits bytes instead strings?
I've rebuilt that to the best of my knowledge, but there are some byte values just not the one I'm sending.
Are the bytes coded or can I really send and receive 1 to 1 bytes?

implementation:

WBSrByte = ReadBytesBuffer = array[0..xxxxx] of byte;
WBSwByte = WriteByteBuffer = array[0..xxxxx] of byte;

DataReceived
jo := SocketData.JSObject;
WebSocketClient1.GetDataAsBytes(jo, procedure(ABytes: TBytes)
begin
for i := 0 to Length(ABytes) - 1 do
WBSrByte[i] := ABytes[i];
end);

Sendroutine

var
JSarrBytes : TJSArrayBuffer;
JSarrByte : TJSUint8Array;

procedure SetJSarrBytes;
var
i : integer;
begin
JSarrBytes := TJSArrayBuffer.New(WBSwCounts);
JSarrByte := TJSUint8Array.new(JSarrBytes);
for i := 0 to (WBSwCounts - 1) do
JSarrByte[i] := WBSwByte[i];
end;

SetJSarrBytes;
WebSocketClient1.Send(JSarrBytes);

You can send bytes as-is.
As far as I can judge, your client code looks OK

Ok it going. The problem was with the web server and the HASH of the oder Site.

But now I have a processing problem:

The following sequence of calls:

procedure Tfm_Start.WebSocketClient1DataReceived(Sender: TObject; Origin: string;
SocketData: TJSObjectRecord);

within DataReceived

WebSocketClient1.GetDataAsBytes(SocketData.JSObject, procedure(ABytes: TBytes)
2 begin
for i := 0 to Length(ABytes) - 1 do begin
WBSrByte[i] := ABytes[i];
end;
end);

3 and then access
if WBSrByte[x] = 1 then ...

when I run it in the browser the WBSrByte is 0.
With the Debuuger I see that the "DataReceived" routine is terminated first and then the procedure "(SocketData.JSObject, procedure (ABytes: TBytes) ..." is processed.

So this order 3 and after that 2.
But I would like this sequence 2 and then 3

How can I change this.

An anonymous method here in this case is called asynchronously because GetDataAsBytes() internally calls an asynchronous JavaScript function. You could use async/await if you want to pseudo serialize this code.
See:


or
https://wiki.lazarus.freepascal.org/pas2js_AsyncAWait#:~:text=Pas2js%20supports%20the%20JS%20operators,the%20next%20and%20so%20forth.