CSharp Silverlight DataSnap モバイル コネクタ入門

提供: RAD Studio
移動先: 案内検索

DataSnap モバイル コネクタ入門 への移動


このトピックは、C# Silverlight DataSnap プロキシの生成と使用についてのガイドで、Windows Phone 7 モバイル開発を対象にしたものです。 C# Silverlight プロキシでは、DataSnap そのものでサポートされているのと同じデータ型をすべてサポートしています。 それらの DBX 型と Delphi 型をラップするための特別な C# クラスが作成されており、その使い方は Delphi の場合と似ています。

DataSnap REST サーバーは、要求されると、サーバー上のメソッドを呼び出すためのプロキシ クラスを生成してディスパッチします。 これは、既によくご存知だと思われるプロキシ生成と非常に似ていますが、プロキシとそれに依存するものをすべて zip 圧縮し、その zip ファイルを要求側に送信するという処理も含まれています。

このプロセスについてのさらなる情報については、「DataSnap モバイル コネクタ入門」を参照してください。

C# Silverlight プロキシ ファイルを DataSnap REST サーバーからダウンロードする方法

まず、Win32ProxyDownloader.exe を入手する必要があります。これは、製品のインストール ディレクトリの \bin ディレクトリに含まれています。 このファイルとコピーの入手先については、「DataSnap モバイル コネクタ入門」で詳しく説明しています。

このダウンローダは、サーバーとの通信に必要なプロキシなどのファイルをサーバーに要求する際に役立つ単純なユーティリティです。

プロキシ ダウンローダを使用するときには、次のパラメータを指定する必要があります。

  • -language(必須): 要求するプロキシのモバイル プラットフォームと言語を指定します。 Windows Phone 7 の場合は、csharp_silverlight を使用します。
  • -protocol: 使用する接続プロトコルを指定します。http か https のどちらかです。 デフォルトは http です。
  • -host: 接続先のポートおよびホスト名または IP アドレスを指定します。 デフォルトは localhost のポート 80 です。 これとは別のホスト名やポートを指定するには、名前とポート番号をコロン(":")で区切って完全修飾名にします。
  • -output: プロキシ ファイルをダウンロードして保存するフォルダを指定します。 指定しなければカレント フォルダになります。

上記パラメータのほとんどを使用した例を以下に示します。

 C:\Win32ProxyDownloader.exe -language csharp_silverlight -host 127.0.0.1:8080 -output C:\test

ダウンローダの実行後、C# Silverlight プロキシ ファイルは指定の出力フォルダにコピーされます。 このファイルには次のものが含まれます。

  • JSON 解析用 DLL
  • プロキシで必要になる静的な C# ソース ファイル
  • 生成されたプロキシである DSProxy.cs

主要なファイルは DSProxy.cs で、これには、サーバー上に定義されているすべてのメソッドが記述されたクラスが宣言されています。

DSProxy クラスの使い方

以下のコードは、サーバーで生成された DSProxy.cs(C#)ファイルを示しています。 この中には TServerMethods1 クラスが含まれており、そこにサーバー メソッドがカプセル化されています。 サーバーにはメソッドが 1 つしかなく(EchoString のみ)、C# クラス TServerMethods1 にそれが適切に実装されています。 プロキシ ジェネレータによって、サーバーに接続してメソッドを実行するためのすべてのコードが自動生成されています。 EchoString メソッドの C# コードを以下で参照してください。

 using System;
 using System.Threading;
 
 namespace Embarcadero.DataSnap.WindowsPhone7
 {
   public class DSProxy
   {
     public class TServerMethods1 : DSAdmin
     {
       public TServerMethods1(DSRESTConnection Connection, ExceptionCallback ExCal) : base(Connection, ExCal)
       {
       }
 
       private DSRESTParameterMetaData[] TServerMethods1_EchoString_Metadata;
       private DSRESTParameterMetaData[] get_TServerMethods1_EchoString_Metadata() {
         if (TServerMethods1_EchoString_Metadata == null) {
           TServerMethods1_EchoString_Metadata = new DSRESTParameterMetaData[] {
               new DSRESTParameterMetaData("Value", DSRESTParamDirection.Input, 
                                                     DBXDataTypes.WideStringType, "string"),
               new DSRESTParameterMetaData("", DSRESTParamDirection.ReturnValue, 
                                               DBXDataTypes.WideStringType, "string"),
           };
         }
         return TServerMethods1_EchoString_Metadata;
       }
 
       /**
        * @param Value [in] - Type on server: string
        * @return result - Type on server: string
        */
       public delegate void EchoStringCallback(String Result);
 
       public void EchoString(String Value, EchoStringCallback callback = null, ExceptionCallback ExCal = null)
       {
         DSRESTCommand cmd = getConnection().CreateCommand();
         cmd.setRequestType(DSHTTPRequestType.GET);
         cmd.setText("TServerMethods1.EchoString");
         cmd.prepare(get_TServerMethods1_EchoString_Metadata());
         InternalConnectionDelegate EchoStringDel = () => {
           if (callback != null) {
             try {
               callback.DynamicInvoke(cmd.getParameter(1).getValue().GetAsString());
             } catch (Exception ex) {
               if (ExCal != null) 
                 getConnection().syncContext.Send(new SendOrPostCallback(x => 
                    ExCal.DynamicInvoke(ex.InnerException)), null);
               else 
                 getConnection().syncContext.Send(new SendOrPostCallback(x => 
                   BaseExCal.DynamicInvoke(ex.InnerException)), null);
             }
           }
         };
         cmd.getParameter(0).getValue().SetAsString(Value);
         getConnection().execute(cmd, this, EchoStringDel, ExCal);
       }
     }
   }
 }

プロキシ クラスを使用するには、まず、サーバーへの接続を作成しセットアップします。 サーバーに接続するために必要なプロパティやメソッドはすべて、DSRESTConnection クラスにカプセル化されています。 以下に示すように、接続を作成しプロパティをセットアップすればよいだけです。

 DSRESTConnection connection = new DSRESTConnection();
 connection.setHost("hostname");
 connection.setPort(portnumber);
 connection.setProtocol("http");
  • host プロパティにはホスト名または IP アドレスを指定します。
  • port プロパティは、サーバーのリスン ポートを指定します。
  • protocol プロパティには接続に使用するプロトコルを指定します。 具体的には、 http か https のどちらかです。

サーバー メソッドをリモートで呼び出すには、接続を引数に渡してプロキシ クラスを作成した後、そのメソッドを呼び出すだけです。

 DSRESTConnection connection = new DSRESTConnection();
 connection.setHost("localhost");
 connection.setPort(8080);
 connection.setProtocol("http");
 
 DSProxy.TServerMethods1 Proxy = new DSProxy. TServerMethods1(connection, ExceptionCallback);
 
 Proxy.EchoString("teststring", (String Result) =>
 {
    // ...
 }, ExceptionCallback);
 
 public void ExceptionCallback(Exception e)
 {
    // ...
 }

var パラメータを持つサーバー メソッドの例

以下の例は、サーバー メソッドが var パラメータを含んでいるか複数の結果を返す場合に生成されるコードです。 これは、そのようなサーバー メソッドの Delphi コードです。

 function TServerMethods1.VarParamTest(var Value: string): string;
 begin
   Value := StrUtils.ReverseString(Value);
   Result := Value;
 end;

そして次に示すのが、そのサーバー メソッドを呼び出すための生成されたプロキシ コードです。

 private DSRESTParameterMetaData[] TServerMethods1_VarParamTest_Metadata;
 private DSRESTParameterMetaData[] get_TServerMethods1_VarParamTest_Metadata()
 {
   if (TServerMethods1_VarParamTest_Metadata == null) {
     TServerMethods1_VarParamTest_Metadata = new DSRESTParameterMetaData[] {
       new DSRESTParameterMetaData("Value", DSRESTParamDirection.InputOutput, 
                                            DBXDataTypes.WideStringType, "string"),
       new DSRESTParameterMetaData("", DSRESTParamDirection.ReturnValue, 
                                      DBXDataTypes.WideStringType, "string"),
     };
   }
   return TServerMethods1_VarParamTest_Metadata;
 }
 
 /**
  * @param Value [in/out] - Type on server: string

メソッドが VarParamTestReturns のインスタンスを返すことに注意してください。 この特別なクラスは、結果の他に、var(in/out)パラメータについての情報も保持します。 以下の例は、メソッドを呼び出し、その結果として得られた値を読み取る方法を示しています。

 Proxy. VarParamTest ("Hello, World!", 
   (DSProxy.TServerMethods1.VarParamTestReturns Result) => {
      Debug.WriteLine(Result.Value);
      Debug.WriteLine(Result.returnValue);
   }
 );

渡されたパラメータの新しい値と結果値が両方とも Result インスタンスに格納されています。 Result.Value の値は "!dlroW ,olleH" で、Result.returnValue の値は "Hello, World!" です。

重量コールバックの使い方

重量コールバックは、DataSnap サーバーから REST クライアントへ、ほぼ即座に通知を送るための方法です。 クライアントは、関心のあるサーバーに特定のトピックのコールバックを登録でき、その後は、そのトピックが更新されるたびに、通知を受け取ります。 これはもちろん、重量コールバックが何を遂行するかを非常に簡単に説明したものですが、このドキュメントの目的にはそれで十分なはずです。

アプリケーションでコールバックを使用するには、まず、抽象クラス DBXCallback を継承するカスタム コールバック クラスを作成し、抽象メソッド "Execute" をオーバーライドします。 以下は、このクラスの実装例です。

 public class MyCallback : DBXCallback {
   public override TJSONValue Execute(TJSONArray params) {
     Debug.WriteLine(Params.ToString());
     return new TJSONTrue();
   }
 }

DSClientCallbackChannelManager クラスはクライアントのコールバックを管理するためのものです。 コールバックを登録および登録解除するためのメソッドや、その 1 つまたはすべてを閉じるためのメソッドを提供しています。

DSClientCallbackChannelManager のコンストラクタには、以下の 3 つのパラメータがあります。

  1. DSRESTConnection。サーバー接続情報を指定します
  2. 登録するサーバー チャネルの名前を含む文字列
  3. マネージャの ID(サーバーから見て一意)を含む文字列
 DSCallbackChannelManager mngr = 
     new DSCallbackChannelManager(Connection, "chname", DSCallbackChannelManager.getNewManagerID());

以下は、コールバックを登録した後、その登録先と同じチャネルにブロードキャストする例です。


 public void testCallbacks(){
 
        DSAdmin admin = new DSAdmin(Connection, ManageExceptionCallback);
    mngr = new DSCallbackChannelManager(Connection," chname",DSCallbackChannelManager.getNewManagerID());
    mngr.registerCallback("mycb01", new MyCallback(), () =>
    {
 	admin.BroadcastToChannel("chname", new TJSONString("This is a broadcast"),(bool b) =>
         {
           mngr.closeClientChannel();
         });  
 
 }
 
 public void ManageExceptionCallback(Exception e)
 {
    // ...
 }

'registerCallback' メソッドの第 1 パラメータは、コールバックの ID(クライアント チャネル内で一意な ID)です。 第 2 パラメータは、実際に登録するコールバック インスタンスで、第 3 パラメータは登録完了時に呼び出すデリゲート メソッドです。

上記のコードでは、MyCallback クラスの新しい インスタンスをサーバーに登録しています。このコールバックは chname チャネルでリスンします。 この登録が正常に終了したら、クライアントは BroadcastToChannel を呼び出し、"chname" チャネルでリスンしているすべてのコールバック(自分自身も含む)に文字列 "This is a broadcast" を送信します。

BroadcastToChannel 呼び出しの 第 3 パラメータは、その呼び出しがサーバーから戻ったときに呼び出されるデリゲートで、ブロードキャスト要求をサーバーが正常に処理したかどうかを示す論理値が含まれています。 上記コードのこのネストしたデリゲート宣言では、ブロードキャストをもう受け取らないように、チャネルを閉じています。

関連項目