(04-29-2022, 08:27 AM)Ahmed Sayed Wrote: Any ideas on how to handle client side in C++ builder code not Delphi?
The procedure is exactly the same in C++Builder as it is in Delphi.
If you are using an up-to-date version of Indy, you can use the hoNoReadMultipartMIME flag in the TIdHTTP::HTTPOptions property.
Enable the flag, and then call TIdHTTP::Get() to begin the streaming. When TIdHTTP.Get() exits, check to make sure that the response's ResponseCode is 200 and ContentType is "multipart/x-mixed-replace", and if so then you can manually read the server's pushed updates from the TIdHTTP::IOHandler as needed until disconnected.
You can use TIdMessageDecoderMIME to help you parse the incoming MIME data, for example:
Code:
IdHTTP1->HTTPOptions = IdHTTP1->HTTPOptions << hoNoReadMultipartMIME;
IdHTTP1->Get(_D("http://server/stream"));
if (IdHTTP1->ResponseCode != 200 || !IsHeaderMediaType(IdHTTP1->Response->ContentType, _D("multipart/x-mixed-replace"))) return;
String LBoundary = ExtractHeaderSubItem(IdHTTP1.Request->ContentType, _D("boundary"), QuoteHTTP);
// or: String LBoundary := IdHTTP1->Response->RawHeaders->Params[_D("Content-Type"), _D("boundary")];
String LBoundaryStart = _D("--") + LBoundary;
String LBoundaryEnd = LBoundaryStart + _D("--");
do
{
String LLine = IdHTTP1->IOHandler->ReadLn();
if (LLine == LBoundaryStart) break;
if (LLine == LBoundaryEnd) return;
}
until (true);
TIdTCPStream *Stream = new TIdTCPStream(IdHTTP1);
try
{
TIdMessageDecoder *LDecoder = new TIdMessageDecoderMIME(NULL);
try
{
bool LMsgEnd = false;
do
{
static_cast<TIdMessageDecoderMIME*>(LDecoder)->MIMEBoundary = LBoundary;
LDecoder->SourceStream = Stream;
LDecoder->FreeSourceStream = false;
LDecoder->ReadHeader();
switch (LDecoder->PartType())
{
case mcptText:
case mcptAttachment:
{
TMemoryStream *LMStream = new TMemoryStream;
try
{
TIdMessageDecoder *LNewDecoder = LDecoder->ReadBody(LMStream, LMsgEnd);
try
{
// process LMStream as needed...
}
catch (const Exception &)
{
delete LNewDecoder;
throw;
}
delete LDecoder;
LDecoder = LNewDecoder;
}
__finally
{
delete LMStream;
}
break;
}
case mcptIgnore:
{
FreeAndNil(LDecoder);
LDecoder = new TIdMessageDecoderMIME(NULL);
break;
}
case mcptEOF:
{
LMsgEnd = true;
break;
}
}
}
while (LDecoder && !LMsgEnd);
}
__finally
{
delete LDecoder;
}
}
__finally
{
delete Stream;
}
