remoting 在分布式应用中逐渐在企业级应用发展开来,最初提出分布式应用,主要目的是为了降低服务器的压力,将耗性能的处理放在另外一个程序中,然后将计算结果发送到另外一个应用中。而remoting就是提供了这个角色,本实例主要讲解服务器端订阅客户端,也就是客户端进行某操作,会及时告知服务器端。既然这样的话,事件订阅应该放在服务器端,行为放在客户端,通过行为触发服务器端事件。好了,大概的思路理清楚了,下面来主要讲解一下代码吧。
思路:客户端执行方法->服务器端事件被触发->公共实体类需要提供委托及执行方法才能让服务器端和客户端进行交互->如果让服务器端和客户端都能交互所以必须向上提炼出接口,接口包括委托和行为。
第一步:创建公共接口类库,命名为ICommon,代码如下:
namespace ICommon { public delegate void OnChangeHander(string msg); public interface IShare { void Say(string msg); } }
第二步:创建实体类库,用于实现接口,命名为ServerBLL,代码如下:
namespace ServerBLL { public class CommonServerUse : MarshalByRefObject, IShare { public static event OnChangeHander OnChange; public void Say(string msg) { if (OnChange != null) { OnChange(msg); } } } }
注意要添加MarshalByRefObject,主要目的是让通道技术数据传输
第三步:服务器端实现,创建服务器,开启事件监听,事件监听注意启用单例模式Sington,防止客户端调用的行为匹配不到服务器端的服务
代码如下:
namespace ConsoleServer { class Program { static void Main(string[] args) { HttpChannel chanel = new HttpChannel(8080); ChannelServices.RegisterChannel(chanel, false); RemotingConfiguration.RegisterWellKnownServiceType(typeof(CommonServerUse), "King", WellKnownObjectMode.Singleton); CommonServerUse.OnChange += new OnChangeHander(CommonServerUse_OnChange); Console.WriteLine("服务器已启动,等待客户端连接"); Console.ReadKey(); } static void CommonServerUse_OnChange(string msg) { Console.WriteLine("来自客户端消息:" + msg); } } }
好了,服务器端实体类(单例)创建好了,事件监听也绑定好饿,接下来就是客户端引用服务器端的单例实体类
第四部:引用服务器端的服务,生成实例:
代码如下:
namespace ConsoleClient { class Program { static void Main(string[] args) { HttpChannel channel = new HttpChannel(0); ChannelServices.RegisterChannel(channel, false); IShare share = (IShare)Activator.GetObject(typeof(IShare),"http://localhost:8080/King"); Console.WriteLine("客户端已启动,输入exit退出客户端"); string console = Console.ReadLine(); while (console != "exit") { share.Say(console); console = Console.ReadLine(); } Console.ReadKey(); } } }
好了,接下来看一下效果,先打开服务器端程序,然后打开多个客户端,效果如下: