Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Ukázka DeadLetter ukazuje, jak zvládnout a zpracovat zprávy, které nebyly úspěšně doručeny. Je založen na ukázkovém příkladu Transacted MSMQ Binding. Tato ukázka používá netMsmqBinding vazbu. Služba je konzolová aplikace v místním prostředí, která umožňuje sledovat službu, která přijímá zprávy ve frontě.
Poznámka:
Postup nastavení a pokyny k sestavení pro tuto ukázku najdete na konci tohoto tématu.
Poznámka:
Tato ukázka demonstruje každou frontu nedoručených zpráv aplikace, která je k dispozici pouze v systému Windows Vista. Ukázku lze upravit tak, aby používala výchozí systémové fronty pro MSMQ 3.0 v systémech Windows Server 2003 a Windows XP.
Při frontové komunikaci klient komunikuje pomocí fronty se službou. Přesněji řečeno, klient odesílá zprávy do fronty. Služba přijímá zprávy z fronty. Služba a klient tedy nemusí být spuštěny současně, aby mohly komunikovat pomocí fronty.
Vzhledem k tomu, že komunikace ve frontě může zahrnovat určitou míru nečinnosti, můžete ke zprávě přidružit hodnotu time-to-live, abyste zajistili, že se zpráva nedoručí do aplikace, pokud uplynula čas. Existují také případy, kdy musí být aplikace informována, jestli zpráva selhala. Ve všech těchto případech, například když vypršela platnost zprávy typu time-to-live nebo zpráva selhala, zpráva se vloží do fronty nedoručených zpráv. Odesílající aplikace pak může číst zprávy ve frontě nedoručených zpráv a provádět opravné akce v rozsahu od žádné akce až po opravu důvodů neúspěšného doručení a opětovného odeslání zprávy.
Fronta nedoručených zpráv ve vazbě NetMsmqBinding je vyjádřena následujícími vlastnostmi:
DeadLetterQueue vlastnost, která vyjadřuje typ fronty nedoručených zpráv požadovaných klientem. Tento výčet má následující hodnoty:
None: Klient nevyžaduje žádnou frontu nedoručených zpráv.System: Fronta nedoručených zpráv systému se používá k ukládání mrtvých zpráv. Systémová fronta nedoručených zpráv je sdílena všemi aplikacemi spuštěnými na počítači.Custom: Vlastní fronta nedoručených zpráv zadaná pomocí CustomDeadLetterQueue vlastnosti se používá k ukládání mrtvých zpráv. Tato funkce je k dispozici pouze v systému Windows Vista. To se používá, když aplikace musí místo sdílení s jinými aplikacemi spuštěnými na stejném počítači používat vlastní frontu nedoručených zpráv.CustomDeadLetterQueue pro vyjádření konkrétní fronty, která se má použít jako fronta nedoručených zpráv. Tato možnost je k dispozici pouze v systému Windows Vista.
V této ukázce klient odešle službě dávku zpráv z rozsahu transakce a určuje libovolně nízkou hodnotu pro tyto zprávy "time-to-live" (přibližně 2 sekundy). Klient také určuje vlastní frontu nedoručených zpráv, která se má použít k zařazení zpráv, jejichž platnost vypršela.
Klientská aplikace může číst zprávy ve frontě nedoručených zpráv a buď zkusit zprávu odeslat znovu, nebo opravit chybu, která způsobila umístění původní zprávy do fronty nedoručených zpráv a odeslání zprávy. V ukázce zobrazí klient chybovou zprávu.
Kontrakt služby je , jak je IOrderProcessorznázorněno v následujícím vzorovém kódu.
[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]
public interface IOrderProcessor
{
[OperationContract(IsOneWay = true)]
void SubmitPurchaseOrder(PurchaseOrder po);
}
Kód služby v ukázce je ten pro Transacted MSMQ Binding.
Komunikace se službou probíhá v rámci transakce. Služba čte zprávy z fronty, provede operaci a pak zobrazí výsledky operace. Aplikace také vytvoří frontu nedoručených zpráv pro nedoručené zprávy.
//The service contract is defined in generatedClient.cs, generated from the service by the svcutil tool.
//Client implementation code.
class Client
{
static void Main()
{
// Get MSMQ queue name from app settings in configuration
string deadLetterQueueName = ConfigurationManager.AppSettings["deadLetterQueueName"];
// Create the transacted MSMQ queue for storing dead message if necessary.
if (!MessageQueue.Exists(deadLetterQueueName))
MessageQueue.Create(deadLetterQueueName, true);
// Create a proxy with given client endpoint configuration
OrderProcessorClient client = new OrderProcessorClient("OrderProcessorEndpoint");
// Create the purchase order
PurchaseOrder po = new PurchaseOrder();
po.CustomerId = "somecustomer.com";
po.PONumber = Guid.NewGuid().ToString();
PurchaseOrderLineItem lineItem1 = new PurchaseOrderLineItem();
lineItem1.ProductId = "Blue Widget";
lineItem1.Quantity = 54;
lineItem1.UnitCost = 29.99F;
PurchaseOrderLineItem lineItem2 = new PurchaseOrderLineItem();
lineItem2.ProductId = "Red Widget";
lineItem2.Quantity = 890;
lineItem2.UnitCost = 45.89F;
po.orderLineItems = new PurchaseOrderLineItem[2];
po.orderLineItems[0] = lineItem1;
po.orderLineItems[1] = lineItem2;
//Create a transaction scope.
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
{
// Make a queued call to submit the purchase order
client.SubmitPurchaseOrder(po);
// Complete the transaction.
scope.Complete();
}
client.Close();
Console.WriteLine();
Console.WriteLine("Press <ENTER> to terminate client.");
Console.ReadLine();
}
}
Konfigurace klienta určuje krátkou dobu, po kterou se zpráva dostane ke službě. Pokud zprávu nelze přenést během zadané doby trvání, vyprší platnost zprávy a přesune se do fronty nedoručených zpráv.
Poznámka:
Klient může zprávu doručit do fronty služby v zadaném čase. Abyste mohli zkontrolovat fungování služby pro nedoručené zprávy, měli byste nejprve spustit klienta před spuštěním služby. Zpráva vyprší a doručí se do služby nedoručených zpráv.
Aplikace musí definovat, která fronta se má použít jako fronta nedoručených zpráv. Pokud není určena žádná fronta, použije se výchozí systémová transakční fronta nedoručených zpráv k zařazení mrtvých zpráv. V tomto příkladu klientská aplikace určuje vlastní frontu nedoručených zpráv aplikace.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<!-- use appSetting to configure MSMQ Dead Letter queue name -->
<add key="deadLetterQueueName" value=".\private$\ServiceModelSamplesOrdersAppDLQ"/>
</appSettings>
<system.serviceModel>
<client>
<!-- Define NetMsmqEndpoint -->
<endpoint name="OrderProcessorEndpoint"
address="net.msmq://localhost/private/ServiceModelSamplesDeadLetter"
binding="netMsmqBinding"
bindingConfiguration="PerAppDLQBinding"
contract="IOrderProcessor" />
</client>
<bindings>
<netMsmqBinding>
<binding name="PerAppDLQBinding"
deadLetterQueue="Custom"
customDeadLetterQueue="net.msmq://localhost/private/ServiceModelSamplesOrdersAppDLQ"
timeToLive="00:00:02"/>
</netMsmqBinding>
</bindings>
</system.serviceModel>
</configuration>
Služba nedoručených zpráv čte zprávy z fronty nedoručených zpráv. Služba nedoručených zpráv implementuje IOrderProcessor kontrakt. Jeho implementace však nezpracovává objednávky. Služba nedoručených zpráv je klientská služba a nemá možnost zpracovávat objednávky.
Poznámka:
Fronta nedoručených zpráv je fronta klienta a je místní pro správce front klienta.
Implementace služby nedoručených zpráv kontroluje důvod selhání doručení zprávy a přijímá nápravná opatření. Důvod selhání zprávy je zaznamenán ve dvou výčtech DeliveryFailure a DeliveryStatus. Můžete načíst MsmqMessageProperty z OperationContext, jak je uvedeno v následujícím příkladu kódu:
public void SubmitPurchaseOrder(PurchaseOrder po)
{
Console.WriteLine("Submitting purchase order did not succeed ", po);
MsmqMessageProperty mqProp =
OperationContext.Current.IncomingMessageProperties[
MsmqMessageProperty.Name] as MsmqMessageProperty;
Console.WriteLine("Message Delivery Status: {0} ",
mqProp.DeliveryStatus);
Console.WriteLine("Message Delivery Failure: {0}",
mqProp.DeliveryFailure);
Console.WriteLine();
…
}
Zprávy ve frontě nedoručených zpráv jsou zprávy, které jsou adresovány službě, která zprávu zpracovává. Proto když služba nedoručených zpráv čte zprávy z fronty, kanálová vrstva Windows Communication Foundation (WCF) najde neshodu v koncových bodech a nepředává zprávu. V tomto případě je zpráva adresována službě zpracování objednávek, ale je přijata službou nedoručených zpráv. Chcete-li obdržet zprávu, která je adresována jinému koncovému bodu, filtr adresy, který odpovídá jakékoli adrese, je zadán v sadě ServiceBehavior. Je to nutné pro úspěšné zpracování zpráv, které jsou čteny z fronty nedoručených zpráv.
V této ukázce služba nedoručených zpráv zprávu odešle znovu, pokud je důvodem selhání, že vypršel časový limit zprávy. Ze všech ostatních důvodů zobrazuje selhání doručení, jak je znázorněno v následujícím ukázkovém kódu:
// Service class that implements the service contract.
// Added code to write output to the console window.
[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single, ConcurrencyMode=ConcurrencyMode.Single, AddressFilterMode=AddressFilterMode.Any)]
public class PurchaseOrderDLQService : IOrderProcessor
{
OrderProcessorClient orderProcessorService;
public PurchaseOrderDLQService()
{
orderProcessorService = new OrderProcessorClient("OrderProcessorEndpoint");
}
[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
public void SubmitPurchaseOrder(PurchaseOrder po)
{
Console.WriteLine("Submitting purchase order did not succeed ", po);
MsmqMessageProperty mqProp = OperationContext.Current.IncomingMessageProperties[MsmqMessageProperty.Name] as MsmqMessageProperty;
Console.WriteLine("Message Delivery Status: {0} ", mqProp.DeliveryStatus);
Console.WriteLine("Message Delivery Failure: {0}", mqProp.DeliveryFailure);
Console.WriteLine();
// resend the message if timed out
if (mqProp.DeliveryFailure == DeliveryFailure.ReachQueueTimeout ||
mqProp.DeliveryFailure == DeliveryFailure.ReceiveTimeout)
{
// re-send
Console.WriteLine("Purchase order Time To Live expired");
Console.WriteLine("Trying to resend the message");
// reuse the same transaction used to read the message from dlq to enqueue the message to app. queue
orderProcessorService.SubmitPurchaseOrder(po);
Console.WriteLine("Purchase order resent");
}
}
// Host the service within this EXE console application.
public static void Main()
{
// Create a ServiceHost for the PurchaseOrderDLQService type.
using (ServiceHost serviceHost = new ServiceHost(typeof(PurchaseOrderDLQService)))
{
// Open the ServiceHostBase to create listeners and start listening for messages.
serviceHost.Open();
// The service can now be accessed.
Console.WriteLine("The dead letter service is ready.");
Console.WriteLine("Press <ENTER> to terminate service.");
Console.WriteLine();
Console.ReadLine();
}
}
}
Následující ukázka ukazuje konfiguraci pro nedoručitelnou zprávu:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service
name="Microsoft.ServiceModel.Samples.PurchaseOrderDLQService">
<!-- Define NetMsmqEndpoint in this case, DLQ end point to read messages-->
<endpoint address="net.msmq://localhost/private/ServiceModelSamplesOrdersAppDLQ"
binding="netMsmqBinding"
bindingConfiguration="DefaultBinding"
contract="Microsoft.ServiceModel.Samples.IOrderProcessor" />
</service>
</services>
<client>
<!-- Define NetMsmqEndpoint -->
<endpoint name="OrderProcessorEndpoint"
address="net.msmq://localhost/private/ServiceModelSamplesDeadLetter"
binding="netMsmqBinding"
bindingConfiguration="SystemDLQBinding"
contract="IOrderProcessor" />
</client>
<bindings>
<netMsmqBinding>
<binding name="DefaultBinding" />
<binding name="SystemDLQBinding"
deadLetterQueue="System"/>
</netMsmqBinding>
</bindings>
</system.serviceModel>
</configuration>
Při spuštění ukázky existují 3 spustitelné programy ke spuštění, abyste viděli, jak fronta nedoručených zpráv funguje pro každou aplikaci: klientský program, služba a služba pro nedoručené zprávy, která čte z fronty nedoručených zpráv pro každou aplikaci a znovu odešle zprávu službě. Všechny jsou konzolové aplikace s výstupem v oknech konzoly.
Poznámka:
Protože je fronta v provozu, klient a služba nemusí být ve stejnou dobu uvedeny do provozu. Klienta můžete spustit, vypnout ho a pak spustit službu a stále přijímat její zprávy. Službu byste měli spustit a vypnout, aby se fronta vytvořila.
Při spuštění klienta zobrazí klient zprávu:
Press <ENTER> to terminate client.
Klient se pokusil zprávu odeslat, ale kvůli krátkému časovému limitu její platnost vypršela a nyní je zařazena do fronty nevyřízených zpráv pro každou aplikaci.
Pak spustíte službu nedoručených zpráv, která přečte zprávu a zobrazí kód chyby a znovu odešle zprávu zpět do služby.
The dead letter service is ready.
Press <ENTER> to terminate service.
Submitting purchase order did not succeed
Message Delivery Status: InDoubt
Message Delivery Failure: ReachQueueTimeout
Purchase order Time To Live expired
Trying to resend the message
Purchase order resent
Služba se spustí, poté přečte znovu zaslanou zprávu a zpracuje ji.
The service is ready.
Press <ENTER> to terminate service.
Processing Purchase Order: 97897eff-f926-4057-a32b-af8fb11b9bf9
Customer: somecustomer.com
OrderDetails
Order LineItem: 54 of Blue Widget @unit price: $29.99
Order LineItem: 890 of Red Widget @unit price: $45.89
Total cost of this order: $42461.56
Order status: Pending
Jak nastavit, sestavit a spustit ukázku
Ujistěte se, že jste provedli instalační proceduru One-Time pro ukázky Windows Communication Foundation.
Pokud je služba spuštěná jako první, zkontroluje, jestli je fronta k dispozici. Pokud fronta není k dispozici, služba ji vytvoří. Službu můžete nejprve spustit, abyste vytvořili frontu, nebo ji můžete vytvořit prostřednictvím Správce front MSMQ. Podle těchto kroků vytvořte frontu v systému Windows 2008.
Otevřete Správce serveru v sadě Visual Studio 2012.
Rozbalte panel Funkce.
Klikněte pravým tlačítkem na Soukromé fronty zpráva vyberte Nová, soukromá fronta.
Zaškrtněte políčko Transakční.
Jako název nové fronty zadejte
ServiceModelSamplesTransacted.
Pokud chcete sestavit verzi C# nebo Visual Basic .NET řešení, postupujte podle pokynů v Sestavení ukázek Windows Communication Foundation.
Pokud chcete ukázku spustit v konfiguraci jednoho počítače nebo mezi více počítači, změňte názvy front odpovídajícím způsobem, nahraďte localhost úplným názvem počítače a postupujte podle pokynů v Spuštění ukázek Windows Communication Foundation.
Ke spuštění ukázky na počítači připojeném k pracovní skupině
Pokud váš počítač není součástí domény, vypněte zabezpečení přenosu nastavením režimu ověřování a úrovně ochrany tak, jak
Noneje znázorněno v následující ukázkové konfiguraci:<bindings> <netMsmqBinding> <binding name="TransactedBinding"> <security mode="None"/> </binding> </netMsmqBinding> </bindings>Ujistěte se, že je koncový bod svázán s vazbou, nastavením atributu
bindingConfigurationkoncového bodu.Před spuštěním ukázky nezapomeňte změnit konfiguraci na serveru DeadLetterService a klientovi.
Poznámka:
Nastavení
security modeje ekvivalentní nastaveníNone,MsmqAuthenticationModeaMsmqProtectionLevelzabezpečení naMessage.
Komentáře
Ve výchozím nastavení s přenosem vazby netMsmqBinding je povoleno zabezpečení. Dvě vlastnosti MsmqAuthenticationMode a MsmqProtectionLevelspolečně určují typ zabezpečení přenosu. Ve výchozím nastavení je režim ověřování nastaven Windows na a úroveň ochrany je nastavena na Sign. Aby služba MSMQ poskytovala funkci ověřování a podepisování, musí být součástí domény. Pokud tuto ukázku spustíte v počítači, který není součástí domény, zobrazí se následující chyba: "Certifikát řízení front zpráv uživatele neexistuje".