I see you solved it by implementing the missing functionality using Indy. Indeed, that is what I would recommend. The IOHandler
in Indy should provide all necessary features one may need.
Our CastleClientServer
in a āsimple wrapperā around Indy deliberately, allows only passing Strings (which we assume have typical encoding, so UTF-8 with FPC and UTF-16 with Delphi), just because that seemed enough for its needs back when it was implemented
A PR to extend CastleClientServer
, to send/receive any binary buffer, would be welcome, itās of course a sensible feature to add (and you donāt want to āoveruseā strings for arbitrary binary data due to Unicode encoding assumptions and FPC/Delphi differences).
If someone wants to tackle this:
As API, I propose to add overloads with Buffer
suffix to send binary blobs, and pass them around them as const ABuffer; const BufferSize: Int64
(so itās just like TStream.WriteBuffer
API). So TCastleTCPServer
gets new methods:
// existing
procedure SendToClient(const AMessage: String; AClient: TClientConnection); virtual;
procedure SendToAll(const AMessage: String); virtual;
// new methods
procedure SendToClient(const ABuffer; const BufferSize: Int64; AClient: TClientConnection); virtual;
procedure SendToAll(const ABuffer; const BufferSize: Int64); virtual;
TCastleTCPClient gets new:
// existing
procedure Send(const AMessage: String); virtual;
// new
procedure SendBuffer(const ABuffer; const BufferSize: Int64); virtual;
And they are received using new callbacks:
// existing
TMessageReceivedEvent = procedure(const AMessage: String) of object;
TClientMessageReceivedEvent = procedure(const AMessage: String; AClientConnection: TClientConnection) of object;
// existing
TMessageBufferReceivedEvent = procedure(const ABuffer; const BufferSize: Int64) of object;
TClientMessageBufferReceivedEvent = procedure(const ABuffer; const BufferSize: Int64; AClientConnection: TClientConnection) of object;
( I wondered about a single callback to receive both types of message, maybe like record case MessageType: TMessageType of 0: Data: Pointer; DataSize: Int64; 1: Message: String
⦠) but it seems safer to expose separate callbacks for string receiving and binary blobs receiving. Opinions to the contrary are welcome
)
The examples should be extended to report it to, you can test passing e.g. TVector3
around.
Warning that it may take some effort to do this ā CastleClientServer
has actually 2 implementations (Indy, or using Android service) and we want them both to be functional (and able to call each other).