当前位置:编程学习 > C#/ASP.NET >>

分布式编程

我采用的是Remoting来作为通道,但是服务器启动之后,客户端要连接的时候,提示,找不到什么程序集,上网找了一下资料,说是在用之前,要用 Microsoft .NET  Configuration这个注册
不知道有谁做过这方便,给个提示 --------------------编程问答-------------------- 填加引用
客户机装.net了吗... --------------------编程问答-------------------- TaskRunner taskRunner = (TaskRunner)Activator.GetObject(typeof(TaskServer.TaskRunner),
                "tcp://localhost:8085/TaskServer");

tcp://localhost:8085/TaskServer 主要是这个,访问不了,需要注册,怎么注册?(是一个DLL文件) --------------------编程问答-------------------- 在客户程序里你是不是没添加引用“TaskServer.TaskRunner” --------------------编程问答-------------------- 程序生成的时候都没错,就是运行的时候提示错,这个不是引用的问题,是服务器必须注册,但是我不知道怎么注册 --------------------编程问答-------------------- RemotingConfiguration.Configure(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile); --------------------编程问答--------------------  
guoyichao 能否把注册的流程说的具体一点
例如:第一步....
     第二步....
谢谢了 --------------------编程问答-------------------- TaskRunner taskRunner = (TaskRunner)Activator.GetObject(typeof(TaskServer.TaskRunner),
  "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,我传一份,这样好不? --------------------编程问答-------------------- 那个我也有写的,可就是不行,如果有懂的人情留下QQ,我传一份大家研究一下

 // 创建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(); --------------------编程问答-------------------- TaskRunner taskRunner = (TaskRunner)Activator.GetObject(typeof(TaskServer.TaskRunner),
  "tcp://localhost:8085/TaskServer");


你客户端这句中的"TaskRunner "和"TaskServer.TaskRunner"是同一个类吗?



----------
三易通软件(服装进销存,服装进销存软件,服装进销存管理软件,服装进销存管理系统,服装店管理软件,服装店管理系统,服装销售管理软件,服装销售管理系统,服装零售管理软件,服装零售管理系统,服装店软件,服装店收银软件):http://www.3etsoft.cn --------------------编程问答-------------------- 没做过remoting的,做过wcf的,帮顶了... --------------------编程问答-------------------- kankan  --------------------编程问答-------------------- 你使用了客户端激活,使用这种方式,你必须在客户端的调用路径里有包含了TaskServer.TaskRunner这个类的DLL。

调用路径包括,GAC,程序当前运行路径,config文件里指定的路径。 --------------------编程问答-------------------- 是同一个类 --------------------编程问答-------------------- 楼主把详细的错误贴上来看看吧 --------------------编程问答-------------------- 执行类:
// 该对象用来运行由客户端提交的任务,提交的任务将在服务器的应用域执行。
// 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);
            }
        }
    }
}
--------------------编程问答-------------------- MARK --------------------编程问答-------------------- 楼主,按照你的代码。你是不是只有两个工程?一个是客户端,一个是服务器端?

如果是,你需要建立第三个工程。该工程里声明 ITask接口以及ClientTask类并实现。

然后客户端工程和服务器端工程都必须引用该工程。 --------------------编程问答-------------------- 三个工程 --------------------编程问答-------------------- 或者换句话说,你必须保证ClientTask类在客户端和服务器端都能调用到。

你的想法可能是想在客户端创建一个类的实例,并将该类的实例传给服务器端,在服务器端被执行后返回结果。

但是,这样是无法实现的。因为服务器端即使有了该接口,但是没有该类的声明,所以当该实例被传输到服务器端时,服务器端无法实例化一个对应的类来获取客户端传上来的实例。 --------------------编程问答-------------------- 让我想想,你既然已经有了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。
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,