请问高人:
用.net remoting 实现“远程的事件”。
但是我在visual studio 2005调试的时候出现:
Type System.DelegateSerializationHolder and the types derived from it (such as System.DelegateSerializationHolder) are not permitted to be deserialized at this security level.
在注册事件的时候:            bcaster.MessageArrived +=new MessageArrivedHandler(eventWrapper.LocallyHandleMessageArrived);
下面没有办法运行了,请高手指点一二,不胜感激。
全部代码如下:
Interface:
using System;
using System.Collections.Generic;
using System.Text;
namespace General
{
    public delegate void MessageArrivedHandler(String msg);
    public interface IBroadcaster
    {
        void BroadcastMessage(String msg);
        event MessageArrivedHandler MessageArrived;
    }
    public class BroadcastEventWrapper : MarshalByRefObject
    {
        public event MessageArrivedHandler MessageArrivedLocally;        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;
        }
    }
}
Client:
using System;
using System.Runtime.Remoting;
using General;
//using RemotingTools; // RemotingHelpernamespace EventListener
{
    class EventListener
    {
        static void Main(string[] args)
        {
            String filename = "Client.exe.config";
            RemotingConfiguration.Configure(filename,false);            IBroadcaster bcaster = (IBroadcaster)Activator.GetObject(typeof(IBroadcaster), "http://localhost:5555/Broadcaster.soap");
               
//            IBroadcaster bcaster =
  //             (IBroadcaster)RemotingHelper.GetObject(typeof(IBroadcaster));            // this one will be created in the client's context and a
            // reference will be passed to the server
            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);
        }
    }
}配置文件:
<configuration>
  <system.runtime.remoting>
    <application>      <channels>
         <channel ref="http"/>
      </channels>      <client>
        <wellknown type="General.IBroadcaster, General"
                    url="http://localhost:5555/Broadcaster.soap" />
      </client>    </application>
  </system.runtime.remoting>
</configuration>
//------------
还有个客户端的帮助类(不过我没有用,可以用注释的代码替换)
using System;
using System.Collections;
using System.Runtime.Remoting;namespace RemotingTools
{
    public class RemotingHelper
    {
        private static bool _isInit=false;
        private static IDictionary _wellKnownTypes;
        public static Object GetObject(Type type)
        {
            if (!_isInit) InitTypeCache();
            WellKnownClientTypeEntry entr =(WellKnownClientTypeEntry)_wellKnownTypes[type];
            if (entr == null)
            {
                throw new RemotingException("Type not found!");
            }
            return Activator.GetObject(entr.ObjectType, entr.ObjectUrl);
        }
        //-- HELP
        public static void InitTypeCache()
        {
            _wellKnownTypes = new Hashtable();
            foreach (WellKnownClientTypeEntry entr in RemotingConfiguration.GetRegisteredWellKnownClientTypes())
            {
                _wellKnownTypes.Add(entr.ObjectType, entr);
            }
        }
    }
}//--------------
Server:
using System;
using System.Runtime.Remoting;
using System.Threading;
using General;
namespace Server
{    public class Broadcaster : MarshalByRefObject, IBroadcaster
    {        public event General.MessageArrivedHandler MessageArrived;        public void BroadcastMessage(string msg)
        {
            Console.WriteLine("Will broadcast message: {0}", msg);
            SafeInvokeEvent(msg);
        }        private void SafeInvokeEvent(String msg)
        {
            // call the delegates manually to remove them if they aren't
            // active anymore.
            if (MessageArrived == null)
            {
                Console.WriteLine("No listeners");
            }
            else
            {                Console.WriteLine("Number of Listeners: {0}",
                                      MessageArrived.GetInvocationList().Length);                MessageArrivedHandler mah = null;                foreach (Delegate del in MessageArrived.GetInvocationList())
                {
                    try
                    {
                        mah = (MessageArrivedHandler)del;
                        mah(msg);
                    }
                    catch (Exception)
                    {
                        Console.WriteLine("Exception occured, will remove Delegate");
                        MessageArrived -= mah;
                    }
                }
            }
        }        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,false);            Console.WriteLine("Server started, press <return> to exit.");
            Console.ReadLine();
        }
    }
}

解决方案 »

  1.   

    自己顶一下
    在.Net Framework1.1中2.0应该没改变,微软对序列化的安全级别进行了限制。有关委托和事件的序列化、反序列化默认是禁止的,所以我们应该将TypeFilterLevel的属性值设置为Full枚举值
      

  2.   

    private void StartServer()
    {
     BinaryServerFormatterSinkProvider serverProvider = new 
      BinaryServerFormatterSinkProvider();
     BinaryClientFormatterSinkProvider clientProvider = new 
      BinaryClientFormatterSinkProvider();
     serverProvider.TypeFilterLevel = TypeFilterLevel.Full; IDictionary props = new Hashtable();
     props["port"] = 8080;
        HttpChannel channel = new HttpChannel(props,clientProvider,serverProvider);
     ChannelServices.RegisterChannel(channel); Obj = new BroadCastObj();
     ObjRef objRef = RemotingServices.Marshal(Obj,"BroadCastMessage.soap"); 
    }注意语句serverProvider.TypeFilterLevel = TypeFilterLevel.Full;此语句即设置序列化安全级别的。要使用TypeFilterLevel属性,必须申明命名空间:
    using System.Runtime.Serialization.Formatters;
      

  3.   

    我的问题解决了,主要参考了如下的网页,介绍的比较详细,遇到同样问题的朋友可以参考一下.
    http://wayfarer.cnblogs.com/articles/75213.html