求助:一个应用程序服务器使用两个或多个不同远程数据模块,为何其中一个引用另一个会出错?(200分)

  • 主题发起人 主题发起人 Ktcs
  • 开始时间 开始时间
K

Ktcs

Unregistered / Unconfirmed
GUEST, unregistred user!
各位庄家:
由于多人同时开发应用程序服务器,每人都建立自己的远程数据模块,其中一个数据模块调用另一个数据模块中定义的Object并给予赋值,结果程序提示灾难性错误,如何解决?
其中一个数据模块:
type
TDmMain = class(TRemoteDataModule, IDmMain)
private
{ Private declarations }
protected
public
end;
同时该模块中又定义如下的Object
TStaff = class(TObject)
private
function GetNextOfficeCode: string;
function GetAreaCode: string;
procedure FreeRights;
procedure GetRights;
public
//单位信息
DUTY_OFFICE_CODE: string;
DUTY_OFFICE_NAME: string;
//部门信息
DEPT_CODE: string;
DEPT_NAME: string;
//员工信息
STAFF_CODE: string;
STAFF_NAME: string;
STS: string;
LoginCryptogram: string;
//登录密码
LoginCode: string;
//登录员工号
RightList: TStringList;
//权限列表
procedure GetStaffInfo;
procedure RegLogoutSystem(var sLogon: string);

constructor Create;
destructor Destroy;
override;
protected
end;
同时定义
var
DMMain: TDMMain;
Me: TStaff;
另一个数据模块包含该单元uses udmmain;同时引用并赋值
type
TLogin = class(TRemoteDataModule, ILogin)
SPGetUser: TOraStoredProc;
SPGetPassWord: TOraStoredProc;
SP_GetSessionCount: TOraStoredProc;
SPKillCurrentSession: TOraStoredProc;
private
{ Private declarations }
protected
class procedure UpdateRegistry(Register: Boolean;
const ClassID, ProgID: string);
override;
function sp_get_username(const i_duty_office_code,
i_staff_code: WideString): WideString;
safecall;
function GetStaff_Code(const GetAreaCode,
EdStaff_Code: WideString): WideString;
safecall;
public
{ Public declarations }
end;
function TLogin.sp_get_username(const i_duty_office_code,
i_staff_code: WideString): WideString;
begin
result := 'Love'+copy(i_duty_office_code,3,6)+'00'+i_staff_code;
end;
//获得登录数据库的员工号,根据客户端的登录机关、员工号进行用户转换
function TLogin.GetStaff_Code(const GetAreaCode,
EdStaff_Code: WideString): WideString;
begin
Me.LoginCode := edStaff_Code;
Me.DUTY_OFFICE_CODE := GetAreaCode[red];--对另一个数据模块中的Object进行赋值[:(][/red] Result := sp_get_username(GetAreaCode,edStaff_Code);
end;
 
建多个远程数据模块,不行吧?
 
你的ME没有创建吧?
 
你定义了两个全局变量,以为那对象就会自动创建吗?
而且即使创建了也不能直接使用,它们在不同的Apartment中.
 
其实应该把他们当作不同的程序
 
那么应该如何创建和使用呢,请高手指教!我的程序就卡在这边啦!应用程序服务器中凡是
对该Object操作,前台客户端socketconnection1.appserver.method一调用便出现灾难性错误?
 
定义局部变量
在使用前创建它,使用完释放不就行了
 
我不是要这样的,因为该object(Tstaff)保留了用户的相关信息,在其它模块中还要应用到它,若为局部变量则无法再次使用登录成功后保留的信息。
 
不好意思,不太明白你的思路
在你的系统中是否每个客户端对应一个TStaff的实例,你是否想在一个客户端连接一个Remote DataModule时,这个Remote DataModule能使用对应的TStaff的实例
如果是这样,问题好象不太好解决
 
不能直接调用,应在调用模块的接口内定义一个属性,通过函数获取被调用模块的接口
例子demos/midas/sharedconn中有,你自己看吧
 
to:wfzha 谢谢你的解答。
to:siyan 兄台,我要设计的正是在系统中每个客户端对应一个TStaff的实例,在一个客户端连接一个Remote DataModule时,这个Remote DataModule能使用对应的TStaff的实例。
如果把Tstaff实例转移到客户端如何?请指教!
 
这个问题我好像遇到过,记不清是COM+调用COM+还是你这样远程调用远程时出现的,后来我发现是没有进入COM环境才会不能进行远程调用,你加这两句在调用前后试试:
..
begin
CoInitialize(nil);
...........
..........
CoUninitialize;
end;

或者加这句试试:
...
begin
application.initialize;
........
...........
 
试试我的办法吧,这个问题我以前遇到过,就是那样解决的。
 
to ktcs
把TStaff实例转移到客户端应该是可以运行的,但是感觉这样做不太好
我再想想
 
to:siyan 真的谢谢你的热心,希望你能搞定;
to:wfzha,xiaasp,请问即使能够正常调用,Tstaff实例的属性值会被不同的用户所更改,或者说它会为前台不同客户端保留不同的值吗(即使它定义的是全局变量)?
谢谢各位庄家指导!!!
 
能否这样呢:
TDmMain 里面维护一个可变的TStaff实例数组(有多少个连接就有多少个),
并在客户端连接TDmMain 时通过一个方法返回其对应Staff实例在数组中的索引MYINDEX
客户端连接其余Remote DataModule之后,通过一个方法把刚才获取的索引传递至Remote DataModule,在这个Remote DataModule里创建TDMMain的实例,并调用TDMMain实例的方法
返回索引为MYINDEX的STAFF实例(TDMMain必须实现这个方法)
这样你程序旧有的接口不需要做什么改变,只需增加几个方法就行了。
你看呢?
 
如何解决无状态对象与需要客户端的信息,可以参见李维的书,另delphi下有例子
demos/midas/pooler
忘了告诉你,好象是通过TClientDataset的BeforegetRecord事件读写
OwnerData来做的
 
to:siyan 我感觉此法甚好,可如何创建TStaff实例数组?然后通过MYINDEX如何重新动态创建这个Tstaff实例呢?还有:返回索引为MYINDEX的STAFF实例(TDMMain必须实现这个方法)此法恐怕很难实现,兄台可否展示一下?万分感激
to:wfzha 请问李维那本书有介绍?delphi的例子demos/midas/pooler你能大致解释一下吗?通过TClientDataset的BeforegetRecord事件读写OwnerData来做之前如何对应呢,它可是无状态的?望不吝赐教。

 
delphi5.x 分布式多层应用系统篇
pooler 主要是实现了客户端连接pooling,管理和共享连接。同时也用到了前面说的技巧。
和siyan说得差不多,就是有一个最大限制。
其实李维的书里,这方面没提几句,还是看例子吧
 
1、在tdmMain的oncreate事件里创建,SetLength(StaffArray,High(StaffArray)+2);
在tdmMain里增加一个CurIndex属性,CurIndex:=High(StaffArray)
公布一个获取CurIndex的方法GetStaffIndex(var Index:variant);
2、根据Index获取Staff实例
function tdmMain.getStaff(index:integer):TStaff;
begin
result:=StaffArray[Index]
end;
 

Similar threads

后退
顶部