Remoting 事件注册

最近真是晕了,事件注册老是注册不上,把情况摘录下来。
一、模块功能

利用Remoting技术广播报警消息,注册的客户端都可以接收到报警信息。

结构:SendAlarm---->AlarmServer---->ReceiveAlarm

ReceiveAlarm类接收到报警在触发自定义事件,这样在主界面报警框类、电子地图上联动报警信息。

二、部分代码

1、远程接口定义

C# code
 
   
namespace KnownObjects { /// <summary> /// 报警结构体 /// </summary> [Serializable] public struct ALARM { public string ipAddress; public string hostName; public string alarmTime; public string alarmMess; } /// <summary> /// 报警客户端 /// </summary> public interface IAlarmClient { /// <summary> /// 消息反馈 /// </summary> /// <param name="message"> A message. </param> object ReceiveMessage(ALARM message); } /// <summary> /// 报警消息通用方法 /// </summary> public interface IAlarmRoom { /// <summary> /// 发送报警信息到所有客户端 /// </summary> /// <param name="message"> Message to send. </param> void SendMessage(ALARM message); /// <summary> /// 注册报警客户端 /// </summary> /// <param name="iAlarmClient"></param> void AttachClient(IAlarmClient iAlarmClient); } }


2、客户接收端

C# code
 
   
namespace ReceiveClient { /// <summary> /// ChatClient demostrates simple client application. /// </summary> public class ReceiveAlarm : MarshalByRefObject, IAlarmClient { public class AlarmMsgEventArgs : EventArgs { // 1. Type defining information passed to receivers of the event public AlarmMsgEventArgs(String ip, String hostname, String mess, String time) { this .ip = ip; this .hostname = hostname; this .mess = mess; this .time = time; } public readonly String ip, hostname,mess,time; } // 报警消息委托 public delegate void AlarmMsgEventHandler(Object sender,AlarmMsgEventArgs args); // 报警消息事件 public event AlarmMsgEventHandler AlarmMsg; // 负责通知事件的登记对象 protected virtual void OnAlarmMsg(AlarmMsgEventArgs e) { // Has any objects registered interest with our event? if (AlarmMsg != null ) { // Yes, notify all the objects AlarmMsg( this , e); } } private IAlarmRoom iAlarmRoom; /// <summary> /// Sigleton instance. /// </summary> public static ReceiveAlarm Instance = new ReceiveAlarm(); public ReceiveAlarm() { } // 连接服务器 public bool InitRemoting() { try { System.Configuration.ConfigurationSettings.GetConfig( " DNS " ); GlobalEventContainer.GenuineChannelsGlobalEvent += new GenuineChannelsGlobalEventHandler(GenuineChannelsEventHandler); RemotingConfiguration.Configure( " Client.exe.config " ); iAlarmRoom = (IAlarmRoom)Activator.GetObject( typeof (IAlarmRoom), " gtcp://127.0.0.1:8737/ChatRoom.rem " ); iAlarmRoom.AttachClient(ReceiveAlarm.Instance); } catch (System.Exception e) { Console.WriteLine( " 异常错误:服务器未启动? " ); return false ; } return true ; } public static void GenuineChannelsEventHandler( object sender, GlobalEventArgs e) { Console.WriteLine( " Global event: {0}, Url: {1}, Exception: {2} " , e.EventType, e.Url, e.SourceException); if (e.EventType == GlobalEventTypes.GTcpConnectionClosed && e.SourceException is OperationException && ((OperationException)e.SourceException).OperationErrorMessage.ErrorIdentifier.IndexOf( " ServerHasBeenRestarted " ) > - 1 ) { // server has been restarted so we have to register our listener again IAlarmRoom iAlarmRoom = (IAlarmRoom)Activator.GetObject( typeof (IAlarmRoom), " gtcp://127.0.0.1:8737/ChatRoom.rem " ); iAlarmRoom.AttachClient(ReceiveAlarm.Instance); } } /// <summary> /// 接收到报警信息.实现了远程接口的方法 /// </summary> /// <param name="message"> The message. </param> public object ReceiveMessage(ALARM message) { /// 测试,接收到消息后触发本地自定义事件,但是有问题,AlarmMsg=null;测试类在后面 AlarmMsgEventArgs e = new AlarmMsgEventArgs(message.ipAddress, message.hostName, message.alarmMess, message.alarmTime); OnAlarmMsg(e); // 这里能够打印出远程传来的信息 Console.WriteLine( " {0},{1},{2},{3} " ,message.ipAddress, message.hostName, message.alarmMess, message.alarmTime); return null ; } public void ArrivingMsg( string ip, string hostname, string mess, string time) { AlarmMsgEventArgs e = new AlarmMsgEventArgs(ip, hostname, mess, time); OnAlarmMsg(e); // Console.WriteLine("Msg...(AppDomain:{0} {1})", AppDomain.CurrentDomain.FriendlyName,mess); } /// <summary> /// This is to insure that when created as a Singleton, the first instance never dies, /// regardless of the expired time. /// </summary> /// <returns></returns> public override object InitializeLifetimeService() { return null ; } } }



3、测试类

C# code
 
   
namespace ReceiveClient { public class Program { static void Main( string [] args) { ReceiveAlarm receive = new ReceiveAlarm(); receive.InitRemoting(); Receiver test = new Receiver(receive); Console.ReadLine(); } } // 测试类 // ReceiveAlarm对象以参数形式传递给测试类, public class Receiver { public Receiver(ReceiveAlarm mm) { // 注册事件 mm.AlarmMsg += new ReceiveAlarm.AlarmMsgEventHandler(RecMsg); } private void RecMsg(Object sender, ReceiveAlarm.AlarmMsgEventArgs e) { Console.WriteLine( " Receiving message: " ); Console.WriteLine( " IP: {0}\n HostName: {1}\n Message: {2}\n Time {3}\n " , e.ip, e.hostname, e.mess, e.time); } public void UnRegister(ReceiveAlarm mm) { mm.AlarmMsg -= new ReceiveAlarm.AlarmMsgEventHandler(RecMsg); } } }
 
 
三、解决方法
由于没有访问到触发的报警实例,所以没有注册到。
ContractedBlock.gif ExpandedBlockStart.gif Code
    public class Program
    {
        
static void Main(string[] args)
        {           
            ReceiveAlarm receive 
= new ReceiveAlarm();
            receive.InitRemoting();
            Receiver rec 
= new Receiver();

            
            Console.ReadLine();
        }
    }
    
public class Receiver
    {

        
/// <summary>
        
/// 要确保访问到触发的类,所以要使用sigleton
        
/// </summary>
        public Receiver()
        {
            
//receive = new ReceiveAlarm();
            
//receive.InitRemoting();
            
//receive.AlarmMsg+=new ReceiveAlarm.AlarmMsgEventHandler(RecMsg);

            ReceiveAlarm.Instance.AlarmMsg
+=new ReceiveAlarm.AlarmMsgEventHandler(RecMsg);
        }
        
        
private void RecMsg(Object sender, ReceiveAlarm.AlarmMsgEventArgs e)
        {
            Console.WriteLine(
" Receiving message:");
            Console.WriteLine(sender.GetType().ToString());
            Console.WriteLine(System.Threading.Thread.CurrentThread.ThreadState.ToString());
            Console.WriteLine(
" IP: {0}\n HostName: {1}\n Message: {2}\n Time {3}\n", e.ip, e.hostname, e.mess, e.time);
        }

        
public void UnRegister(ReceiveAlarm mm)
        {     
            mm.AlarmMsg 
-= new ReceiveAlarm.AlarmMsgEventHandler(RecMsg);
        }
    }
四、总结
当实例化多个类,就不能控制要访问的类。这是要考虑使用Sigleton模式
public class myClass
{
     public static myClass instance=new myClass();
     public myClass()
     {}
}

转载于:https://www.cnblogs.com/goodyao/archive/2008/09/09/1287616.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值