问题标签 [datasnap]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
515 浏览

delphi - How to find out current delta record in TPacketDataSet point to which record in TClientDataSet?

Let said i have a ClientDataSet1 link with TDataSetProvider to access database for data and i have opened the ClientDataSet1 ready for edit and did some changes, so at the end i have some delta. The delta being assigned to TPacketDataSet for easy resolve purpose before i call ClientDataSet1.ApplyUpdates. Is there anyway to find out the current record of TPacketDataSet is actually point to which record in TClientDataSet without call TDataSet.Locate as i believe TDataSet.Locate might slow down performance. I would like to locate TClientDataSet record while traversing TPacketDataSet for some editing purpose. I have some reason not to do this in TDataSetProvider.OnUpdateData due to some problem i face earlier here.

Thanks!

0 投票
1 回答
4257 浏览

delphi - TClientDataSet 不释放内存

我有一个 DataSnap 服务器,它创建一个 TSQLQuery、TDataSetProvider 和一个 TClientDataSet,它们对给定用户的会话是唯一的,用于从数据库中检索数据并将 TClientDataSet.Data(一个 OleVariant)发送到客户端。它工作得很好,除了一个问题。

当我通过调用其 Open 方法填充 TClientDataSet 时,分配的内存不会被释放,直到用户断开其客户端与 DataSnap 服务器的连接。随着用户使用应用程序并继续从 DataSnap 服务器检索数据,内存继续被分配(数百兆)。当用户断开连接时,所有内存都被释放。它需要在每次请求后释放分配的内存,以便长时间连接的用户不会因消耗所有 RAM 而导致服务器崩溃。

我认为在用户请求数据时创建 TSQLQuery、TDataSetProvider 和 TClientDataSet 组件可能会起作用,然后在每次请求后立即销毁它们。这并没有改变行为。RAM 继续分配,直到用户断开连接才释放。

为什么 DataSnap 服务器在使用 TClientDataSet 时要保留分配的内存,即使每次请求后组件都被销毁?

谢谢,詹姆斯

<<< 编辑:2011 年 7 月 7 日下午 6:23 >>>

根据 Jeroen 的建议,我创建了一个复制问题的小程序。有两个部分,服务器(4 个源文件)和客户端(4 个源文件)。如果有将文件附加到此讨论的功能,我还不能使用它 - 没有足够的声誉点...,所以我粘贴下面的代码。服务器是一项服务,因此必须在构建后进行注册(例如,C:\ProjectFolder\Server.exe /install)。

在构建服务器之前,设置 SQLConnection1 的属性,并编辑 ServerMethodsUnit1.pas 中的 SQL 语句。查看内存分配问题的唯一方法是在每个请求中检索相当数量的数据(例如,500k)。我要查询的表包括uniqueidentifiervarchar(255)varchar(max)nvarchar(max)intbitdatetime其他列。我验证了所有数据库数据类型都存在内存问题。传输到客户端的数据集越大,服务器在不释放内存的情况下分配内存的速度就越快。

构建两个应用程序并注册/启动服务后,使用 ProcessExplorer 查看服务器服务使用的内存。然后启动客户端,点击连接,点击按钮获取数据。请注意 ProcessExplorer 中服务器的内存增加。单击断开连接,观察内存全部释放。

服务器.dpr

ServerContainerUnit1.dfm

ServerContainerUnit1.pas

ServerMethodsUnit1.pas

客户端.dpr

ClientUnit1.dfm

ClientUnit1.pas

代理方法.pas

0 投票
1 回答
636 浏览

windows - 部署 Datasnap 服务

在 Rad Studio XE 下使用 C++ Builder 我从头开始创建了一个简单的 Datasnap 服务器服务。我想在添加任何功能之前测试服务安装过程,发现虽然它可以在一系列 Windows 机器上成功安装,但我无法在 Windows 7 x64 的全新安装下启动它。

尝试启动该服务的错误消息是:Windows 无法在本地计算机上启动该服务。错误2:系统找不到指定的文件。

我已经关闭了动态链接和运行时库。它在 Windows XP 和 2003 操作系统下启动良好,只是不是我拥有的这台 Win7 机器。我已经为指定的端口打开了防火墙,并确认没有其他应用程序也在使用它们。该服务安装在管理员下,并以本地系统帐户登录。

Windows 7 或 64 位下的 C++ Builder 编译服务是否存在问题?希望有人能指出我正确的方向,这样我就不必再用头撞墙了。

谢谢!

0 投票
4 回答
4604 浏览

delphi - 有没有办法将 JSONP 与 Delphi DataSnap REST 服务器一起使用?

似乎没有办法使用 DataSnap 实现JSONP(带填充的 JSON)解决方案,但我想在这里提出这个问题,以防有人解决了这个问题。

背景:JSONP 是一种利用 HTML 脚本元素的跨站点引用能力来克服 XmlHttpRequest 类的同源策略的机制。使用 XmlHttpRequest,您只能从提供 HTML 文档的同一域中获取数据(JSON 对象)。但是,如果您想从多个站点检索数据并将该数据绑定到浏览器中的控件,该怎么办?

使用 JSONP,脚本元素的 src 属性不会引用 JavaScript 文件,而是引用 Web 方法(可以驻留在检索 HTML 的不同域中的方法)。此 Web 方法返回 JavaScript。

script 标签假定返回的数据是一个 JavaScript 文件并正常执行。然而,Web 方法实际返回的是一个以文字 JSON 对象作为参数的函数调用。假设定义了调用的函数,该函数执行并可以对 JSON 对象进行操作。例如,该函数可以从 JSON 对象中提取数据并将该数据绑定到当前文档。

JSONP 的优劣已经被广泛争论(它代表了一个非常严重的安全问题),所以这里没有必要重复。

我感兴趣的是是否有人知道如何将 JSONP 与 Delphi 的 DataSnap REST 服务器一起使用。正如我所看到的,这就是问题所在。一个典型的 JSONP 用法可能包括一个如下所示的脚本标记:

getdata Web 方法将返回如下调用:

workit 函数可能看起来像这样:

问题是 DataSnap 似乎无法返回一个简单的字符串,例如

相反,它被包装,如下所示:

显然,这不是可执行的 JavaScript。

有任何想法吗?

0 投票
1 回答
524 浏览

delphi - Delphi DataSnapXE BroadcastMessage 错误

我有一个使用 TCP/IP 的 DatasnapXE 客户端服务器应用程序。服务器使用 TDSServer.broadcastmessage 向客户端广播消息 如果碰巧用户由于某种原因不再可用,DSServer 将触发 OnError 事件。

在 OnError 中,我无法弄清楚如何确定哪个用户已关闭?有可能吗?

最好的问候, 基里尔哈吉耶夫

0 投票
2 回答
1571 浏览

javascript - 为什么 OnUserAuthenticate 在 DataSnap REST 服务器上被调用两次?

我在 Delphi XE 中使用 DataSnap 创建了一个 REST Web 服务。我正在使用 XMLHttpRequest JavaScript 对象调用服务器方法。我在 XMLHttpRequest Open 方法的第四个和第五个可选参数中传递用户名和密码以进行身份​​验证。

当我在 Delphi 中加载我的 DataSnap 服务器并将调试器附加到 IIS(我使用的是 IIS 7.5)时,我可以看到第一次调用其中一个服务器方法会导致 DSAuthenticationManager 的 OnUserAuthenticate 事件被调用两次。

在第一次调用中,OnUserAuthenticate 事件处理程序的用户和密码参数是空字符串。在第二次调用中,我在 XMLHttpRequest Open 方法中传递的用户名和密码出现在这些参数中。

一旦用户通过身份验证,任何使用 XMLHttpRequest 对任何服务器方法的后续调用都会导致对 OnUserAuthenticate 事件处理程序的一次调用,用户的用户名和密码分别出现在用户和密码参数中。

我检查了许多 DataSnap 类的源代码,但没有找到会导致这种效果的代码,这使我认为这种行为可能源自浏览器或 IIS。

为什么 OnUserAuthenticate 在第一次服务器方法调用时被调用两次,是什么产生了这种效果?


为了回应 Mat DeLong 的回答,我展示了我用来调用服务器方法的通用函数之一。此特定方法进行同步调用。baseURL 参数通常是类似于http://mydomain.com/myservice/myservice.dll/datasnap/rest/tservermethods1的字符串,方法可能是 myservermethod。附加参数用于将参数传递给服务器方法:


编辑:Lex Li 似乎是正确的,IIS 仅在第一次请求失败时才使用基本身份验证。此外,Mat 正确的是 OnUserAuthenticate 每个会话只应调用一次。在检查了他提供的链接后,很明显我未能捕获并返回会话 ID。这是一个有效的代码示例,这次是异步的。它捕获 sessionid 并将其存储在隐藏字段中。然后,它在 Pragma 标头中的每个后续调用中将该会话 ID 传递回。


编辑:当我第一次发布这两个代码示例时,我在 XMLHttpRequest open 方法的第四个和第五个参数中包含了示例用户名和密码。我在测试期间明确地传递了这些值。不建议传递这样的参数,因此我在此编辑中删除了这些参数。如果您省略这些密码,并且不使用其他方法(例如在您的第一个 REST 服务器方法调用的标头中)传递它们,浏览器将显示一个对话框,询问用户此信息。提供用户名和密码后,浏览器将在会话的剩余部分中记住此信息。如果您关闭然后重新打开浏览器并调用另一个 REST 服务器方法,您将再次被要求输入用户名和密码。这当然假设,

0 投票
2 回答
6456 浏览

delphi - 在一个请求中从 DataSnap 服务器返回两个数据集

2012-06-27 发表评论

原始帖子有一些有用的代码,但并没有真正说明如何在来自客户端应用程序的一个请求中从 DataSnap 服务器返回多个数据集。要查看如何执行此操作的示例,请查看页面底部标记为正确的答案。


2011-08-31 评论

多亏了 Gunny,我又看了一遍。令人烦恼的问题是我自己的错误,现在已修复。通过在每个数据库查询之间创建/销毁组件,我可以在单个客户端到服务器请求中在 DataSnap 服务器上执行多个 SQL 语句。TSQLQuery

当我尝试解决一个众所周知的问题时,我在存储过程中留下了一行调试代码,该问题阻止您output在调用后访问参数TSQLStoredProc.Openhttp://qc.embarcadero.com/wc/qcmain.aspx? d=90211 )。

因此,即使我的问题解决了,原来的问题仍然存在——您不能调用该Open方法来提取数据然后访问output参数,并且您不能访问从单个存储过程返回的多个数据集。

再次感谢甘尼,您的建议。


原帖

我试图在一个请求中从 DataSnap 服务器返回两个不同的数据集。两者都来自同一个数据库。一种是单字段/单记录值,另一种是多字段/多记录数据集。

DataSnap 服务器有以下方法:

这行不通。即使我可以看到两个单独的请求都命中了数据库,但我无法访问第二个结果集。当我尝试时,(再次)返回第一个结果集而不是第二个结果集。

在我创建/销毁查询组件(每个客户端到服务器请求)之前,所有后续客户端到服务器请求都将返回第一个数据集。非常令人沮丧。创建/销毁查询组件解决了这个问题,但现在我在一个客户端执行多个查询到服务器请求,问题又回来了——即使执行新查询,也会返回第一个数据集。

我尝试了几种方法:

ONE:为第一个请求动态创建TSQLQuery组件,拉取 db 值,销毁TSQLQuery,创建一个新的TSQLQuery并拉取第二个数据集。那没有帮助。我可以使用SQL Server Profiler并观察两个命令都命中数据库,但第一个结果集显示为两个查询的数据集。

:做与#1相同,但使用TSQLStoredProcedure而不是TSQLQuery。结果是一样的。

:使用 aTSQLStoredProcedure并从同一个存储过程中返回两个数据集,如下所示:

自从TSQLStoredProcedure有了NextRecordSet,我曾希望访问这两个数据集,但没有乐趣。当我打电话时NextRecordSet,它会返回nil

:在一次调用中返回两个值以TSQLStoredProcedure使用数据集和output参数:

Delphi 代码如下所示:

我检查 sp.Params 并且有一个名为 的输入/输出参数valueoutput当还返回数据集时,我无法访问该参数。这是一个已知的错误(多年来):http: //qc.embarcadero.com/wc/qcmain.aspx ?d=90211

结论:

由于 DataSnap 服务器TSQLConnection与所有连接的客户端共享其主服务器,并且因为TSQLQuery(or TSQLStoredProc) 和TClientDataSet组件都是随每个请求创建/释放的,所以剩下的唯一可能是保留先前的数据集并将其返回到TSQLQueryandTSQLStoredProc组件是TSQLConnection组件。我尝试TSQLConnection.CloseDataSets在关闭和释放TSQLQuery(或TStoredProc)组件之前调用,但这也无济于事。

也许仔细研究TSQLConnection会有所帮助。以下是它在.dfm文件中的外观:

在运行时,我做了一些事情,这样我就不必为 DBX 驱动程序部署 .INI 文件。首先,让我注册自己的无 INI 驱动程序的单元:

上述方法包含在项目(.dpr 文件)中,并自行注册驱动程序。下一个方法利用它TSQLConnection在运行时(DataSnap 服务器启动时)设置 (sqlcon):

这些设置中的任何一个是否可能会弄乱TSQLConnection组件并使其缓存数据集并返回它们而不是最近TSQLQuery执行的组件?

任何帮助将不胜感激。正如你所知道的,这让我发疯了!

谢谢,詹姆斯

0 投票
2 回答
1314 浏览

delphi - Delphi XE 和 ServerMethods

使用 Delphi XE,我使用“DataSnap Server”向导创建了一个客户端-服务器应用程序。

ServerMethodUnitI Define a TSQLQuerywith sql property like this "Select * from TABLE"

我也定义了一个调用的函数ChangeSQLServerMethodUnit通过示例更改sql属性SELECT * from TABLE where ID = 5

当我通过调用ChangeSQL表单客户端应用程序时TSQLServerMethodChangeSQL函数更改SQL属性ServerMethodUnit,但是当它离开函数ChangeSQL时,TSQLQuery不包含新的sql命令但有原始的sql。

编辑:添加代码示例

我使用“DataSnap Server”向导创建了一个新的客户端-服务器应用程序。

ServerMethodsUnit

我把一个TSQLConnection到我的数据库。我打了一个TSQLQuery电话MyQuerySQL属性 = 'Select * from client' 我把TDataSetProvider一个TSQLQuery

并定义一个这样的函数:

//------------------------------------------------ // 此时,MyQuery.RecordCount = 所有记录(包括第一次和以后) // --------------------------- ---------------------

然后我使用“DataSnap 客户端”创建一个新应用程序

ClientModuleUni: 我放了一个,ClientDataSet调用MyClientDS和我的提供者。我在里面放了一个被调用的指向RemoteServerProviderNameMyQueryTSQLServerMethodMyMethodClientFilterServerMethodsUnit

在客户端应用程序的一个表格 然后我把ADataSource和aDBGrid放到MyClientDs并打开它。我放了一个Tbutton代码OnClick

DBGrid我看到客户端表的所有记录中,总是。

我尝试过滤ClientTable单击按钮,但DBGrid总是出现所有记录。

0 投票
1 回答
1858 浏览

delphi - Delphi XE Data Snap TCP/IP 客户端登录表单

(我看到了 Demo Dirt - 但它用于 HTTP Web,我不知道如何将其切换到 TCP/IP)我是 Delphi 的新手 - 我需要有关使用 DataSnap 和客户端登录表单的帮助(从 SQL Server 检查用户密码) 然后申请角色。任何代码或答案将不胜感激提前谢谢

0 投票
2 回答
1068 浏览

objective-c - 从 Delphi XE2 Datasnap Server 在 Xcode 中处理 TDataSet 结果

我正在研究使用 Delphi XE2 DataSnap 服务器将数据从 SQL 服务器推送到 iPad 应用程序的可行性。

我已经编写了 Datasnap 服务器应用程序,现在正在查看 iOS 应用程序。TServerMethod 在 iOS 中将数据作为 TDataSet 返回。不清楚的是如何在 Xcode 中将生成的 TDataSet 提取为 NSMutableArray?下面是 DSProxy.m 中生成的代码: -

}