Vorgehensweise: Erstellen eines WCF-Diensts, der über WebSockets kommuniziertHow to: Create a WCF Service that Communicates over WebSockets

WCF-Dienste und -Clients können die NetHttpBinding-Bindung verwenden, um über WebSockets zu kommunizieren.WCF services and clients can use the NetHttpBinding binding to communicate over WebSockets. WebSockets werden verwendet, wenn die NetHttpBinding bestimmt, dass der Dienstvertrag einen Rückrufvertrag definiert.WebSockets will be used when the NetHttpBinding determines the service contract defines a callback contract. In diesem Thema wird das Implementieren eines WCF-Diensts und -Clients beschrieben, die mithilfe der NetHttpBinding über WebSockets kommunizieren.This topic describes how to implement a WCF service and client that uses the NetHttpBinding to communicate over WebSockets.

Definieren des DienstsDefine the Service

  1. Definieren Sie einen Rückrufvertrag.Define a callback contract

    [ServiceContract]  
        public interface IStockQuoteCallback  
        {  
            [OperationContract(IsOneWay = true)]  
            Task SendQuote(string code, double value);  
        }  
    

    Dieser Vertrag wird von der Clientanwendung implementiert, damit der Dienst Nachrichten zurück an den Client senden kann.This contract will be implemented by the client application to allow the service to send messages back to the client.

  2. Definieren Sie den Dienstvertrag, und geben Sie die IStockQuoteCallback-Schnittstelle als Rückrufvertrag an.Define the service contract and specify the IStockQuoteCallback interface as the callback contract.

    [ServiceContract(CallbackContract = typeof(IStockQuoteCallback))]  
        public interface IStockQuoteService  
        {  
            [OperationContract(IsOneWay = true)]  
            Task StartSendingQuotes();  
        }  
    
  3. Implementieren Sie den Dienstvertrag.Implement the service contract.

    public class StockQuoteService : IStockQuoteService  
        {  
            public async Task StartSendingQuotes()  
            {  
                var callback = OperationContext.Current.GetCallbackChannel<IStockQuoteCallback>();  
                var random = new Random();  
                double price = 29.00;  
    
                while (((IChannel)callback).State == CommunicationState.Opened)  
                {  
                    await callback.SendQuote("MSFT", price);  
                    price += random.NextDouble();  
                    await Task.Delay(1000);  
                }  
            }  
        }  
    

    Der Dienstvorgang StartSendingQuotes wird als asynchroner Aufruf implementiert.The service operation StartSendingQuotes is implemented as an asynchronous call. Der Rückrufkanal wird mithilfe des OperationContext abgerufen, und wenn der Kanal geöffnet ist, wird ein asynchroner Aufruf des Rückrufkanals ausgeführt.We retrieve the callback channel using the OperationContext and if the channel is open, we make an async call on the callback channel.

  4. Konfigurieren Sie den Dienst.Configure the service

    <configuration>  
        <appSettings>  
          <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />        
        </appSettings>  
        <system.web>  
          <compilation debug="true" targetFramework="4.5" />        
        </system.web>  
        <system.serviceModel>  
            <protocolMapping>  
              <add scheme="http" binding="netHttpBinding"/>  
              <add scheme="https" binding="netHttpsBinding"/>  
            </protocolMapping>  
            <behaviors>  
                <serviceBehaviors>  
                    <behavior name="">  
                        <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />  
                        <serviceDebug includeExceptionDetailInFaults="false" />  
                    </behavior>  
                </serviceBehaviors>  
            </behaviors>  
            <serviceHostingEnvironment aspNetCompatibilityEnabled="true"  
                multipleSiteBindingsEnabled="true" />  
        </system.serviceModel>  
    </configuration>  
    

    Die Konfigurationsdatei des Diensts basiert auf WCF-Standardendpunkten.The service’s configuration file relies on WCF’s default endpoints. Mit dem <protocolMapping>-Abschnitt wird angegeben, dass für die erstellten Standardendpunkte die NetHttpBinding verwendet werden soll.The <protocolMapping> section is used to specify that the NetHttpBinding should be used for the default endpoints created.

Definieren des ClientsDefine the Client

  1. Implementieren Sie den Rückrufvertrag.Implement the callback contract.

    private class CallbackHandler : StockQuoteServiceReference.IStockQuoteServiceCallback  
            {  
                public async Task SendQuoteAsync(string code, double value)  
                {  
                    Console.WriteLine("{0}: {1:f2}", code, value);  
                }  
            }  
    

    Der Rückrufvertragsvorgang wird als asynchrone Methode implementiert.The callback contract operation is implemented as an asynchronous method.

    1. Implementieren Sie den Clientcode.Implement the client code.

      class Program  
      {  
          static void Main(string[] args)  
          {  
              var context = new InstanceContext(new CallbackHandler());  
              var client = new StockQuoteServiceReference.StockQuoteServiceClient(context);  
              client.StartSendingQuotes();              
              Console.ReadLine();  
          }  
      
          private class CallbackHandler : StockQuoteServiceReference.IStockQuoteServiceCallback  
          {  
              public async Task SendQuoteAsync(string code, double value)  
              {  
                  Console.WriteLine("{0}: {1:f2}", code, value);  
              }  
          }  
      }  
      

      Der CallbackHandler wird hier aus Gründen der Übersichtlichkeit wiederholt.The CallbackHandler is repeated here for clarity. Die Clientanwendung erstellt einen neuen InstanceContext und gibt die Implementierung der Rückrufschnittstelle an.The client application creates a new InstanceContext and specifies the implementation of the callback interface. Danach erstellt sie eine Instanz der Proxyklasse, die einen Verweis an den neu erstellten InstanceContext sendet.Next it creates an instance of the proxy class sending a reference to the newly created InstanceContext. Wenn der Client den Dienst aufruft, ruft der Dienst den Client mithilfe des angegebenen Rückrufvertrags auf.When the client calls the service, the service will call the client using the callback contract specified.

    2. Konfigurieren Sie den Client.Configure the client

      <?xml version="1.0" encoding="utf-8" ?>  
      <configuration>  
          <startup>   
              <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />  
          </startup>  
          <system.serviceModel>  
              <bindings>  
                  <netHttpBinding>  
                      <binding name="NetHttpBinding_IStockQuoteService">  
                          <webSocketSettings transportUsage="Always" />  
                      </binding>  
                  </netHttpBinding>  
              </bindings>  
              <client>  
                  <endpoint address="ws://localhost/NetHttpSampleServer/StockQuoteService.svc"  
                      binding="netHttpBinding" bindingConfiguration="NetHttpBinding_IStockQuoteService"  
                      contract="StockQuoteServiceReference.IStockQuoteService" name="NetHttpBinding_IStockQuoteService" />  
              </client>  
          </system.serviceModel>  
      </configuration>  
      

      In der Clientkonfiguration sind keine besonderen Schritte erforderlich. Sie geben einfach den clientseitigen Endpunkt mithilfe der NetHttpBinding an.There is nothing special you need to do in the client configuration, just specify the client side endpoint using the NetHttpBinding.

BeispielExample

In Folgenden finden Sie den vollständigen Code, der in diesem Thema verwendet wird.The following is the complete code used in this topic.

// IStockQuoteService.cs  
using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Runtime.Serialization;  
using System.ServiceModel;  
using System.Text;  
using System.Threading.Tasks;  

namespace Server  
{  
    [ServiceContract(CallbackContract = typeof(IStockQuoteCallback))]  
    public interface IStockQuoteService  
    {  
        [OperationContract(IsOneWay = true)]  
        Task StartSendingQuotes();  
    }  

    [ServiceContract]  
    public interface IStockQuoteCallback  
    {  
        [OperationContract(IsOneWay = true)]  
        Task SendQuote(string code, double value);  
    }  
}  
// StockQuoteService.svc.cs  
using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Runtime.Serialization;  
using System.ServiceModel;  
using System.ServiceModel.Channels;  
using System.Text;  
using System.Threading.Tasks;  

namespace Server  
{  
    public class StockQuoteService : IStockQuoteService  
    {  
        public async Task StartSendingQuotes()  
        {  
            var callback = OperationContext.Current.GetCallbackChannel<IStockQuoteCallback>();  
            var random = new Random();  
            double price = 29.00;  

            while (((IChannel)callback).State == CommunicationState.Opened)  
            {  
                await callback.SendQuote("MSFT", price);  
                price += random.NextDouble();  
                await Task.Delay(1000);  
            }  
        }  
    }  
}  
<?xml version="1.0"?>  

<!--  
  For more information on how to configure your ASP.NET application, please visit  
  http://go.microsoft.com/fwlink/?LinkId=169433  
  -->  

<configuration>  
    <appSettings>  
      <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />        
    </appSettings>  
    <system.web>  
      <compilation debug="true" targetFramework="4.5" />        
    </system.web>  
    <system.serviceModel>  
        <protocolMapping>  
          <add scheme="http" binding="netHttpBinding"/>  
          <add scheme="https" binding="netHttpsBinding"/>  
        </protocolMapping>  
        <behaviors>  
            <serviceBehaviors>  
                <behavior name="">  
                    <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />  
                    <serviceDebug includeExceptionDetailInFaults="false" />  
                </behavior>  
            </serviceBehaviors>  
        </behaviors>  
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true"  
            multipleSiteBindingsEnabled="true" />  
    </system.serviceModel>  
</configuration>  
<!-- StockQuoteService.svc -->  
<%@ ServiceHost Language="C#" Debug="true" Service="Server.StockQuoteService" CodeBehind="StockQuoteService.svc.cs" %>  
// Client.cs  
using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.ServiceModel;  
using System.Text;  
using System.Threading.Tasks;  

namespace Client  
{  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            var context = new InstanceContext(new CallbackHandler());  
            var client = new StockQuoteServiceReference.StockQuoteServiceClient(context);  
            client.StartSendingQuotes();              
            Console.ReadLine();  
        }  

        private class CallbackHandler : StockQuoteServiceReference.IStockQuoteServiceCallback  
        {  
            public async Task SendQuoteAsync(string code, double value)  
            {  
                Console.WriteLine("{0}: {1:f2}", code, value);  
            }  
        }  
    }  
}  
<!—App.config -->  
<?xml version="1.0" encoding="utf-8" ?>  
<configuration>  
    <startup>   
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />  
    </startup>  
    <system.serviceModel>  
        <bindings>  
            <netHttpBinding>  
                <binding name="NetHttpBinding_IStockQuoteService">  
                    <webSocketSettings transportUsage="Always" />  
                </binding>  
            </netHttpBinding>  
        </bindings>  
        <client>  
            <endpoint address="ws://localhost/NetHttpSampleServer/StockQuoteService.svc"  
                binding="netHttpBinding" bindingConfiguration="NetHttpBinding_IStockQuoteService"  
                contract="StockQuoteServiceReference.IStockQuoteService" name="NetHttpBinding_IStockQuoteService" />  
        </client>  
    </system.serviceModel>  
</configuration>  

Siehe auchSee Also

Synchrone und asynchrone VorgängeSynchronous and Asynchronous Operations
Verwenden von NetHttpBindingUsing the NetHttpBinding