我使用向导创建了一个独立的Datasnap TCP/IP服务器。我选择了示例方法(回声串和反转串)。我保存了服务器并运行了它。然后我创建了一个客户端应用程序,并使用file-new-other,将ClientModule和ClientClasses单元一起添加到该客户端项目。在主要形式上。我添加了一个按钮。在按钮的onclick事件处理程序,添加以下代码:Delphi 10西雅图Datasnap错误:“操作失败,连接已关闭。”
procedure TForm1.Button1Click(Sender: TObject);
begin
if ClientModule1.SQLConnection1.Connected then
begin
Button1.Text := 'Open';
ClientModule1.SQLConnection1.Close;
end
else
begin
Button1.Text := 'Close';
// ClientModule1.SQLConnection1.Open;
ClientModule1.ServerMethods1Client.ReverseString('myteststring');
end;
end;
这里的目的是模拟在客户端的登录和退出服务器的规律,而不是保持连接的情况。这对于部署到移动设备的应用程序尤为重要。
您可以看到我注释掉了Connection.Open,因为第一次调用ServerMethods1client会打开连接。生成的代码如下所示:
function TClientModule1.GetServerMethods1Client: TServerMethods1Client;
begin
if FServerMethods1Client = nil then
begin
SQLConnection1.Open;
FServerMethods1Client := TServerMethods1Client.Create(SQLConnection1.DBXConnection, FInstanceOwner);
end;
Result := FServerMethods1Client;
end;
现在问题出现了。首先点击按钮,打开连接,并调用该方法。在第二次点击按钮时,连接关闭。 在第3次点击时,会引发TDBXCommand代码引发的异常“操作失败。连接已关闭”。
作为一种变通方法,我尝试这样做:
procedure TForm1.Button1Click(Sender: TObject);
begin
if ClientModule1.SQLConnection1.Connected then
begin
Button1.Text := 'Open';
ClientModule1.SQLConnection1.Close;
ClientModule1.ServerMethods1Client := nil;
end
else
begin
Button1.Text := 'Close';
// ClientModule1.SQLConnection1.Open;
ClientModule1.ServerMethods1Client.ReverseString('myteststring');
end;
end;
这不排序的解决这个问题,因为ClientModule1的FServerMethods1Client实例被重置,以便在创建代码,就像它在第一次运行再次运行。
现在唯一的其他问题是(我正在使用Eurekalog)它会产生内存泄漏。
我在做什么错?无需重新启动应用程序,连接/断开Datasnap服务器的正确方法是什么?
这是有效的,但只要连接打开就保持客户端代理实例的分配效率更高,而不是每次创建和销毁新实例。内存分配/管理很昂贵,尤其是与替代方案相比(不重复执行)。 –
当你提供的信息真的不是对原始问题的回答时,我很困惑你回答了你自己的问题并将其标记为答案。 –
当然欢迎您提供完整的答案。与此同时,我自己的回答就足够了,不是吗? – nolaspeaker