2

NetTcpBindingを使用して、クライアントとサーバー間で二重通信チャネルを開くことに向けて、ゆっくりと着実に進歩しています。(参考までに、ここここで私の初心者の進歩を観察することができます!)

これで、サーバーのファイアウォールを介してサーバーに正常に接続できる段階になり、クライアントはサーバーに要求を行うことができます。

しかし、逆の方向では、物事はそれほど幸せではありません。自分のマシンでテストする場合は正常に機能しますが、インターネット経由でテストする場合、サーバー側からコールバックを開始しようとすると、エラーが発生します。

The message with Action 'http://MyWebService/IWebService/HelloWorld' cannot be
processed at the receiver, 
due to a ContractFilter mismatch at the EndpointDispatcher. 
This may be because of either a contract mismatch (mismatched Actions between 
sender and receiver) 
or a binding/security mismatch between the sender and the receiver.  
Check that sender and receiver have the same contract and the same binding 
(including security requirements, e.g. Message, Transport, None).

ここにコードの重要な部分のいくつかがあります。まず、Webインターフェイス:

[ServiceContract(Namespace = "http://MyWebService", SessionMode = SessionMode.Required, CallbackContract = typeof(ISiteServiceExternal))]
public interface IWebService {
  [OperationContract]
  void Register(long customerID);
}

public interface ISiteServiceExternal {
  [OperationContract]
  string HelloWorld();
}

IWebServiceの実装は次のとおりです。

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
class WebService : IWebService {
  void IWebService.Register(long customerID) {
    Console.WriteLine("customer {0} registering", customerID);
    var callbackService = OperationContext.Current.GetCallbackChannel<ISiteServiceExternal>();
    RegisterClient(customerID, callbackService);
    Console.WriteLine("customer {0} registered", customerID);
  }
}

次に、クライアント側で(私が何をしているのかを実際に知らずに、これらの属性をいじっていました):

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, Namespace="http://MyWebService")]
class SiteServer : IWebServiceCallback {
  string IWebServiceCallback.HelloWorld() {
return "Hello World!";
  }
  ...
}

それで、私はここで何を間違っているのですか?

編集: app.configコードを追加します。サーバーから:

<system.serviceModel>
  <diagnostics>
    <messageLogging logMalformedMessages="true" logMessagesAtServiceLevel="true"
        logMessagesAtTransportLevel="true" logEntireMessage="true" maxMessagesToLog="1000" maxSizeOfMessageToLog="524288" />
  </diagnostics>
  <behaviors>
    <serviceBehaviors>
      <behavior name="mex">
        <serviceDebug includeExceptionDetailInFaults="true"/>
        <serviceMetadata/>
      </behavior>
    </serviceBehaviors>
  </behaviors>
  <services>
    <service name ="MyWebService.WebService" behaviorConfiguration="mex">
      <endpoint address="net.tcp://localhost:8000" binding="netTcpBinding" contract="MyWebService.IWebService"
                bindingConfiguration="TestBinding" name="MyEndPoint"></endpoint>
      <endpoint address ="mex"
                binding="mexTcpBinding"
                name="MEX"
                contract="IMetadataExchange"/>
      <host>
        <baseAddresses>
          <add baseAddress="net.tcp://localhost:8000"/>
        </baseAddresses>
      </host>
    </service>
  </services>
  <bindings>
    <netTcpBinding>
      <binding name="TestBinding" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" portSharingEnabled="false">
        <readerQuotas maxDepth="32" maxStringContentLength ="8192" maxArrayLength ="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
        <security mode="None"/>
      </binding>
    </netTcpBinding>
  </bindings>
</system.serviceModel>

およびクライアント側:

<system.serviceModel>
  <bindings>
    <netTcpBinding>
      <binding name="MyEndPoint" closeTimeout="00:01:00" openTimeout="00:01:00"
          receiveTimeout="00:10:00" sendTimeout="00:01:00" transactionFlow="false"
          transferMode="Buffered" transactionProtocol="OleTransactions"
          hostNameComparisonMode="StrongWildcard" listenBacklog="10"
          maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10"
          maxReceivedMessageSize="65536">
        <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
            maxBytesPerRead="4096" maxNameTableCharCount="16384" />
        <reliableSession ordered="true" inactivityTimeout="00:10:00"
            enabled="false" />
        <security mode="None">
          <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign">
            <extendedProtectionPolicy policyEnforcement="Never" />
          </transport>
          <message clientCredentialType="Windows" />
        </security>
      </binding>
    </netTcpBinding>
  </bindings>
  <client>
    <endpoint address="net.tcp://mydomain.gotdns.com:8000/" binding="netTcpBinding"
        bindingConfiguration="MyEndPoint" contract="IWebService" name="MyEndPoint" />
  </client>
</system.serviceModel>
4

2 に答える 2

3

何が悪かったのか気付くのを手伝ってくれた@AllonGuralnekに敬意を表します。

サーバー側では:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
class WebService : IWebService { ... }

そして、クライアント側では:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, Namespace="http://MyWebService")]
class SiteServer : IWebServiceCallback { ... }

競合はとの間PerCallでしPerSessionた。サーバーサイドをに変更しましたPerSession。-ヒューストン、リフトオフがあります。

さて、これをセキュリティで機能させるために...私のWCF学習曲線の次のエキサイティングな記事をSOで見てください!:)

于 2010-12-27T09:11:57.733 に答える
0

コールバックコントラクトをとしてリストしましISiteServiceExternalたが、クライアントはを実装していますIWebServiceCallback。最初にそれを修正して、成功するかどうかを確認してください。

于 2010-12-26T19:09:30.190 に答える