Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Przykład transportu współoperacyjnego TCP w WSE 3.0 demonstruje, jak zaimplementować sesję dwukierunkową TCP jako niestandardowy transport w Windows Communication Foundation (WCF). Pokazuje również, jak można wykorzystać rozszerzalność warstwy kanału do interfejsowania przez przewód z istniejącymi wdrożonymi systemami. W poniższych krokach pokazano, jak utworzyć ten niestandardowy transport WCF:
Począwszy od gniazda TCP, utwórz implementacje IDuplexSessionChannel klienta i serwera, które używają framingu DIME, aby oddzielić granice komunikatów.
Utwórz fabrykę kanałów, która łączy się z usługą TCP WSE i wysyła komunikaty framowane za pośrednictwem klientów IDuplexSessionChannel.
Utwórz odbiornik kanału w celu akceptowania przychodzących połączeń TCP i tworzenia odpowiednich kanałów.
Upewnij się, że wszystkie wyjątki specyficzne dla sieci są znormalizowane do odpowiedniej klasy pochodnej klasy CommunicationException.
Dodaj element powiązania, który dodaje niestandardowy transport do stosu kanału. Aby uzyskać więcej informacji, zobacz [Dodawanie elementu powiązania].
Tworzenie IDuplexSessionChannel
Pierwszym krokiem w procesie tworzenia WSE 3.0 TCP Interoperability Transport jest utworzenie implementacji IDuplexSessionChannel na Socket.
WseTcpDuplexSessionChannel
pochodzi od ChannelBase. Logika wysyłania komunikatu składa się z dwóch głównych elementów: (1) kodowania komunikatu w bajtach i (2) ramowania tych bajtów i ich transmisji siecią.
ArraySegment<byte> encodedBytes = EncodeMessage(message);
WriteData(encodedBytes);
Ponadto zakładana jest blokada, aby wywołania Send() utrzymały gwarancję IDuplexSessionChannel dotyczącą kolejności oraz aby wywołania do bazowego gniazda były prawidłowo zsynchronizowane.
WseTcpDuplexSessionChannel
używa elementu MessageEncoder do tłumaczenia elementu Message do i z bajtu[]. Ponieważ jest to transport, WseTcpDuplexSessionChannel
jest również odpowiedzialny za zastosowanie zdalnego adresu, którym skonfigurowano kanał.
EncodeMessage
zawiera logikę konwersji.
this.RemoteAddress.ApplyTo(message);
return encoder.WriteMessage(message, maxBufferSize, bufferManager);
Po zakodowaniu Message w bajtach należy go przekazać w przewodzie. Wymaga to systemu do definiowania granic komunikatów. WSE 3.0 używa wersji DIME jako protokołu framingu.
WriteData
Hermetyzuje logikę tworzenia ramek w celu zawijania bajtu[] do zestawu rekordów DIME.
Logika odbierania komunikatów jest podobna. Główną złożonością jest obsługa faktu, że odczyt gniazda może zwrócić mniej bajtów niż zażądano. Aby odebrać komunikat, WseTcpDuplexSessionChannel
odczytuje bajty z przewodu, dekoduje ramkę DIME, a następnie używa MessageEncoder elementu do przekształcania bajtu[] w Message.
W bazie WseTcpDuplexSessionChannel
przyjęto założenie, że otrzymuje połączone gniazdo. Klasa bazowa obsługuje zamykanie gniazd. Istnieją trzy miejsca, które interagują z procesem zamknięcia gniazda.
OnAbort - zamknij gniazdo niegrzecznie (twarde zamknięcie).
Na[Początek]Zamknij - zamknij gniazdo bezpiecznie (miękkie zamknięcie).
sesja.CloseOutputSession — zamknij strumień danych wychodzących (częściowe zamknięcie).
Fabryka kanałów
Następnym krokiem podczas pisania transportu TCP jest utworzenie implementacji IChannelFactory dla kanałów klienckich.
-
WseTcpChannelFactory
pochodzi z ChannelFactoryBase<IDuplexSessionChannel>. Jest to fabryka, która zastępujeOnCreateChannel
tworzenie kanałów klienckich.
protected override IDuplexSessionChannel OnCreateChannel(EndpointAddress remoteAddress, Uri via)
{
return new ClientWseTcpDuplexSessionChannel(encoderFactory, bufferManager, remoteAddress, via, this);
}
-
ClientWseTcpDuplexSessionChannel
dodaje logikę do bazyWseTcpDuplexSessionChannel
w celu nawiązania połączenia z serwerem TCP wchannel.Open
czasie. Najpierw nazwa hosta jest rozpoznawana jako adres IP, jak pokazano w poniższym kodzie.
hostEntry = Dns.GetHostEntry(Via.Host);
- Następnie nazwa hosta jest połączona z pierwszym dostępnym adresem IP w pętli, jak pokazano w poniższym kodzie.
IPAddress address = hostEntry.AddressList[i];
socket = new Socket(address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
socket.Connect(new IPEndPoint(address, port));
- W ramach umowy dotyczącej kanału, wszystkie wyjątki specyficzne dla domeny są opakowane, takie jak
SocketException
w CommunicationException.
Odbiornik kanału
Następnym krokiem podczas pisania transportu TCP jest utworzenie implementacji akceptowania IChannelListener kanałów serwera.
-
WseTcpChannelListener
pochodzi z ChannelListenerBase<IDuplexSessionChannel> i zastępuje on[Begin]Open i On[Begin]Close, aby kontrolować okres istnienia gniazda nasłuchiwania. W funkcji OnOpen jest tworzone gniazdo do nasłuchiwania na IP_ANY. Bardziej zaawansowane implementacje mogą również utworzyć drugie gniazdo do nasłuchiwania przy użyciu protokołu IPv6. Mogą również zezwalać na określenie adresu IP w nazwie hosta.
IPEndPoint localEndpoint = new IPEndPoint(IPAddress.Any, uri.Port);
this.listenSocket = new Socket(localEndpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
this.listenSocket.Bind(localEndpoint);
this.listenSocket.Listen(10);
Po zaakceptowaniu nowego gniazda kanał serwera jest inicjowany za pomocą tego gniazda. Wszystkie dane wejściowe i wyjściowe są już implementowane w klasie bazowej, więc ten kanał jest odpowiedzialny za inicjowanie gniazda.
Dodawanie elementu powiązania
Teraz, gdy fabryki i kanały zostały zbudowane, muszą być udostępnione w środowisku uruchomieniowym ServiceModel za pomocą powiązania. Powiązanie to kolekcja elementów powiązania, które reprezentują stos komunikacji skojarzony z adresem usługi. Każdy element w stosie jest reprezentowany przez element powiązania.
W przykładzie element powiązania to WseTcpTransportBindingElement
, który pochodzi z elementu TransportBindingElement. Obsługuje IDuplexSessionChannel i zastępuje następujące metody, aby tworzyć fabryki związane z naszym wiązaniem.
public IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingContext context)
{
return (IChannelFactory<TChannel>)(object)new WseTcpChannelFactory(this, context);
}
public IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context)
{
return (IChannelListener<TChannel>)(object)new WseTcpChannelListener(this, context);
}
Zawiera również elementy członkowskie do klonowania BindingElement
i zwracania naszego schematu (wse.tcp).
Konsola testowa PROTOKOŁU TCP programu WSE
Kod testowy do korzystania z tego przykładowego transportu jest dostępny w TestCode.cs. Poniższe instrukcje pokazują, jak przygotować przykładową konfigurację WSE TcpSyncStockService
.
Kod testowy tworzy niestandardowe powiązanie, które używa MTOM jako kodowania oraz WseTcpTransport
jako transportu. Konfiguruje również wersję AddressingVersion zgodnie z WSE 3.0, jak pokazano w poniższym kodzie.
CustomBinding binding = new CustomBinding();
MtomMessageEncodingBindingElement mtomBindingElement = new MtomMessageEncodingBindingElement();
mtomBindingElement.MessageVersion = MessageVersion.Soap11WSAddressingAugust2004;
binding.Elements.Add(mtomBindingElement);
binding.Elements.Add(new WseTcpTransportBindingElement());
Składa się z dwóch testów — jeden test konfiguruje typizowanego klienta przy użyciu kodu wygenerowanego na podstawie WSDL programu WSE 3.0. Drugi test używa WCF zarówno jako klienta, jak i serwera, wysyłając komunikaty bezpośrednio nad interfejsami API kanału.
Podczas uruchamiania przykładu oczekiwane są następujące dane wyjściowe.
Klient:
Calling soap://stockservice.contoso.com/wse/samples/2003/06/TcpSyncStockService
Symbol: FABRIKAM
Name: Fabrikam, Inc.
Last Price: 120
Symbol: CONTOSO
Name: Contoso Corp.
Last Price: 50.07
Press enter.
Received Action: http://SayHello
Received Body: to you.
Hello to you.
Press enter.
Received Action: http://NotHello
Received Body: to me.
Press enter.
Serwer:
Listening for messages at soap://stockservice.contoso.com/wse/samples/2003/06/TcpSyncStockService
Press any key to exit when done...
Request received.
Symbols:
FABRIKAM
CONTOSO
Konfigurowanie, kompilowanie i uruchamianie przykładu
- Aby uruchomić ten przykład, musisz mieć zainstalowane ulepszenia usług sieci Web (WSE) 3.0 dla platformy Microsoft .NET i przykład programu WSE
TcpSyncStockService
.
Uwaga / Notatka
Ponieważ program WSE 3.0 nie jest obsługiwany w systemie Windows Server 2008, nie można zainstalować ani uruchomić przykładu TcpSyncStockService
w tym systemie operacyjnym.
Po zainstalowaniu przykładu
TcpSyncStockService
wykonaj następujące czynności:Otwórz
TcpSyncStockService
w programie Visual Studio. ( Przykład TcpSyncStockService jest instalowany z programem WSE 3.0. Nie jest częścią kodu tego przykładu).Ustaw projekt StockService jako projekt startowy.
Otwórz StockService.cs w projekcie StockService i oznacz jako komentarz atrybut [Policy] w
StockService
klasie. Spowoduje to wyłączenie zabezpieczeń z przykładu. Chociaż program WCF może współpracować z bezpiecznymi punktami końcowymi programu WSE 3.0, zabezpieczenia są wyłączone, aby zachować ten przykład skoncentrowany na niestandardowym transporcie TCP.naciśnij F5, aby uruchomić
TcpSyncStockService
. Usługa jest uruchamiana w nowym oknie konsoli.Otwórz ten przykład transportu TCP w programie Visual Studio.
Zaktualizuj zmienną "hostname" w TestCode.cs, aby odpowiadała nazwie komputera uruchamiającego
TcpSyncStockService
.naciśnij F5 , aby uruchomić przykład transportu TCP.
Klient testowy transportu TCP jest uruchamiany w nowej konsoli. Klient żąda ofert giełdowych z usługi, a następnie wyświetla wyniki w oknie konsoli.