3

これは Java のサンプル コードです。

共有インターフェース:

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface Compute extends Remote {
  public Object executeTask(Task t) throws RemoteException;
}

タスク (これはパラメーターとして渡されます):

import java.io.Serializable;

public interface Task extends Serializable {
  public Object execute();
}

サーバ:

import java.rmi.Naming;
import java.rmi.RMISecurityManager;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class ComputeEngine extends UnicastRemoteObject implements Compute {

  public ComputeEngine() throws RemoteException {
    super();
  }

  public Object executeTask(Task t) {
    return t.execute();
  }

  public static void main(String[] args) {
    setRmiCodebase();
    System.setSecurityManager(new RMISecurityManager());
    try {
      Compute engine = new ComputeEngine();
      Naming.rebind("//localhost:1099/Compute", engine);
      System.out.println("ComputeEngine started.");
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }

  private static void setRmiCodebase() {
    String codebase = System.getProperty("java.rmi.server.codebase");
    if (codebase != null)
      return;
    // set codebase based on location of this clsas (is it in jar or filesistem?)
  }

}

クライアント:

import java.math.BigDecimal;
/**
* Calculates Pi to arbitrary number of digits:
*/
public class Pi implements Task {

  public Pi(int digits) {
    this.digits = digits;
  }

  public Object execute() {
    return computePi(digits);
  }

  public static BigDecimal computePi(int digits) {
    // compute Pi
  }

}

クライアントのメイン:

import java.math.BigDecimal;
import java.rmi.Naming;
import java.rmi.RMISecurityManager;

public class ComputePi {

  public static void main(String[] args) {
    setRmiCodebase();
    System.setSecurityManager(new RMISecurityManager());
    try {
      Compute comp = (Compute)Naming.lookup("//localhost:1099/Compute");
      Pi task = new Pi(100);
      BigDecimal pi = (BigDecimal)comp.executeTask(task);
      System.out.println(pi);
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }

  private static void setRmiCodebase() {
    String codebase = System.getProperty("java.rmi.server.codebase");
    if (codebase != null)
      return;
    // set codebase based on location of this clsas (is it in jar or filesistem?)
  }
}

ご覧のとおり、クライアントからのコード (データだけでなく) がサーバーに転送され、そこで実行され、計算結果が返されます。サーバーはクラスのPi存在を認識せず、インターフェイスについてのみ認識しTaskます。

.net 環境 (重要な場合は C#) で動作するには、このようなものが必要です。WCF があればいいのですが、私は最も簡単な解決策を探しているので、WCF は必須ではありません。Googleドキュメントやこれに対する解決策にどのキーワードを使用すればよいかさえわかりません。

どんな助けでも大歓迎です。

4

5 に答える 5

2

Afaik .NETは、これをそのままではサポートしていません。リモート処理は実行できますが、サーバー上のクライアントからコードを実行することは(そのままでは)できません。実行したいコードを含むdllをサーバーに転送するものを実装してから、おそらくそのdllを別のAppDomainにロードする必要があると思います(別のAppDomainにロードしない限りdllをアンロードできないため) 、実行するクラスを指定する方法があります。

于 2012-05-31T12:37:51.087 に答える
1

このMSDNページには、あなたが説明したのとほぼ同じユースケースがあります。ServiceContract を変更するだけです

http://msdn.microsoft.com/en-us/library/system.servicemodel.netnamedpipebinding.aspx

おそらく、この部分を変更するだけで済みます。

 [ServiceContract(Namespace = "http://UE.Samples")]
    public interface ICalculator
    {
        [OperationContract]
        double Add(double n1, double n2);
    }

    // Service class which implements the service contract.
    public class CalculatorService : ICalculator
    {
        public double Add(double n1, double n2)
        {
            return n1 + n2;
        }

スカラー値の代わりに、独自のクラスのパラメーターを使用して executeTask メソッドを配置します。

于 2012-05-31T13:11:05.660 に答える
1

.NET は、別のコンピューターで実行される "コードの送信" をネイティブにサポートしていません。通常、必要なコードはアセンブリにコンパイルされ、クライアントによって呼び出される前にサーバーにプレインストールされます。これは、リモート処理と WCF の両方に当てはまります。サーバーが WCF を介してクライアントのメソッドにコールバックする双方向のリモート処理の状況が発生する可能性がありますが、これはあなたが望んでいるものではないと思います。サーバー上で動的コードを実際に実行する唯一の方法は、動的コードを生成し、それを文字列としてサーバーに送信し、サーバーにその場でメモリ内アセンブリにコンパイルさせてから実行させることです。それ。興味がある場合は、同様の質問に対する私の回答をご覧ください。

自動活性化されたプロパティ?

ただし、ほとんどの場合、私が提案するものではありません。最初に、典型的な「.NET の方法」で必要なことを行う方法があるかどうかを確認するために、設計を再考することをお勧めします。

于 2012-05-31T13:08:09.947 に答える
1

必要なのは .NET Remoting です。 RMI から .NET Remoting に移行する方法を示す記事へのリンクを次に示します。

しかし、この MSDN の記事によると、これはレガシー テクノロジであり、WCF を使用する必要があります。

編集:

「そのように」WCF で .NET Remoting 機能を取得することはできません。

ここでは、.NET Remoting から WCF への移植に関する説明を読むことができます。しかし、WCF をまったく知らない場合は、ここから始めるべきです。そして、おそらく結果がすぐに得られないでしょう:)。

于 2012-05-31T12:29:05.147 に答える
0

クライアントからサーバーに実行可能コードを転送するためのソリューションが .NET に組み込まれているとは思えません。セキュリティ上の制約で許可されていると仮定すると、 IronPythonまたはIronJSを介してそれぞれサーバー側で実行できる Python や JavaScript などの解釈可能なコードを送信することを検討できます。C# が必要な場合 (そしてソース コードに引き続きアクセスできる場合)、ソースを送信し、サーバー側でコンパイルします (Roslyn または Mono のエバリュエーターを介して)。

于 2012-05-31T12:54:49.143 に答える