pardahlman / RawRabbit

A modern .NET framework for communication over RabbitMq
MIT License
747 stars 144 forks source link

Serializing delegates is not supported on this platform. #286

Closed tiago-alves closed 6 years ago

tiago-alves commented 7 years ago

Hi,

I'm trying to implement an image processing service that is going to receive images to be processed and will return the extracted information to a different queue. After removing all the unnecessary code I realized that the problem I am facing is when I call publish from within subscribe delegate.

Below is the method where I subscribe.

public async Task StartListening()
        {
            try
            {
                _log.InfoFormat("Preparing to subscribe to queue messages");

                LoadConfiguration();

                CreateBusClient();
                _log.DebugFormat("BusClient created, calling subscribe");

                _client.SubscribeAsync<string>((msgStr, context) =>
                {

                    _client.PublishAsync("test", default(Guid), cfg => cfg.WithExchange(exc => exc.WithName("face_process_exchange").WithType(ExchangeType.Direct)).WithRoutingKey("face_process_response"));
                    return Task.FromResult(true);

                }, cfg => cfg.WithExchange(exc => exc.WithName(_configuration.Exchange).WithType(ExchangeType.Direct)).
                            WithRoutingKey(_configuration.RoutingKeyToListen).
                            WithQueue(q => q.WithName(_configuration.QueueToListen)).
                            WithSubscriberId(""));

                _log.Info("Subscribed to queue");
            }
            catch(Exception e)
            {
                _log.ErrorFormat("Failed to subscribe to queue: {0}", e.ToString());
            }
        }

And here is the method where I create the BusClient;

private void CreateBusClient()
        {
            var busConfig = new RawRabbitConfiguration
            {
                Username = _configuration.ConnectionUsername,
                Password = _configuration.ConnectionPassword,
                Port = _configuration.ConnectionPort,
                VirtualHost = "/",
                Hostnames = { _configuration.Hostname },
                RouteWithGlobalId = false
            };

            _log.DebugFormat("Calling BusClientFactory.CreateDefault for _configuration read as: {0}", _configuration.ToString());

            var addCfg = new Action<IServiceCollection>(s => s.AddSingleton(p => busConfig));
            var serviceProvider = new ServiceCollection().AddRawRabbit<AdvancedMessageContext>(null, addCfg).BuildServiceProvider();

            var cs = serviceProvider.GetService<IBusClient<AdvancedMessageContext>>();
            _client = new RawRabbit.vNext.Disposable.BusClient<AdvancedMessageContext>(cs);
        }

The problem is that I always get the following exception when PublishAsync is called.

System.Runtime.Serialization.SerializationException: Serializing delegates is not supported on this platform.
   at System.MulticastDelegate.GetObjectData(SerializationInfo info, StreamingContext context)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeISerializable(JsonWriter writer, ISerializable value, JsonISerializableContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType)
   at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType)
   at RawRabbit.Context.Provider.MessageContextProviderBase`1.SerializeContext(TMessageContext messageContext)
   at RawRabbit.Context.Provider.MessageContextProviderBase`1.GetMessageContext(Guid& globalMessageId)
   at RawRabbit.Operations.Publisher`1.PublishAsync[TMessage](TMessage message, Guid globalMessageId, PublishConfiguration config)
   at RawRabbit.Common.BaseBusClient`1.PublishAsync[T](T message, Guid globalMessageId, Action`1 configuration)
   at RawRabbit.vNext.Disposable.BusClient`1.PublishAsync[T](T message, Guid globalMessageId, Action`1 configuration)
   at SimpleID.FaceProcessing.Services.Implementation.RawRabbitQueueService.<StartListening>b__11_0(String msgStr, AdvancedMessageContext context)
pardahlman commented 7 years ago

I believe this is an issue with the AdvancedMessageContext. It is possible to fix, but requires registering custom internal services. Before I'll go into the details: do you think it would be at all feasable to migrate to 2.0 (currently in rc1)? This is no longer an issue for that client.

pardahlman commented 6 years ago

Closing this now. Feel free to re-open if you have any more issues regarding this.