一个应用服务器(COM+)与客户端的数据流传送问题。(50分)

  • 主题发起人 主题发起人 特尔斐
  • 开始时间 开始时间

特尔斐

Unregistered / Unconfirmed
GUEST, unregistred user!
我想在应用服务器上将数据打包,然后将数据流返回到客户端。可是
TADOQuery没有SaveTostream的方法,这样,我必须先SaveToFile再用
内存流LoadFromFile才行。有没有不必经过这种转换的方法?
注:此应用不使用数据提供者(TDataSetProvider)。
 
使用 olevariant
---------------------
服务端创建数据集作为 olevariant
TreomteObj.getdata:olevariant
var data:recordset;
begin
data:=corecordset.create;
data.open('select * from XXXX',,,);
result:=data;
data:=nil;
end

客户端 使用 adotable.recordset:=Iunknown(reomteObj.getdata) as _recordset
 
做这方面的软件必须对COM/DCOM非常熟悉,配起来有点麻烦,先给分,才讲怎样建立一个应用服务器层。
 
to :畅雨
谢谢你的回答,这个方法我知道。可能我没说清楚,我要将数据集放到
一个TMemoryStream中,经过一些处理,再将此TMemoryStream的内容转换
为OleVariant传回客户端。现在卡在一个地方,就是TMemoryStream与
OleVariant如何相互转换。
to :saiyue
如果你只能告诉我“怎样建立一个应用服务器层。”的话,就不劳费心了,
如果你能解决我的实际问题,还会少了你的分吗?
此问题加到200分!只给一个解决此问题的人。
 
这两种数据类型的转换,以前的帖子也有,好像是
VarArrayCreate([0..100], varByte)
然后,再Lock, 复制内存即可
 
to LiChaoHui:
能详细点吗?解决后,200分为您送上!
 
function StreamToVariant(stream:TStream):variant;
procedure VariantToStream(AVariant:variant;
stream:TStream);
function StreamToVariant(stream:TStream):variant;
var
p:PChar;
begin
stream.Seek(0,0);
Result:=VarArrayCreate([0,stream.Size - 1],VarByte);
try
p:=VarArrayLock(Result);
try
stream.ReadBuffer(p^,stream.Size);
finally
VarArrayUnlock(Result);
end;
except
Result:=Unassigned;
end;
end;

// Get contents of a variant and put it in a stream.
procedure VariantToStream(AVariant:variant;
stream:TStream);
var
p:PChar;
sz:integer;
begin
// Check if variant contains data and is an array.
if VarIsEmpty(AVariant) or VarIsNull(AVariant) or (not VarIsArray(AVariant)) then
exit;
sz:=VarArrayHighBound(AVariant,1);
p:=VarArrayLock(AVariant);
try
stream.WriteBuffer(p^,sz+1);
finally
VarArrayUnlock(AVariant);
end;
end;

 
顺便给你推荐kbmMemTable组件, 编写你这样的程序可能方便一些
它有个 AllData 的属性, 它也很容易从别的数据集复制数据
property AllData:variant read GetAllData write SetAllData;
上面的两个方法就是来自于它的源码
 
这儿还有些东西呢,有个工具单元,定义了很多函数
http://www.lemanix.com/NixUtils
procedure VariantToStream (const V: OLEVariant;
Stream : TStream);
var
P : Pointer;
begin
Stream.Position := 0;
Stream.Size := VarArrayHighBound (V, 1) - VarArrayLowBound (V, 1) + 1;
P := VarArrayLock (V);
Stream.Write (P^, Stream.Size);
VarArrayUnlock (V);
Stream.Position := 0;
end;

procedure StreamToVariant (Stream : TStream;
var V: OLEVariant);
var
P : Pointer;
begin
V := VarArrayCreate ([0, Stream.Size - 1], varByte);
P := VarArrayLock (V);
Stream.Position := 0;
Stream.Read (P^, Stream.Size);
VarArrayUnlock (V);
end;
 
还是不明白,
处理 TMemoryStream 跟处理OleVariant有什么区别,干吗还要转换来再转换去呢,
再说,OleVariant中可以保存MemoryStream呀
 
to: LiChaoHui
谢谢您!高手就是高手啊!
等我解决了这个问题马上给您敬献200分!
to: 畅雨:
还是有一些不同的!在我们的项目里有一些特殊的要求要这样做。还是谢谢你啦。
 
好久没人给我分了,先行谢过
to: 畅雨:
OleVariant可以在DCOM中传递, TStream能行吗?
主要用于DCOM中传递数据,
to 楼主:
其实,DataSetProvider中有现成的方法根据数据集生成Packet,
直接用Midas要方便的多啊,不知道楼主为什么不用,
愿听一下原因!
 
to LiChaoHui:
老大,你的分还少吗?[:D]
不过我讲话算数,晚上发分。
我知道TDataSetProvider可以生成数据包,但我的要求比较特殊,我要对从数据库服务器
取得的记录集压缩、加密。。。等等,所以我在应用服务器上没有使用TDataSetProvider,
而是通过接口函数来传递记录集
(单向的,传给客户端就不管了,客户端也不要更新回来)。
to 各位:
我的问题马上就可以解决了!谢谢!
 
to 特尔斐,
有谁嫌过自己的钱多吗?
忍不住要打击你一下了,
你的要求完全可以用Midas-SocketConnection来实现,
其实,你可以采用SocketConnection
它在发送或接收数据之前,允许用户定义一个对象进行数据处理
包括压缩或加密,甚至你可以自己修改一下SConnect.pas
www.playicq.com 上面有个我的修改版,支持zlib快速数据压缩
另外,我还发现了SConnect.pas 的一个连接时假死的漏洞,
相关链接以及解决方法在:
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1848198
playicq
http://61.132.118.185:8080/dispdocnew.php?id=4602
 
to LiChaoHui:
非常谢谢您!何来打击之说?况且没有打击哪有进步呢?我正在下载您的大作,我会尝
试改用您说的方法看看。谢谢您!
 
还给不给我分了啊?
 
to LiChaoHui:
老大,我开了贴子给分,您就是不去拿:
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1883234
呵呵,客人不到,陪客的来了一大堆,您说要不要给他们分点分啊?[:D][:D][:D]
 
to LiChaoHui:
下面还有您的两百分:
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1883234
 
后退
顶部