远程事件也需要转化成消息,所以也需要加事件委托继承自MarshalByRefObject。实际操作如下
1.定义接口
public delegate void MessageArrivedHandler(String msg); public interface IBroadcaster { void BroadcastMessage(String msg); event MessageArrivedHandler MessageArrived; }
2.服务器端实现
public class Broadcaster: MarshalByRefObject, IBroadcaster { public event General.MessageArrivedHandler MessageArrived; public void BroadcastMessage(string msg) { // call the delegate to notify all listeners Console.WriteLine("Will broadcast message: {0}"); MessageArrived(msg); } public override object InitializeLifetimeService() { // this object has to live "forever" return null; } } class ServerStartup { static void Main(string[] args) { String filename = "server.exe.config"; RemotingConfiguration.Configure(filename); Console.WriteLine ("Server started, press <return> to exit."); Console.ReadLine(); } }
上面两步没多大悬念,关键在客户端
3.客户端实现
3.1定义一个继承自MarshalByRefObject的委托方法
public class EventHandler: MarshalByRefObject { public void HandleMessage(String msg) { Console.WriteLine("Received: {0}",msg); } public override object InitializeLifetimeService() { // this object has to live "forever" return null; } }
3.2调用事件时,委托接收的方法应是继承自MarshalByRefObject的方法
static void Main(string[] args) { String filename = "eventlistener.exe.config"; RemotingConfiguration.Configure(filename); IBroadcaster bcaster = (IBroadcaster) RemotingHelper.GetObject(typeof(IBroadcaster)); Console.WriteLine("Registering event at server"); // callbacks can only work on MarshalByRefObjects, so // I created a different class for this as well EventHandler eh = new EventHandler(); bcaster.MessageArrived += new MessageArrivedHandler(eh.HandleMessage); Console.WriteLine("Event registered. Waiting for messages."); Console.ReadLine(); }
上面的方法将会报错
在中间层加入一个事件,由事件触发获取内部委托,由内部对象触发事件,不可以直接触发,一定要在中间层,不可以直接在客户端添加
public class BroadcastEventWrapper : MarshalByRefObject { public event MessageArrivedHandler MessageArrivedLocally; [OneWay] public void LocallyHandleMessageArrived(String msg) { // forward the message to the client MessageArrivedLocally(msg); } public override object InitializeLifetimeService() { // this object has to live "forever" return null; } }
调整后如下
static void Main(string[] args) { String filename = "eventlistener.exe.config"; RemotingConfiguration.Configure(filename); IBroadcaster bcaster = (IBroadcaster) RemotingHelper.GetObject(typeof(IBroadcaster)); BroadcastEventWrapper eventWrapper =new BroadcastEventWrapper(); // register the local handler with the "remote" handler eventWrapper.MessageArrivedLocally +=new MessageArrivedHandler(HandleMessage); Console.WriteLine("Registering event at server"); bcaster.MessageArrived +=new MessageArrivedHandler(eventWrapper.LocallyHandleMessageArrived); Console.WriteLine("Event registered. Waiting for messages."); Console.ReadLine(); } public static void HandleMessage(String msg) { Console.WriteLine("Received: {0}", msg); }