将代码发送到服务器上在C#中执行 - 像Java RMI [英] Send code to be executed on server in C# - like Java RMI

查看:180
本文介绍了将代码发送到服务器上在C#中执行 - 像Java RMI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是在java中的示例代码。



共享接口:



 进口java.rmi.Remote的; 
进口java.rmi.RemoteException异常;

公共接口扩展计算远程{
公共对象executeTask(任务T)将抛出RemoteException;
}



任务(这将作为参数传递):

 的Bean; 

公共接口扩展任务序列化{
公共对象的execute();
}

服务器:



 进口java.rmi.Naming中; 
进口java.rmi.RMISecurityManager;
进口java.rmi.RemoteException异常;
进口java.rmi.server.UnicastRemoteObject;

公共类COMPUTEENGINE扩展了UnicastRemoteObject实现计算{

公共COMPUTEENGINE()将抛出RemoteException {
超();
}

公共对象executeTask(任务T){
返回t.execute();
}

公共静态无效的主要(字串[] args){
setRmiCodebase();
System.setSecurityManager(新RMISecurityManager());
尝试{
的Compute Engine =新COMPUTEENGINE();
Naming.rebind(//本地主机:1099 /计算,发动机);
的System.out.println(COMPUTEENGINE启动。);
}赶上(例外前){
ex.printStackTrace();
}
}

私有静态无效setRmiCodebase(){
字符串代码库= System.getProperty(java.rmi.server.codebase);
如果(代码库!= NULL)
的回报;
//在此基础上clsas(它是在瓶子或filesistem?)
}的位置

}


客户:

 进口java.math.BigDecimal的; 
/ **
*计算圆周率位数任意数量:
* /
公共类丕实现任务{

公共PI(INT位) {
this.digits =数字;
}

公共对象的execute(){
返回computePi(位);
}

公共静态的BigDecimal computePi(INT位){
//计算丕
}

}

客户机主:

 进口java.math.BigDecimal的; 
进口java.rmi.Naming中;
进口java.rmi.RMISecurityManager;

公共类ComputePi {

公共静态无效的主要(字串[] args){
setRmiCodebase();
System.setSecurityManager(新RMISecurityManager());
尝试{
计算补偿=(计算)Naming.lookup(//本地主机:1099 /计算);
丕任务=新的PI(100);
的BigDecimal PI =(BigDecimal)的comp.executeTask(任务);
的System.out.println(PI);
}赶上(例外前){
ex.printStackTrace();
}
}

私有静态无效setRmiCodebase(){
字符串代码库= System.getProperty(java.rmi.server.codebase);
如果(代码库!= NULL)
的回报;
//在此基础上clsas(它是在瓶子或filesistem?)
}的位置
}


如你所见,代码从客户(不仅仅是数据)被转移到服务器,并在那里执行,并返回计算结果。服务器不知道类存在,它只知道工作接口。



我需要像这样在.NET环境中工作(C#如果它是很重要的)。 WCF将是不错的,但我正在寻找最简单的解决办法,所以WCF是不是强制性的。我不知道,甚至什么关键字来使用谷歌documetation或解决方案这一点。



任何帮助将不胜感激。


解决方案

.NET本身并不支持送码被另一台计算机上执行。通常情况下,必要的代码将被编译成程序集和在服务器上预先安装之前它是由客户端调用。这既是远程和WCF也是如此。你可以有那里的服务器调用回通过WCF客户端上的方法,双向远程处理的情况,但我怀疑这是不是你想要的。我所知道的在服务器上真正运行动态代码的唯一方法是生成动态代码,将其发送到服务器作为字符串,然后让服务器把它编译成一个内存中装配的飞行,然后执行它。如果你有兴趣在这样做,看看我的回答类似的问题:



自动激活属性?



然而,它不完全是我会在大多数情况下建议。我建议你重新考虑你的设计,一是看是否有办法做到你在一个典型的.NET路需要什么。


This is example code in java.

Shared interfaces:

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

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

Task (this will be passed as parameter):

import java.io.Serializable;

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

Server:

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?)
  }

}

Client:

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
  }

}

Client main:

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?)
  }
}

As you can see, code (not just data) from client is transfered to server and executed there and result of computation is returned. Server does not know that class Pi exists, it only knows about Task interface.

I need something like this to work in .net environment (C# if it is important). WCF would be nice, but I am looking for the most straightforward solution, so WCF is not compulsory. I am not sure even what keyword to use to google documetation or solution for this.

Any help will be appreciated.

解决方案

.NET does not natively support "sending code" to be executed on another computer. Typically the necessary code would be compiled to assemblies and pre-installed on the server before it is called by the client. This is true of both remoting and WCF. You could have a two-way remoting situation where the server calls back to a method on the client via WCF, but I suspect this is not what you want. The only way I'm aware of to really run dynamic code on the server is to generate dynamic code, send it to the server as a string, and then have the server compile it to an in-memory assembly on the fly and then execute it. If you are interested in doing so, take a look at my answer to a similar question:

Autovivified properties?

However, it's not exactly something I would suggest in most cases. I would suggest you rethink your design, first, to see if there is any way to do what you need in a typical ".NET way".

这篇关于将代码发送到服务器上在C#中执行 - 像Java RMI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆