Событие публикации NServicebus - получает пустое сообщение - PullRequest
1 голос
/ 22 июля 2011

После публикации события в моем домене я продолжаю получать следующее сообщение с моего хоста денормализатора:

2011-07-22 14:18:32,374 [Worker.5] WARN  NServiceBus.Unicast.UnicastBus [(null)]
 <(null)> - Received an empty message - ignoring.

Я просто делаю это с Jolivers Eventstore:

return Wireup.Init()
                .UsingRavenPersistence("EventStore", new DocumentObjectSerializer())
                .UsingAsynchronousDispatcher()
                .PublishTo(new DelegateMessagePublisher(c => container.Resolve<IPublishMessages>().Publish(c)))
                .Build();

IPublishMessages разрешается в:

 public sealed class NServiceBusPublisher : IPublishMessages
{
    private const string AggregateIdKey = "AggregateId";
    private const string CommitVersionKey = "CommitVersion";
    private const string EventVersionKey = "EventVersion";
    private const string BusPrefixKey = "Bus.";
    private readonly IBus bus;

    public NServiceBusPublisher(IBus bus)
    {
        this.bus = bus;
    }

    public void Dispose()
    {
        GC.SuppressFinalize(this);
    }

    public void Publish(Commit commit)
    {
        for (var i = 0; i < commit.Events.Count; i++)
        {
            var eventMessage = commit.Events[i];
            var busMessage = eventMessage.Body as IMessage;
            AppendHeaders(busMessage, commit.Headers); // optional
            AppendHeaders(busMessage, eventMessage.Headers); // optional
            AppendVersion(commit, i); // optional
            this.bus.Publish(busMessage);
        }
    }
    private static void AppendHeaders(IMessage message, IEnumerable<KeyValuePair<string, object>> headers)
    {
        headers = headers.Where(x => x.Key.StartsWith(BusPrefixKey));
        foreach (var header in headers)
        {
            var key = header.Key.Substring(BusPrefixKey.Length);
            var value = (header.Value ?? string.Empty).ToString();
            message.SetHeader(key, value);
        }
    }
    private static void AppendVersion(Commit commit, int index)
    {
        var busMessage = commit.Events[index].Body as IMessage;
        busMessage.SetHeader(AggregateIdKey, commit.StreamId.ToString());
        busMessage.SetHeader(CommitVersionKey, commit.StreamRevision.ToString());
        busMessage.SetHeader(EventVersionKey, GetSpecificEventVersion(commit, index).ToString());
    }
    private static int GetSpecificEventVersion(Commit commit, int index)
    {
        // e.g. (StreamRevision: 120) - (5 events) + 1 + (index @ 4: the last index) = event version: 120
        return commit.StreamRevision - commit.Events.Count + 1 + index;
    }
}

Хост NServiceBus, публикующий события, имеет следующую конфигурацию:

    <MsmqTransportConfig
    InputQueue="SonatribeInputQueue"
    ErrorQueue="error"
    NumberOfWorkerThreads="1"
    MaxRetries="5"
    />

  <UnicastBusConfig
     DistributorControlAddress=""
     DistributorDataAddress=""
     ForwardReceivedMessagesTo="">
    <MessageEndpointMappings>
      <add Messages="Events" Endpoint="SonatribeInputQueue"/>
    </MessageEndpointMappings>
  </UnicastBusConfig>

И хост денормализатора, получающий события:

 <MsmqTransportConfig
    InputQueue="MyServerInputQueue"
    ErrorQueue="error"
    NumberOfWorkerThreads="1"
    MaxRetries="5"
    />

  <UnicastBusConfig>
    <MessageEndpointMappings>
      <add Messages="Events" Endpoint="SonatribeInputQueue"/>
    </MessageEndpointMappings>
  </UnicastBusConfig>

Что мне кажется правильным - издатель обрабатывает команду, отправленную из Интернета, и домен вызывает событие. NServiceBusPublisher публикует событие, а хост денормализатора по крайней мере что-то получает! это просто не сообщение, которое было отправлено - или что-то произошло, по крайней мере, для того, чтобы думать, что сообщение пустое ...

Любой

***** обновление ***********

Теперь я получаю от l4n следующее:

2011-07-22 16:31:30,646 [Worker.7] ERROR NServiceBus.Faults.InMemory.FaultManage
r [(null)] <(null)> - Serialization failed for message with ID 56b7b693-090f-49b
d-83ad-7beeb334fe6d\12639.
System.Security.VerificationException: Operation could destabilize the runtime.
   at SetId(Object , Object )
   at NServiceBus.Serializers.XML.MessageSerializer.GetObjectOfTypeFromNode(Type
 t, XmlNode node) in c:\Dev\NServiceBus\src\impl\Serializers\NServiceBus.Seriali
zers.XML\MessageSerializer.cs:line 343
   at NServiceBus.Serializers.XML.MessageSerializer.Process(XmlNode node, Object
 parent) in c:\Dev\NServiceBus\src\impl\Serializers\NServiceBus.Serializers.XML\
MessageSerializer.cs:line 330
   at NServiceBus.Serializers.XML.MessageSerializer.Deserialize(Stream stream) i
n c:\Dev\NServiceBus\src\impl\Serializers\NServiceBus.Serializers.XML\MessageSer
ializer.cs:line 267
   at NServiceBus.Unicast.UnicastBus.Extract(TransportMessage m) in c:\Dev\NServ
iceBus\src\unicast\NServiceBus.Unicast\UnicastBus.cs:line 851
2011-07-22 16:31:30,908 [Worker.7] WARN  NServiceBus.Unicast.UnicastBus [(null)]
 <(null)> - Received an empty message - ignoring.

Вот сообщение, которое оно пытается десериализовать !!

[Serializable]
public class AccountCreatedEvent : IEvent
{
    public readonly string Id;
    public readonly string Name;

    public AccountCreatedEvent()
    {

    }

    public AccountCreatedEvent(string id, string name)
    {
        this.Id = id;
        this.Name = name;
    }
    public override string ToString()
    {
        return "AccountCreatedEvent - for when you've created an account";
    }
}

не совсем ничего беспокойного ...

1 Ответ

5 голосов
/ 26 июля 2011

Понятно, почему это сообщение нельзя десериализовать - у вас есть свойства только для чтения.Если вы хотите иметь эту работу, вам нужно переключиться на общедоступные свойства get / set.Чтобы сохранить ваше намерение не публично изменяемых свойств, вот альтернативный подход:

[Serializable]
public class AccountCreatedEvent : IEvent
{
    public string Id { get; private set; }
    public string Name {get; private set; }

    public AccountCreatedEvent(string id, string name)
    {
        this.Id = id;
        this.Name = name;
    }

    public override string ToString()
    {
        return "AccountCreatedEvent - for when you've created an account";
    }
}
...