从服务器到客户端的大流传输失败

时间:2017-02-16 16:52:44

标签: delphi datasnap firedac

所有

我正在开发基于位于C:\ Users \ Public \ Documents \ Embarcadero \ Studio \ 18.0 \ Samples \ Object Pascal \ DataSnap \ FireDAC_DBX中的示例项目的新datasnap项目。

我正在尝试将一个大流(1,606,408字节)从datasnap服务器传输到客户端。我遇到了一个似乎是常见问题的问题,那就是整个流不会传到客户端。

这是我的服务器代码:

//Returns Customer Info
function TServerMethods.GetBPInfo(CardCode : String): TStringStream;
begin
  Result := TStringStream.Create;
  try
    qBPInfo.Close;
    if CardCode.Trim = '' then
       qBPInfo.ParamByName('ParmCardCode').AsString := '%%'
    else
       qBPInfo.ParamByName('ParmCardCode').AsString := '%' + CardCode + '%';
    qBPInfo.Open;
    FDSchemaAdapterBPInfo.SaveToStream(Result, TFDStorageFormat.sfBinary);
    Result.Position := 0;
    //    Result.SaveToFile('output.adb');
    except
       raise;
  end;
end;

这是我的客户代码:

procedure TdmDataSnap.GetBPInfo(CardCode : String);
var
  LStringStream : TStringStream;
begin
  dmDataSnap.FDStoredProcBPInfo.ParamByName('CardCode').AsString := CardCode;
  FDStoredProcBPInfo.ExecProc;
  LStringStream := TStringStream.Create(FDStoredProcBPInfo.ParamByName('ReturnValue').asBlob);
  //LStringStream.Clear;
  //LStringStream.LoadFromFile('Output.adb');
  try
    if LStringStream <> nil then
    begin
      LStringStream.Position := 0;
      try
        DataModuleFDClient.FDSchemaAdapterBP.LoadFromStream(LStringStream, TFDStorageFormat.sfBinary);
      except
        on E : Exception do
        showmessage(e.Message);
      end;
    end;
  finally
    LStringStream.Free;
  end;
end;

您将看到流保存和加载代码;这就是我如何确定服务器将整个结果集放入流中,以及客户端可以处理整个结果集并正确显示它。

所以较小的流传输得很好,但是当在ide调试器中检查时,这个较大的流不会以65,66,68,83个字符开头,并且负载因错误而失败,&#39; [FireDAC] [斯坦] -710。二进制存储格式无效&#39;。

我从扩展的谷歌搜索中了解到这方面的解决方法,但我不明白如何使用Tfdstoredproc和TfdSchemaAdaptor组件将变通方法应用于我的案例。我试图继续使用这种编码方案。

如何调整此代码以正确接收大流?

更新1:

好的,我尝试过字符串和Base64编码。它没有用。

客户代码:

procedure TdmDataSnap.GetBPInfo(CardCode : String);
var
  LStringStream : TStringStream;
  TempStream  : TStringStream;
begin
  dmDataSnap.FDStoredProcBPInfo.ParamByName('CardCode').AsString := CardCode;
  FDStoredProcBPInfo.ExecProc;
  try
    TempStream := TStringStream.Create;
    TIdDecoderMIME.DecodeStream(FDStoredProcBPInfo.ParamByName('ReturnValue').asString,TempStream);
    if TempStream <> nil then
    begin
      TempStream.Position := 0;
      try
        DataModuleFDClient.FDSchemaAdapterBP.LoadFromStream(TempStream, TFDStorageFormat.sfBinary);
      except
        on E : Exception do
        showmessage(e.Message);
      end;
    end;
  finally
    TempStream.Free;
  end;
end;

这是我的服务器代码:

//Returns Customer Info
function TServerMethods.GetBPInfo(CardCode : String): String;
var
  TempStream  : TMemoryStream;
  OutputStr   : String;
begin
  Result := '';
  TempStream := TMemoryStream.Create;
  try
    try
      qBPInfo.Close;
      if CardCode.Trim = '' then
        qBPInfo.ParamByName('ParmCardCode').AsString := '%%'
      else
        qBPInfo.ParamByName('ParmCardCode').AsString := '%' + CardCode + '%';
      qBPInfo.Open;
      FDSchemaAdapterBPInfo.SaveToStream(TempStream, TFDStorageFormat.sfBinary);
      TempStream.Position := 0;
      OutputStr := IdEncoderMIMEBPInfo.EncodeStream(TempStream);
      Result := OutputStr
    except
      raise;
    end;
  finally
    TempStream.Free;
  end;
end;

结果是一样的。

0 个答案:

没有答案