問題タブ [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.
delphi - TPacketDataSet の現在のデルタ レコードが TClientDataSet のどのレコードを指しているかを調べる方法は?
データのデータベースにアクセスするための TDataSetProvider との ClientDataSet1 リンクがあり、ClientDataSet1 を編集の準備ができて開いていくつかの変更を行ったので、最後にいくつかのデルタがあるとしましょう。ClientDataSet1.ApplyUpdates を呼び出す前に、簡単に解決できるように TPacketDataSet に割り当てられているデルタ。TPacketDataSet の現在のレコードが実際に TDataSet.Locate を呼び出さずに TClientDataSet のどのレコードを指しているかを調べる方法はありますか? TDataSet.Locate はパフォーマンスを低下させる可能性があると考えています。編集目的で TPacketDataSet をトラバースしながら、TClientDataSet レコードを見つけたいと思います。ここで以前に直面した問題のため、TDataSetProvider.OnUpdateData でこれを行わない理由があります。
ありがとう!
delphi - TClientDataSet がメモリを解放しない
特定のユーザーのセッションに固有の TSQLQuery、TDataSetProvider、および TClientDataSet を作成する DataSnap サーバーがあります。これらは、データベースからデータを取得し、TClientDataSet.Data (OleVariant) をクライアントに送信するために使用および再利用されます。1つの問題を除いて、非常にうまく機能します。
Open メソッドを呼び出して TClientDataSet を設定すると、割り当てられたメモリは、ユーザーがクライアントを DataSnap サーバーから切断するまで解放されません。ユーザーがアプリケーションを使用して DataSnap サーバーからデータを取得し続けると、メモリが引き続き割り当てられます (数百メガバイト)。ユーザーが切断すると、すべてのメモリが解放されます。長時間接続しているユーザーがすべての RAM を消費してサーバーをクラッシュさせないように、各要求の後に割り当てられたメモリを解放する必要があります。
ユーザーがデータを要求したときに TSQLQuery、TDataSetProvider、および TClientDataSet コンポーネントを作成し、各要求の後にすぐにそれらを破棄することがうまくいくと思いました。これは動作を変更しませんでした。RAM は引き続き割り当てられ、ユーザーが切断するまで解放されません。
TClientDataSet を使用すると、各要求の後でコンポーネントが破棄される場合でも、DataSnap サーバーが割り当てられたメモリを保持するのはなぜですか?
ありがとう、ジェームズ
<<< 編集 : 2011 年 7 月 7 日 18:23 >>>
Jeroen の推奨に従って、問題を再現する小さなプログラムを作成しました。サーバー (4 つのソース ファイル) とクライアント (4 つのソース ファイル) の 2 つの部分があります。このディスカッションにファイルを添付する機能がある場合、まだ使用できません。評価ポイントが不足しているため、以下にコードを貼り付けます。サーバーはサービスであるため、構築後に登録する必要があります (例: C:\ProjectFolder\Server.exe /install
)。
サーバーを構築する前に、SQLConnection1 のプロパティを設定し、ServerMethodsUnit1.pas の SQL ステートメントを編集します。メモリ割り当ての問題を確認する唯一の方法は、各リクエストでかなりの量のデータ (たとえば、500k) を取得することです。クエリを実行しているテーブルには、、、、、、、およびその他の列uniqueidentifier
が含まれます。すべてのデータベース データ型でメモリの問題が発生することを確認しました。クライアントに転送されるデータセットが大きいほど、サーバーはメモリを解放せずにすばやくメモリを割り当てます。varchar(255)
varchar(max)
nvarchar(max)
int
bit
datetime
両方のアプリがビルドされ、サービスが登録/開始されたら、ProcessExplorer を使用して、サーバー サービスによって使用されるメモリを表示します。次に、クライアントを起動し、[接続] をクリックし、ボタンをクリックしてデータを取得します。サーバーの ProcessExplorer のメモリが増加していることに注意してください。[切断] をクリックして、メモリがすべて解放されるのを確認します。
サーバー.dpr
ServerContainerUnit1.dfm
ServerContainerUnit1.pas
ServerMethodsUnit1.pas
クライアント.dpr
ClientUnit1.dfm
ClientUnit1.pas
ProxyMethods.pas
windows - Datasnapサービスの展開
RadStudioXEでC++Builderを使用して、単純なDatasnapサーバーサービスを最初から作成しました。機能を追加する前にサービスのインストールプロセスをテストしたかったのですが、さまざまなWindowsマシンに正常にインストールできますが、Windows7x64のクリーンインストールでは開始できませんでした。
サービスを開始しようとしたときのエラーメッセージは次のとおりです。Windowsはローカルコンピューターでサービスを開始できませんでした。エラー2:システムは指定されたファイルを見つけることができません。
ダイナミックリンクとランタイムライブラリの両方をオフにしました。私が持っているこの単一のWin7マシンだけでなく、WindowsXPおよび2003オペレーティングシステムでも正常に起動します。指定されたポートのファイアウォールを開き、他のアプリもそれらを使用していないことを確認しました。サービスは管理者の下にインストールされ、ローカルシステムアカウントとしてログオンします。
Windows7または64ビットでのC++Builderコンパイル済みサービスに問題はありますか?誰かが私を正しい方向に向けることができれば、壁に頭をぶつける必要がなくなります。
ありがとう!
delphi - Delphi DataSnap RESTサーバーでJSONPを使用する方法はありますか?
DataSnapを使用してJSONP (JSON with Padding)ソリューションを実装する方法はないようですが、誰かがこの問題を解決した場合に備えて、この質問をここに投げ出します。
背景:JSONPは、HTMLスクリプト要素のクロスサイト参照機能を利用して、XmlHttpRequestクラスの同一生成元ポリシーを克服するメカニズムです。XmlHttpRequestを使用すると、HTMLドキュメントを提供したのと同じドメインからのみデータ(JSONオブジェクト)を取得できます。しかし、複数のサイトからデータを取得し、そのデータをブラウザーのコントロールにバインドする場合はどうでしょうか。
JSONPでは、script要素のsrc属性はJavaScriptファイルを参照しませんが、代わりにWebメソッド(HTMLが取得された別のドメインに存在できるメソッド)を参照します。このWebメソッドはJavaScriptを返します。
スクリプトタグは、返されたデータがJavaScriptファイルであると想定し、通常どおりに実行します。ただし、Webメソッドが実際に返すのは、パラメーターとしてリテラルJSONオブジェクトを使用した関数呼び出しです。呼び出される関数が定義されていると仮定すると、関数は実行され、JSONオブジェクトを操作できます。たとえば、この関数はJSONオブジェクトからデータを抽出し、そのデータを現在のドキュメントにバインドできます。
JSONPの長所と短所は広く議論されているため(これは非常に深刻なセキュリティ問題を表します)、ここでそれを繰り返す必要はありません。
私が興味を持っているのは、DelphiのDataSnapRESTサーバーでJSONPを使用する方法を誰かが理解しているかどうかです。私が見ているように、ここに問題があります。典型的なJSONPの使用法には、次のようなスクリプトタグが含まれる場合があります。
getdata Webメソッドは、次のような呼び出しを返します。
そして、workit関数は次のようになります。
問題は、DataSnapが次のような単純な文字列を返すことができないように見えることです。
代わりに、次のようにラップされます。
明らかに、これは実行可能なJavaScriptではありません。
何か案は?
delphi - DelphiDataSnapXEBroadcastMessageエラー
TCP/IPを使用するDatasnapXEクライアントサーバーアプリケーションがあります。TDSServer.broadcastmessageを使用してクライアントにメッセージをブロードキャストするサーバー何らかの理由でユーザーが利用できなくなった場合、DSServerはOnErrorイベントを発生させます。
OnErrorで、どのユーザーがダウンしているかを判断する方法がわかりませんか?それは可能ですか?
よろしく、キリルハジエフ
javascript - DataSnap REST サーバーで OnUserAuthenticate が 2 回呼び出されるのはなぜですか?
Delphi XE で DataSnap を使用して REST Web サービスを作成しました。XMLHttpRequest JavaScript オブジェクトを使用してサーバー メソッドを呼び出しています。XMLHttpRequest Open メソッドの 4 番目と 5 番目のオプション パラメータで、認証用のユーザー名とパスワードを渡しています。
DataSnap サーバーを Delphi にロードし、デバッガーを IIS にアタッチすると (IIS 7.5 を使用しています)、サーバー メソッドの 1 つを初めて呼び出すと、DSAuthenticationManager の OnUserAuthenticate イベントが 2 回呼び出されることがわかります。
最初の呼び出しでは、OnUserAuthenticate イベント ハンドラーのユーザーとパスワードのパラメーターは空の文字列です。2 回目の呼び出しでは、XMLHttpRequest Open メソッドで渡したユーザー名とパスワードがこれらのパラメーターに表示されます。
ユーザーが認証されると、その後 XMLHttpRequest を使用していずれかのサーバー メソッドを呼び出すと、OnUserAuthenticate イベント ハンドラーが 1 回呼び出され、ユーザーのユーザー名とパスワードがそれぞれ user パラメーターと password パラメーターに表示されます。
多くの DataSnap クラスのソース コードを調べましたが、この影響を引き起こすコードは見つかりませんでした。このため、この動作はブラウザまたは IIS に起因するのではないかと考えています。
最初のサーバー メソッド呼び出しで OnUserAuthenticate が 2 回呼び出されるのはなぜですか? また、何がこの影響を生み出しているのですか?
Mat DeLong の回答に応えて、サーバー メソッドを呼び出すために使用している汎用関数の 1 つを示しています。この特定のメソッドは、同期呼び出しを行います。通常、baseURL パラメーターはhttp://mydomain.com/myservice/myservice.dll/datasnap/rest/tservermethods1のような文字列で、メソッドは myservermethod の場合があります。追加のパラメーターを使用して、サーバー メソッドにパラメーターを渡します。
編集: Lex Li は正しいようです。IIS は、最初の要求で失敗した場合にのみ基本認証を使用します。また、OnUserAuthenticate はセッションごとに 1 回だけ呼び出す必要があるという Mat の指摘は正しいです。彼が提供したリンクを調べたところ、セッション ID を取得して返すことに失敗していたことが明らかになりました。今回は非同期で動作するコードの例を次に示します。sessionid をキャプチャし、隠しフィールドに格納します。その後、Pragma ヘッダー内の後続の各呼び出しでそのセッション ID を返します。
編集: これら 2 つのコード サンプルを最初に投稿したとき、サンプルのユーザー名とパスワードを XMLHttpRequest オープン メソッドの 4 番目と 5 番目のパラメーターに含めました。テスト中にこれらの値を明示的に渡していました。このようなパラメーターを渡すことはお勧めできないため、この編集でこれらのパラメーターを削除しました。これらのパスワードを省略し、別のメソッド (最初の REST サーバー メソッド呼び出しのヘッダーなど) を使用してパスワードを渡さない場合、ブラウザーはユーザーにこの情報を求めるダイアログ ボックスを表示します。ユーザー名とパスワードが提供されると、ブラウザーはセッションの残りの間、この情報を記憶します。ブラウザーを閉じてから再度開き、別の REST サーバー メソッドを呼び出すと、ユーザー名とパスワードの入力を再度求められます。もちろん、これは、
delphi - 1回のリクエストでDataSnapサーバーから2つのデータセットを返す
2012-06-27コメント
元の投稿にはいくつかの便利なコードがありますが、クライアントアプリからの1回のリクエストでDataSnapサーバーから複数のデータセットを返す方法を実際には示していません。その方法の例を見るには、ページの一番下にある「正解」とマークされた回答を見てください。
2011-08-31コメント
ガニーのおかげで、私はすべてをもう一度見ました。厄介な問題は私自身のバグでしたが、現在は修正されています。各データベースクエリの間にコンポーネントを作成/破棄することで、単一のクライアントからサーバーへの要求内のDataSnapサーバーで複数のSQLステートメントを実行できます。TSQLQuery
(output
http://qc.embarcadero.com/wc/qcmain.aspx ? _ d = 90211)。TSQLStoredProc.Open
したがって、私の問題は解決されましたが、元の問題は残っています。メソッドを呼び出してOpen
データをプルしてからoutput
パラメータにアクセスすることはできません。また、単一のストアドプロシージャから返された複数のデータセットにアクセスすることもできません。
ガニー、あなたの提案にもう一度感謝します。
元の投稿
1回のリクエストでDataSnapサーバーから2つの異なるデータセットを返そうとしています。どちらも同じデータベースからのものです。1つは単一フィールド/単一レコード値であり、もう1つはマルチフィールド/マルチレコードデータセットです。
DataSnapサーバーには次の方法があります。
これは機能しません。両方の個別のリクエストがデータベースにヒットしていることはわかりますが、2番目の結果セットにアクセスできません。試してみると、2番目の結果セットではなく最初の結果セットが(再び)返されます。
クエリコンポーネントを作成/破棄する前に(各クライアントからサーバーへのリクエストで)、後続のすべてのクライアントからサーバーへのリクエストは最初のデータセットを返していました。非常にイライラします。クエリコンポーネントを作成/破棄するとその問題は修正されましたが、1つのクライアントからサーバーへのリクエストで複数のクエリを実行すると、問題が返されます。新しいクエリが実行された場合でも、最初のデータセットが返されます。
私はいくつかのアプローチを試しました:
ONETSQLQuery
:最初のリクエストのコンポーネントを動的に作成し、db値をプルし、を破棄しTSQLQuery
、新しいデータセットを作成してTSQLQuery
、2番目のデータセットをプルします。それは役に立ちませんでした。SQL Server Profilerを使用して、両方のコマンドがデータベースにヒットすることを確認できますが、最初の結果セットが両方のクエリのデータセットとして表示されます。
TWO:#1と同じことを行いますが、TSQLStoredProcedure
の代わりに使用しTSQLQuery
ます。結果は同じです。
3:を使用してTSQLStoredProcedure
、次のように同じストアドプロシージャ内から両方のデータセットを返します。
TSQLStoredProcedure
を持っているのでNextRecordSet
、私は両方のデータセットにアクセスすることを望んでいましたが、喜びはありませんでした。を呼び出すとNextRecordSet
、が返されますnil
。
4TSQLStoredProcedure
:データセットとoutput
パラメーターを使用する1回の呼び出しで2つの値を返します。
Delphiのコードは次のようになります。
sp.Paramsを調べたところ、。という名前のin/outパラメーターが1つありますvalue
。output
データセットも返されるときにパラメータにアクセスできません。これは既知のバグです(長年にわたって):http://qc.embarcadero.com/wc/qcmain.aspx?d = 90211
結論:
DataSnapサーバーはTSQLConnection
接続しているすべてのクライアントとメインを共有しており、TSQLQuery
(またはTSQLStoredProc
)とTClientDataSet
コンポーネントはすべてリクエストごとに作成/解放されるため、前のデータセットを保持してTSQLQuery
、TSQLStoredProc
コンポーネントはTSQLConnection
コンポーネントです。(または)コンポーネントTSQLConnection.CloseDataSets
を閉じて解放する前に呼び出してみましたが、それも役に立ちませんでした。TSQLQuery
TStoredProc
おそらく、よく見るTSQLConnection
と役立つでしょう。.dfm
ファイル内での表示は次のとおりです。
また、実行時に、DBXドライバー用の.INIファイルを展開する必要がないようにいくつかのことを行います。まず、自分のINIレスドライバーを登録できるユニット:
上記のメソッドはプロジェクト(.dprファイル)に含まれており、ドライバーを自己登録します。次の方法では、これを利用してTSQLConnection
実行時(DataSnapサーバーの起動時)に(sqlcon)をセットアップします。
これらの設定のいずれかが、コンポーネントを台無しにして、TSQLConnection
データセットをキャッシュし、最新のTSQLQuery
コンポーネントが実行したものの代わりにそれらを返すようにしている可能性がありますか?
どんな助けでも大歓迎です。お分かりのように、これは私を夢中にさせています!
ありがとう、ジェームズ
delphi - Delphi XE と ServerMethods
Delphi XE では、「DataSnap サーバー」ウィザードを使用してクライアント サーバー アプリケーションを作成します。
この「Select * from TABLE」のようなSQLプロパティServerMethodUnit
を定義するTSQLQuery
私も呼び出される関数を定義します。ChangeSQL
例によってServerMethodUnit
sql プロパティを変更するものSELECT * from TABLE where ID = 5
ChangeSQL
を介してフォームクライアントアプリケーションを呼び出すTSQLServerMethod
と、関数のプロパティがChangeSQL
変更されますが、関数を離れると、新しいSQLコマンドは含まれていませんが、元のSQLがあります。SQL
ServerMethodUnit
ChangeSQL
TSQLQuery
EDIT:コードサンプルの追加
「DataSnap サーバー」ウィザードを使用して、新しいクライアント サーバー アプリケーションを作成します。
でServerMethodsUnit
:
TSQLConnection
私は自分のデータベースに入れました。I put a TSQLQuery
call MyQuery
, with SQL
property = 'Select * from client' I put a TDataSetProvider
toTSQLQuery
そして、次のような関数を定義します。
// ------------------------------------------------ // この時点で、MyQuery.RecordCount = すべてのレコード (初回と次の両方) // --------------------------- ----------------------
そして、「DataSnap クライアント」で新しいアプリケーションを作成します
にClientModuleUni
: を配置しClientDataSet
、MyClientDS
withRemoteServer
とProviderName
自分のMyQuery
プロバイダーに呼び出します。を指すTSQLServerMethod
呼び出しを入れましたMyMethod
ClientFilter
ServerMethodsUnit
クライアントアプリケーションのフォームに 次に、ADataSource
と aDBGrid
を入れMyClientDs
て開きます。Tbutton
私はコードを入れましたOnClick
:
DBGrid
The I see all records of Client Table, ALWAYS .
ClientTable
ボタンをクリックしてフィルターをかけてみましたが、DBGrid
常にすべてのレコードが表示されます。
delphi - Delphi XE Data Snap TCP/IP クライアント ログイン フォーム
(私は Demo Dirt を見ました - しかし、それは HTTP Web に使用され、TCP/IP に切り替える方法がわかりません) 私は Delphi を初めて使用します - DataSnap とクライアント ログイン フォームの使用について助けが必要です (SQL Server からユーザー パスワードを確認してください) ) 次に、役割を適用します。コードまたは回答をいただければ幸いです よろしくお願いします
objective-c - TDataSet の結果を Delphi XE2 Datasnap Server から Xcode で処理する
Delphi XE2 DataSnap サーバーを使用して、SQL サーバーから iPad アプリケーションにデータをプッシュする可能性を検討しています。
私は Datasnap サーバー アプリケーションを作成し、現在 iOS アプリケーションを見ています。TServerMethod は、データを iOS の TDataSet として返します。明確でないのは、結果の TDataSet を Xcode で NSMutableArray として抽出する方法です。以下は、DSProxy.m で生成されたコードです。
}