Dela via


Reliable Messaging Protocol version 1.0

Det här avsnittet beskriver implementeringsinformation för Windows Communication Foundation (WCF) för protokollet WS-Reliable Messaging februari 2005 (version 1.0) som krävs för interoperation med http-transporten. WCF följer WS-Reliable Messaging-specifikationen med de begränsningar och förtydliganden som beskrivs i det här avsnittet. Observera att WS-ReliableMessaging version 1.0-protokollet implementeras från och med WinFX.

WS-Reliable Messaging Februari 2005-protokollet implementeras i WCF av ReliableSessionBindingElement.

För enkelhetens skull använder ämnet följande roller:

  • Initierare: klienten som initierar skapandet av WS-Reliable Message-sekvensen

  • Svarare: tjänsten som tar emot initierarens begäranden

Det här dokumentet använder prefixen och namnrymderna i följande tabell.

Prefix Namnområde
Wsrm http://schemas.xmlsoap.org/ws/2005/02/rm
netrm http://schemas.microsoft.com/ws/2006/05/rm
s http://www.w3.org/2003/05/soap-envelope
Wsa http://schemas.xmlsoap.org/ws/2005/08/addressing
Wsse http://docs.oasis-open.org/wss/2004/01/oasis-200401-wssecurity-secext-1.0.xsd

Meddelandetjänster

Meddelanden om sekvensetablering

WCF implementerar CreateSequence och CreateSequenceResponse meddelanden för att upprätta en tillförlitlig meddelandesekvens. Följande restriktioner gäller:

  • B1101: WCF-initieraren genererar inte det valfria expires-elementet CreateSequence i meddelandet eller, i de fall då CreateSequence meddelandet innehåller ett Offer element, det valfria Expires elementet i elementet Offer .

  • B1102: Vid åtkomst till CreateSequence meddelandet skickar och tar WCFResponder emot båda Expires elementen om de finns, men använder inte sina värden.

WS-Reliable Messaging introducerar mekanismen Offer för att upprätta de två omvända korrelerade sekvenserna som utgör en session.

  • R1103: Om CreateSequence innehåller ett Offer element måste Reliable Messaging Responder antingen acceptera sekvensen och svara med CreateSequenceResponse som innehåller ett wsrm:Accept element, bilda två korrelerade converse-sekvenser eller avvisa CreateSequence begäran.

  • R1104: SequenceAcknowledgement och programmeddelanden som flödar i omvänd sekvens måste skickas till slutpunktsreferensen för ReplyToCreateSequence.

  • R1105: AcksTo och ReplyTo slutpunktsreferenser i CreateSequence måste ha adressvärden som matchar oktettvis.

    WCF-svararen verifierar att URI-delen av AcksTo och ReplyTo EPR:erna är identiska innan en sekvens skapas.

  • R1106: AcksTo och ReplyTo Slutpunktsreferenser i CreateSequence bör ha samma uppsättning referensparametrar.

    WCF tillämpar inte men förutsätter att [referensparametrar] för AcksTo och ReplyToCreateSequence är identiska och använder [referensparametrar] från ReplyTo slutpunktsreferens för bekräftelser och samtalssekvensmeddelanden.

  • R1107: När två konversera sekvenser upprättas med hjälp av mekanismen Offer , SequenceAcknowledgement och programmeddelanden som flödar på converse-sekvenser måste skickas till slutpunktsreferensen för ReplyToCreateSequence.

  • R1108: När två konversera sekvenser upprättas med hjälp av erbjudandemekanismen [address] måste egenskapen för den underordnade elementet Slutpunktsreferens i elementet CreateSequenceResponsewsrm:Accept i matcha bytevis mål-URI:n för CreateSequence.wsrm:AcksTo

  • R1109: När två omvända sekvenser upprättas med hjälp av mekanismen Offer måste meddelanden som skickas av initieraren och bekräftelser till meddelanden av svararen skickas till samma slutpunktsreferens.

    WCF använder WS-Reliable Messaging för att upprätta tillförlitliga sessioner mellan initieraren och svararen. WCF:s WS-Reliable Messaging-implementering ger en tillförlitlig session för enkelriktade, begärandesvar och fullständiga duplex-meddelandemönster. Med WS-Reliable Messaging-mekanismen OfferCreateSequence/CreateSequenceResponse kan du upprätta två korrelerade converse-sekvenser och tillhandahåller ett sessionsprotokoll som är lämpligt för alla meddelandeslutpunkter. Eftersom WCF tillhandahåller en säkerhetsgaranti för en sådan session, inklusive skydd från slutpunkt till slutpunkt för sessionsintegritet, är det praktiskt att se till att meddelanden som är avsedda för samma part kommer till samma mål. På så sätt kan du även backa upp sekvensbekrästningar i programmeddelanden. Därför gäller begränsningarna R1104, R1105 och R1108 för WCF.

Ett exempel på ett CreateSequence meddelande.

<s:Envelope>
  <s:Header>
    <a:Action s:mustUnderstand="1">
      http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequence
    </a:Action>
    <a:ReplyTo>
      <a:Address>
         http://Business456.com/clientA
      </a:Address>
    </a:ReplyTo>
    <a:MessageID>
      urn:uuid:addabbbf-60cb-44d3-8c5b-9e0841629a36
    </a:MessageID>
    <a:To s:mustUnderstand="1">
      http://Business456.com/clientA
    </a:To>
  </s:Header>
  <s:Body>
    <wsrm:CreateSequence>
      <wsrm:AcksTo>
       <wsa:Address>
         http://Business456.com/clientA
       </wsa:Address>
     </wsrm:AcksTo>
     <wsrm:Offer>
      <wsrm:Identifier>
        urn:uuid:0afb8d36-bf26-4776-b8cf-8c91fddb5496
      </wsrm:Identifier>
     </wsrm:Offer>
   </wsrm:CreateSequence>
  </s:Body>
</s:Envelope>

Ett exempel på ett CreateSequenceResponse meddelande.

<s:Envelope>
  <s:Header>
    <a:Action s:mustUnderstand="1">
      http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequenceResponse
    </a:Action>
    <a:RelatesTo>
      urn:uuid:addabbbf-60cb-44d3-8c5b-9e0841629a36
    </a:RelatesTo>
    <a:To s:mustUnderstand="1">
      http://Business456.com/clientA
    </a:To>
  </s:Header>
  <s:Body>
   <wsrm:CreateSequenceResponse>
    <Identifier>
     urn:uuid:eea0a36c-b38a-43e8-8c76-2fabe2d76386
    </Identifier>
    <Accept>
    <AcksTo>
      <a:Address>
        http://BusinessABC.com/serviceA
      </a:Address>
    </AcksTo>
    </Accept>
   </wsrm:CreateSequenceResponse>
  </s:Body>
</s:Envelope>

Sequence

Följande är en lista över begränsningar som gäller för sekvenser:

  • B1201:WCF genererar och kommer åt sekvensnummer som inte är högre än xs:longmaximalt inkluderande värde, 9223372036854775807.

  • B1202:WCF genererar alltid ett tomfyllt sista meddelande med åtgärds-URI http://schemas.xmlsoap.org/ws/2005/02/rm/LastMessage:n för .

  • B1203: WCF tar emot och levererar ett meddelande med ett sekvenshuvud som innehåller ett LastMessage element så länge åtgärds-URI:n inte http://schemas.xmlsoap.org/ws/2005/02/rm/LastMessageär .

Ett exempel på en sekvensrubrik.

<wsrm:Sequence>
  <wsrm:Identifier>
    urn:uuid:addabbbf-60cb-44d3-8c5b-9e0841629a36
  </wsrm:Identifier>
  <wsrm:MessageNumber>
    10
  </wsrm:MessageNumber>
  <wsrm:LastMessage/>
 </wsrm:Sequence>

AckRequested-rubrik

WCF använder AckRequested Header som en keep-alive-mekanism. WCF genererar inte det valfria MessageNumber elementet. När ett meddelande med en AckRequested rubrik som innehåller elementet MessageNumber tas emot ignorerar MessageNumber WCF elementets värde, enligt följande exempel.

<wsrm:AckRequested>
  <wsrm:Identifier>
    urn:uuid:addabbbf-60cb-44d3-8c5b-9e0841629a36
  </wsrm:Identifier>
</wsrm:AckRequested>

SequenceAcknowledgement-rubrik

WCF använder piggy-back-mekanismen för sekvensbekrästningar som tillhandahålls i WS-Reliable Messaging.

  • R1401: När två konversera sekvenser upprättas med hjälp av mekanismen OfferSequenceAcknowledgement kan rubriken inkluderas i alla programmeddelanden som skickas till den avsedda mottagaren.

  • B1402: När WCF måste generera en bekräftelse innan sekvensmeddelanden tas emot (till exempel för att uppfylla ett AckRequested meddelande) genererar WCF en SequenceAcknowledgement rubrik som innehåller intervallet 0-0, som du ser i följande exempel.

    <wsrm:SequenceAcknowledgement>
      <wsrm:Identifier>
        urn:uuid:addabbbf-60cb-44d3-8c5b-9e0841629a36
      </wsrm:Identifier>
      <wsrm:AcknowledgementRange Upper="0" Lower="0"/>
    </wsrm:SequenceAcknowledgement>
    
  • B1403: WCF genererar SequenceAcknowledgement inte rubriker som innehåller ett Nack element men som stöder Nack element.

WS-ReliableMessaging-fel

Följande är en lista över begränsningar som gäller för WCF-implementeringen av WS-Reliable Messaging-fel:

  • B1501: WCF genererar MessageNumberRollover inga fel.

  • B1502:WCF-slutpunkten kan generera CreateSequenceRefused fel enligt beskrivningen i specifikationen.

  • B1503:När tjänstslutpunkten når anslutningsgränsen och inte kan bearbeta nya anslutningar genererar WCF ytterligare CreateSequenceRefused ett felunderkod, netrm:ConnectionLimitReached, som du ser i följande exempel.

    <s:Envelope>
      <s:Header>
        <wsa:Action>
          http://schemas.xmlsoap.org/ws/2005/08/addressing/fault
        </wsa:Action>
      </s:Header>
      <s:Body>
        <s:Fault>
          <s:Code>
            <s:Value>
              s:Receiver
            </s:Value>
            <s:Subcode>
              <s:Value>
                wsrm:CreateSequenceRefused
              </s:Value>
              <s:Subcode>
                <s:Value>
                  netrm:ConnectionLimitReached
                </s:Value>
              </s:Subcode>
            </s:Subcode>
          </s:Code>
          <s:Reason>
            <s:Text xml:lang="en">
              [Reason]
            </s:Text>
          </s:Reason>
        </s:Fault>
      </s:Body>
    </s:Envelope>
    

WS-adresseringsfel

Eftersom WS-Reliable Messaging använder WS-Addressing kan WCF WS-Reliable Messaging-implementering generera WS-adresseringsfel. Det här avsnittet beskriver WS-adresseringsfel som WCF uttryckligen genererar i WS-Reliable Messaging-lagret:

  • B1601:WCF genererar det meddelandeadresseringshuvud som krävs när något av följande är sant:

    • Ett meddelande saknar en Sequence rubrik och ett Action huvud.

    • Ett CreateSequence meddelande saknar en MessageId rubrik.

    • Ett CreateSequence meddelande saknar en ReplyTo rubrik.

  • B1602:WCF genererar felåtgärden stöds inte som svar på ett meddelande som saknar ett Sequence huvud och har ett Action huvud som inte är en identifierad i WS-Reliable Messaging-specifikationen.

  • B1603:WCF genererar felet Slutpunkten är inte tillgänglig för att indikera att slutpunkten inte bearbetar sekvensen baserat på undersökning av meddelandets adresshuvuden CreateSequence .

Protokollsammansättning

Sammansättning med WS-adressering

WCF stöder två versioner av WS-Addressing: WS-Addressing 2004/08 [WS-ADDR] och W3C WS-Addressing 1.0 Rekommendationer [WS-ADDR-CORE] och [WS-ADDR-SOAP].

Även om WS-Reliable Messaging-specifikationen endast nämner WS-Addressing 2004/08, begränsar den inte den WS-adresseringsversion som ska användas. Följande är en lista över begränsningar som gäller för WCF:

  • R2101:Både WS-Addressing 2004/08 och WS-Addressing 1.0 kan användas med WS-Reliable Messaging.

  • R2102:En enda version av WS-Addressing måste användas i en viss WS-Reliable Messaging-sekvens eller ett par converse-sekvenser som är korrelerade med hjälp av mekanismen wsrm:Offer .

Sammansättning med SOAP

WCF stöder användning av både SOAP 1.1 och SOAP 1.2 med WS-Reliable Messaging.

Sammansättning med WS-Security och WS-SecureConversation

WCF ger skydd för WS-Reliable Messaging-sekvenser med hjälp av säker transport (HTTPS), komposition med WS-Security och komposition med WS-Secure Conversation. Följande är en lista över begränsningar som gäller för WCF:

  • R2301:För att skydda integriteten i en WS-Reliable Messaging-sekvens utöver integriteten och konfidentialiteten för enskilda meddelanden kräver WCF att WS-Secure Conversation måste användas.

  • R2302:AWS-Secure Conversation-sessionen måste upprättas innan WS-Reliable Messaging-sekvenser upprättas.

  • R2303: Om WS-Reliable Messaging-sekvensens livslängd överskrider WS-Secure Conversation-sessionens livslängd måste den SecurityContextToken som upprättas med WS-Secure Conversation förnyas med hjälp av motsvarande WS-Secure Conversation Renewal-bindning.

  • B2304:WS-Reliable Messaging-sekvens eller ett par korrelerade converse-sekvenser är alltid bundna till en enda WS-SecureConversation-session.

    WCF-källan genererar elementet wsse:SecurityTokenReference i utökningsbarhetsavsnittet för elementet i CreateSequence meddelandet.

  • R2305:När det består av WS-Secure Conversation måste ett CreateSequence meddelande innehålla elementet wsse:SecurityTokenReference .

WS-Reliable Messaging WS-Policy Assertion

WCF använder WS-Reliable Messaging WS-Policy Assertion wsrm:RMAssertion för att beskriva slutpunktsfunktioner. Följande är en lista över begränsningar som gäller för WCF:

  • B3001: WCF kopplar wsrm:RMAssertion WS-Policy Assertion till wsdl:binding element. WCF stöder både bifogade filer till wsdl:binding och wsdl:port element.

  • B3002: WCF stöder följande valfria egenskaper för WS-Reliable Messaging-försäkran och ger kontroll över dem på WCFReliableMessagingBindingElement:

    • wsrm:InactivityTimeout

    • wsrm:AcknowledgementInterval

    Följande är ett exempel.

    <wsrm:RMAssertion>
      <wsrm:InactivityTimeout Milliseconds="600000" />
      <wsrm:AcknowledgementInterval Milliseconds="200" />
    </wsrm:RMAssertion>
    

Flow Control WS-Reliable Messaging Extension

WCF använder utökningsbarhet för WS-Reliable Messaging för att ge ytterligare kontroll över sekvensmeddelandeflödet ytterligare.

Flödeskontroll aktiveras genom att ställa in egenskapen på ReliableSessionBindingElement.FlowControlEnabledtrue. Följande är en lista över begränsningar som gäller för WCF:

  • B4001: När Reliable Messaging Flow Control är aktiverat genererar WCF ett netrm:BufferRemaining element i elementets utökningsbarhet för SequenceAcknowledgement huvudet.

  • B4002: När Reliable Messaging Flow Control är aktiverat kräver WCF inte att ett netrm:BufferRemaining element finns i SequenceAcknowledgement huvudet, som du ser i följande exempel.

    <wsrm:SequenceAcknowledgement>
      <wsrm:Identifier>
        http://fabrikam123.com/abc
      </wsrm:Identifier>
      <wsrm:AcknowledgementRange Upper="1" Lower="1"/>
      <netrm:BufferRemaining>
        8
      </netrm:BufferRemaining>
    </wsrm:SequenceAcknowledgement>
    
  • B4003: WCF använder netrm:BufferRemaining för att ange hur många nya meddelanden som reliable messaging-målet kan buffa.

  • B4004:WCF Reliable Messaging Service begränsar antalet meddelanden som överförs när målprogrammet Reliable Messaging inte kan ta emot meddelanden snabbt. Reliable Messaging-målet buffrar meddelanden och elementets värde sjunker till 0.

  • B4005: WCF genererar heltalsvärden netrm:BufferRemaining mellan 0 och 4096 och läser heltalsvärden mellan 0 och xs:int's maxInclusive värde 214748364 inklusive.

Exchange-mönster för meddelanden

I det här avsnittet beskrivs WCF:s beteende när WS-Reliable Messaging används för olika Exchange-mönster för meddelanden. Följande två distributionsscenarier beaktas för varje Meddelandeutbytesmönster:

  • Initiator som inte kan adresseras: Initieraren finns bakom brandväggen. Svararen kan endast leverera meddelanden till initieraren på HTTP-svar.

  • Adresserbar initierare: Initieraren och svararen kan båda skickas HTTP-begäranden. Med andra ord kan två omvända HTTP-anslutningar upprättas.

Enkelriktad, icke-adresserbar initierare

Bindning

WCF tillhandahåller ett enkelriktad meddelandeutbytesmönster med en sekvens över en HTTP-kanal. WCF använder HTTP-begäranden för att överföra alla meddelanden från RMS till RMD och HTTP-svaret för att överföra alla meddelanden från RMD till RMS.

CreateSequence Exchange

WCF-initieraren genererar ett CreateSequence meddelande utan erbjudande. WCF-svararen ser till att CreateSequence det inte finns något erbjudande innan du skapar en sekvens. WCF-svararen svarar på CreateSequence begäran med ett CreateSequenceResponse meddelande.

SequenceAcknowledgement

WCF-initieraren bearbetar bekräftelser på svaret för alla meddelanden förutom CreateSequence meddelandet och felmeddelandena. WCF-svararen genererar alltid en fristående bekräftelse i svaret på både sekvens och AckRequested meddelanden.

TerminateSequence-meddelande

WCF behandlas TerminateSequence som en enkelriktad åtgärd, vilket innebär att HTTP-svaret har en tom brödtext och HTTP 202-statuskod.

One Way, adresserbar initierare

Bindning

WCF tillhandahåller ett enkelriktad meddelandeutbytesmönster med hjälp av en sekvens över en inkommande och en utgående Http-kanal. WCF använder HTTP-begäranden för att överföra alla meddelanden. Alla HTTP-svar har en tom brödtext och HTTP 202-statuskod.

CreateSequence Exchange

WCF-initieraren genererar ett CreateSequence meddelande utan erbjudande. WCF-svararen CreateSequence ser till att inte har något erbjudande innan du skapar en sekvens. WCF-svararen CreateSequenceResponse skickar meddelandet på en HTTP-begäran som adresserats med slutpunktsreferensen ReplyTo .

Duplex, Adresserbar initierare

Bindning

WCF tillhandahåller ett helt asynkront dubbelriktade meddelandeutbytesmönster med två sekvenser över en inkommande och en utgående HTTP-kanal. WCF använder HTTP-begäranden för att överföra alla meddelanden. Alla HTTP-svar har en tom brödtext och HTTP 202-statuskod.

CreateSequence Exchange

WCF-initieraren genererar ett CreateSequence meddelande med ett erbjudande. WCF-svararen CreateSequence ser till att har ett erbjudande innan du skapar en sekvens. WCF skickar CreateSequenceResponse http-begäran som är adresserad till slutpunktsreferensenCreateSequenceReplyTo.

Sekvenslivslängd

WCF behandlar de två sekvenserna som en helt dubbelsidig session.

När ett fel genereras som felar en sekvens förväntar sig WCF att fjärrslutpunkten ska fela båda sekvenserna. Vid läsning av ett fel som felar en sekvens felar WCF båda sekvenserna.

WCF kan stänga sin utgående sekvens och fortsätta bearbeta meddelanden på den inkommande sekvensen. Omvänt kan WCF bearbeta stängningen av den inkommande sekvensen och fortsätta att skicka meddelanden på dess utgående sekvens.

Begärandesvar, icke-adresserbar initierare

Bindning

WCF tillhandahåller ett utbytesmönster för enkelriktade och begärandesvarsmeddelanden med två sekvenser över en HTTP-kanal. WCF använder HTTP-begäranden för att överföra begärandesekvensens meddelanden och använder HTTP-svaren för att överföra svarssekvensens meddelanden.

CreateSequence Exchange

WCF-initieraren genererar ett CreateSequence meddelande med ett erbjudande. WCF-svararen CreateSequence ser till att har ett erbjudande innan du skapar en sekvens. WCF-svararen svarar på CreateSequence begäran med ett CreateSequenceResponse meddelande.

Enkelriktade meddelanden

För att slutföra ett enkelriktad meddelandeutbytesprotokoll skickar WCF-initieraren ett meddelande om begärandesekvens på HTTP-begäran och tar emot ett fristående SequenceAcknowledgement meddelande om HTTP-svaret. Måste SequenceAcknowledgement bekräfta meddelandet som skickas.

WCF-svararen kan svara på begäran med en bekräftelse, ett fel eller ett svar med en tom brödtext och HTTP 202-statuskod.

Tvåvägsmeddelanden

För att slutföra ett exchange-protokoll för tvåvägsmeddelanden skickar WCF-initieraren ett meddelande om begärandesekvens på HTTP-begäran och tar emot ett svarssekvensmeddelande om HTTP-svaret. Svaret måste innehålla ett SequenceAcknowledgement bekräftelsemeddelande om att begärandesekvensmeddelandet har överförts.

WCF-svararen kan svara på begäran med ett programsvar, ett fel eller ett svar med en tom brödtext och HTTP 202-statuskod.

På grund av förekomsten av enkelriktade meddelanden och tidpunkten för programsvar har sekvensnumret för begärandesekvensmeddelandet och svarsmeddelandets sekvensnummer ingen korrelation.

Försök svara igen

WCF förlitar sig på http-begäran-svar korrelation för tvåvägs meddelande exchange protokoll korrelation. På grund av detta slutar WCF-initieraren inte att försöka igen med ett sekvensmeddelande för begäran när begärandesekvensmeddelandet bekräftas, utan i stället när HTTP-svaret bär ett bekräftelse-, användarmeddelande eller fel. WCF-svararen försöker svara på HTTP-begärandeben för den begäran som svaret korreleras till.

LastMessage Exchange

WCF-initieraren genererar och överför ett tomt kroppsligt sista meddelande på HTTP-begärandeben. WCF kräver ett svar men ignorerar det faktiska svarsmeddelandet. WCF-svararen svarar på begärandesekvensens tomma sista meddelande med svarssekvensens tomma sista meddelande.

Om WCF-svararen får ett sista meddelande där åtgärdens URI inte http://schemas.xmlsoap.org/ws/2005/02/rm/LastMessageär svarar WCF med ett sista meddelande. När det gäller ett dubbelriktad meddelandeutbytesprotokoll bär det sista meddelandet programmeddelandet. När det gäller ett protokoll för envägsmeddelandeutbyte är det sista meddelandet tomt.

WCF-svararen kräver ingen bekräftelse för svarssekvensens tomma sista meddelande.

TerminateSequence Exchange

När alla begäranden har fått ett giltigt svar genererar och överför WCF-initieraren begärandesekvensens TerminateSequence meddelande på HTTP-begärandeben. WCF kräver ett svar men ignorerar det faktiska svarsmeddelandet. WCF-svararen svarar på begärandesekvensens TerminateSequence meddelande med svarssekvensens TerminateSequence meddelande.

I en normal avstängningssekvens har båda TerminateSequence meddelandena ett fullständigt intervall SequenceAcknowledgement.

Begäran/svar, adresserbar initierare

Bindning

WCF tillhandahåller ett exchange-mönster för begäran-svar-meddelanden med två sekvenser över en inkommande och en utgående HTTP-kanal. WCF använder HTTP-begäranden för att överföra alla meddelanden. Alla HTTP-svar har en tom brödtext och HTTP 202-statuskod.

CreateSequence Exchange

WCF-initieraren genererar ett CreateSequence meddelande med ett erbjudande. WCF-svararen CreateSequence ser till att har ett erbjudande innan du skapar en sekvens. WCF skickar CreateSequenceResponse http-begäran som är adresserad till slutpunktsreferensenCreateSequenceReplyTo.

Korrelation mellan begäran och svar

WCF-initieraren ser till att alla programbegärandemeddelanden har en MessageId slutpunktsreferens och en ReplyTo slutpunktsreferens. WCF-initieraren tillämpar CreateSequence meddelandets slutpunktsreferens ReplyTo på varje programbegärandemeddelande. WCF-svararen kräver att inkommande begärandemeddelanden har en MessageId och en ReplyTo. WCF-svararen ser till att slutpunktsreferensens URI för både CreateSequence och alla programbegärandemeddelanden är identiska.