让我想想,你既然已经有了3个工程,那么ITask和TaskRunner在一个工程里(A)(A是DLL) ClientTask和Client在一个工程里(B)(B是EXE) TaskServerEngine在一个工程里(C)(C是EXE)所以 B 引用了 A,C 引用 A,而关键了 C 要调用 B 里ClientTask,所以 C 要引用 B。但是C和B都是EXE,他们是不能直接互相引用的。因此C无法在运行是获取ClientTask的一个实例。所以,我建议你将ITask和ClientTask放到同一个工程里(B),并将该工程设置成DLL,然后A引用B,C引用B。
"tcp://localhost:8085/TaskServer");tcp://localhost:8085/TaskServer 主要是这个,访问不了,需要注册,怎么注册?(是一个DLL文件)
guoyichao 能否把注册的流程说的具体一点
例如:第一步....
第二步....
谢谢了
"tcp://localhost:8085/TaskServer");tcp://localhost:8085/TaskServer 主要是这个,访问不了,需要注册,怎么注册?(是一个DLL文件)你在服务端,需要注册TaskServer这个类
TcpServerChannel channel = new TcpServerChannel(8888);
ChannelServices.RegisterChannel(channel, false);
RemotingConfiguration.RegisterWellKnownServiceType(typeof(TaskServer), "TaskServer", WellKnownObjectMode.SingleCall);----------
三易通软件(服装进销存,服装进销存软件,服装进销存管理软件,服装进销存管理系统,服装店管理软件,服装店管理系统,服装销售管理软件,服装销售管理系统,服装零售管理软件,服装零售管理系统,服装店软件,服装店收银软件):http://www.3etsoft.cn
// 创建TCP通道
Console.WriteLine("[i] -- 创建TCP通道");
TcpChannel chan = new TcpChannel(8085);
// 向.NET的远程服务注册新创建的TcpChannel,使客户端可以使用这一服务
Console.WriteLine("[i] -- 注册TCP通道");
ChannelServices.RegisterChannel(chan, false);
//向远程机制的后端注册TaskRunner对象,RegisterWellKnownServiceType方法将完成这一 //操作,并接收下面的参数:
// *内容为TaskRunner对象映象的类型对象
// * 向客户公布的服务名字
// * 对象的模式:Singleton意味着所有客户端请求共享一个对象服务;SingleCall意味着 // 每个客户端请求使用一个新的对象服务。
Console.WriteLine("[i] -- 向远程机制的后端注册TaskRunner对象");
Type theType = new TaskRunner().GetType();
RemotingConfiguration.RegisterWellKnownServiceType(theType, "TaskServer", WellKnownObjectMode.Singleton);
Console.WriteLine("[i] 服务器启动成功,按任何键退出...");
Console.ReadLine();可就是不行,如果懂的话请留下QQ,我传一份,这样好不?
Console.WriteLine("[i] -- 创建TCP通道");
TcpChannel chan = new TcpChannel(8085);
// 向.NET的远程服务注册新创建的TcpChannel,使客户端可以使用这一服务
Console.WriteLine("[i] -- 注册TCP通道");
ChannelServices.RegisterChannel(chan, false);
//向远程机制的后端注册TaskRunner对象,RegisterWellKnownServiceType方法将完成这一 //操作,并接收下面的参数:
// *内容为TaskRunner对象映象的类型对象
// * 向客户公布的服务名字
// * 对象的模式:Singleton意味着所有客户端请求共享一个对象服务;SingleCall意味着 // 每个客户端请求使用一个新的对象服务。
Console.WriteLine("[i] -- 向远程机制的后端注册TaskRunner对象");
Type theType = new TaskRunner().GetType();
RemotingConfiguration.RegisterWellKnownServiceType(theType, "TaskServer", WellKnownObjectMode.Singleton);
Console.WriteLine("[i] 服务器启动成功,按任何键退出...");
Console.ReadLine();
"tcp://localhost:8085/TaskServer");
你客户端这句中的"TaskRunner "和"TaskServer.TaskRunner"是同一个类吗?----------
三易通软件(服装进销存,服装进销存软件,服装进销存管理软件,服装进销存管理系统,服装店管理软件,服装店管理系统,服装销售管理软件,服装销售管理系统,服装零售管理软件,服装零售管理系统,服装店软件,服装店收银软件):http://www.3etsoft.cn
// 该对象用来运行由客户端提交的任务,提交的任务将在服务器的应用域执行。
// TaskRunner对象以引用的方式传递给客户端,无需对它进行串行化
// TaskRunner接受所有实现ITask界面的任务,它需要二个参数:Run()和Identify()。
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;namespace TaskServer
{
// 必须将它定义为一个界面
public interface ITask
{
object Run();
string Identify();
} public class TaskRunner : MarshalByRefObject
{
ITask remoteTaskObject;
public TaskRunner()
{
Console.WriteLine("\n[i] 服务器启动");
}
public string LoadTask(ITask task)
{
Console.WriteLine("\n[i] 加载新任务...");
if (task == null)
{
Console.WriteLine("[e] 没有任务,无法加载任务.");
return "[e] 任务加载失败.";
}
remoteTaskObject = task;
Console.WriteLine("[i] 任务加载成功.");
Console.WriteLine("[i] 任务编号: " + remoteTaskObject.Identify() + "\n");
return "[i] 任务加载成功,欢迎使用分布式服务器.";
}
public object RunTask()
{
Console.WriteLine("\n[i] 开始执行客户端提交的任务...");
object result = remoteTaskObject.Run();
Console.WriteLine("[i] 任务执行完毕.");
return result;
}
}
}
// 这是一个客户端应用域,客户端的任务是建立一个任务对象,并将它提交给任务服务器
using System;
// 建立与任务服务器的连接所必需的库文件
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using TaskServer;namespace HappyClientWithTask
{
[Serializable()]
// 下面是我们创建的任务
class ClientTask : ITask
{
private int num1, num2;
private int result;
public ClientTask(int num1, int num2)
{
this.num1 = num1;
this.num2 = num2;
}
public object Run()
{
result = num1 * num2;
return (object)result;
}
public string Identify()
{
return ("这是一个乘法例子.");
}
}
public class Client
{
public static void Main()
{
Console.WriteLine("\n欢迎使用分布式简单测试例子.\n");
ClientTask clientTask = new ClientTask(100, 100);
try
{
Console.WriteLine("[i] 连接服务器...");
Console.WriteLine("[i] - 打开TCP通道");
TcpChannel chan = new TcpChannel();
Console.WriteLine("[i] - 注册通道");
ChannelServices.RegisterChannel(chan);
Console.WriteLine("[i] 连接上服务器");
// 从TaskServer中获取TaskRunner对象的引用
// Activator类中的GetObject方法需要二个参数:
// * 对象类型
// * 对象的URI位置
Console.WriteLine("[i] 得到一个新对象提交给服务器");
TaskRunner taskRunner = (TaskServer.TaskRunner)Activator.GetObject(typeof(TaskServer.TaskRunner),
"tcp://localhost:8085/TaskServer");
if (taskRunner == null)
{
Console.WriteLine("[e] 连接不上服务器.");
Console.WriteLine("[i] 退出...");
return;
}
Console.WriteLine("[i] 有一个新对象!");
// 下面我们将把任务对象传递给任务服务器
Console.WriteLine("\n[i] 把任务提交给服务器...");
string response = taskRunner.LoadTask(clientTask);
Console.WriteLine("[i] 服务器收到指令: " + response);
Console.WriteLine("\n[i] 服务器开始执行指令并返回结果...");
object result = taskRunner.RunTask();
Console.WriteLine("[aaa-uuuum] 服务器返回的结果集: " + (int)result);
Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine("[e] 一个错误.");
Console.WriteLine(e);
}
}
}
}
// 这个类用来启动任务服务器应用程序。它建立C#远程执行的后端,加载通道,注册TaskRunner对象,然后让 //远程执行机制的后端监测TCP通道上的连接请求
using System;
using System.IO;
// 下面的库用于向远程执行机制注册我们的对象
using System.Runtime.Remoting;
// 下面的库用于向通道服务注册我们的TCP通道设备
using System.Runtime.Remoting.Channels;
// 该库提供了用来与远程应用域(客户端)通讯所需要的TCP通道
using System.Runtime.Remoting.Channels.Tcp;namespace TaskServer
{
public class TaskServerEngine
{
// 我们只需要一个方法,它可以是静态的,因为我们不需要建立这个类的实例,该方法的作用仅仅是 //创建并创始化TaskServerEngine。
public static void Main()
{
//RemotingConfiguration.Configure(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile, false);
// 向用户表明我们正在启动服务器类
Console.WriteLine("正在启动服务器类!");
Console.WriteLine("....\"客户端的任务是服务器的指令\"....");
Console.WriteLine("\n[i] 开始启动客户端服务器...");
try
{
// 创建TCP通道
Console.WriteLine("[i] -- 创建TCP通道");
TcpChannel chan = new TcpChannel(8085);
// 向.NET的远程服务注册新创建的TcpChannel,使客户端可以使用这一服务
Console.WriteLine("[i] -- 注册TCP通道");
ChannelServices.RegisterChannel(chan, false);
//向远程机制的后端注册TaskRunner对象,RegisterWellKnownServiceType方法将完成这一 //操作,并接收下面的参数:
// *内容为TaskRunner对象映象的类型对象
// * 向客户公布的服务名字
// * 对象的模式:Singleton意味着所有客户端请求共享一个对象服务;SingleCall意味着 // 每个客户端请求使用一个新的对象服务。
Console.WriteLine("[i] -- 向远程机制的后端注册TaskRunner对象");
Type theType = new TaskRunner().GetType();
RemotingConfiguration.RegisterWellKnownServiceType(theType, "TaskServer", WellKnownObjectMode.Singleton);
Console.WriteLine("[i] 服务器启动成功,按任何键退出...");
Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine("[!] 错误.");
Console.WriteLine(e);
}
}
}
}
ClientTask和Client在一个工程里(B)(B是EXE)
TaskServerEngine在一个工程里(C)(C是EXE)所以 B 引用了 A,C 引用 A,而关键了 C 要调用 B 里ClientTask,所以 C 要引用 B。但是C和B都是EXE,他们是不能直接互相引用的。因此C无法在运行是获取ClientTask的一个实例。所以,我建议你将ITask和ClientTask放到同一个工程里(B),并将该工程设置成DLL,然后A引用B,C引用B。