web-dev-qa-db-ja.com

WCFのセットアップTCP Webアプリケーションでのサービス

私はこれと何日も戦い続けており、WCF TCPベースのサービスをWebアプリケーションにセットアップする方法に関する部分的なガイドラインを提供する100の記事を通り抜けています。誰かが私を助けることができるなら、私はこの質問を完全なガイドラインにします。

現在の状況

Net.tcp接続は私の開発マシンで動作します。また、Windows Server 2008 R2に展開した後もローカルで動作します。ただし、リモートでサーバーのポート808にTelnet接続することは可能ですが、リモートでは機能しません。詳細については、質問の一番下までスクロールしてください。できれば助けてください。

この詳細について新しい質問を作成し、結果が得られた場合は、この質問を回答で更新します。

コード

次の内容でServerHubService.svcを作成しました。

namespace Manage.SignalR
{
    [ServiceContract]
    public class ServerHubService
    {
        [OperationContract]
        public void UpdateServerStatus(string serverStatus)
        {
            // Do something
        }
    }
}

サービスをホストするアプリケーションの構成

オンラインチュートリアルに従って、Web.configに以下を追加しました(さまざまなバリエーションを多数試しました)。これは、後でTCPで接続するサービスをホストしているWebアプリケーションのWeb.configです。

<configuration>
  <system.serviceModel>
    <services>
      <service behaviorConfiguration="ServerHubBehavior"
      name="Manage.SignalR.ServerHubService">
        <endpoint address=""
              binding="netTcpBinding"
              bindingConfiguration="portSharingBinding"
              name="MyServiceEndpoint"
              contract="Manage.SignalR.ServerHubService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>

        <endpoint address="mex"
              binding="mexTcpBinding"
              bindingConfiguration=""
              name="MyServiceMexTcpBidingEndpoint"
              contract="IMetadataExchange" />
        <Host>
          <baseAddresses>
            <add baseAddress="net.tcp://test.mydomain.com:808/SignalR/ServerHubService.svc" />
          </baseAddresses>
        </Host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServerHubBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <netTcpBinding>
        <binding name="portSharingBinding" portSharingEnabled="true"/>
      </netTcpBinding>
    </bindings>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
      minFreeMemoryPercentageToActivateService="0" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
</configuration>

httpGetEnabled="true"は重要です。それ以外の場合は、サービスへのサービス参照を作成できません。

Webアプリケーションが実行されているサーバーの構成

IIS 7.5を使用している開発マシンでこれをセットアップしています

IIS Express(ビルトインVisual Studioに組み込まれている)はnet.tcpをサポートしていないため、.NETを使用してIIS 7.5に新しいWebサイトをセットアップしました。 4.5、それはnet.tcpバインディングを持っています

bindings in IIS

また、ウェブサイトの[詳細設定]に移動し、[有効なプロトコル]をhttp,net.tcpに設定しました

Windows機能の非HTTPアクティベーションが有効になっている(そして再起動されている)ことを確認しました。これはWindowsの機能なので、「Windowsの機能の有効化または無効化」を探して確認してください。

enter image description here

Webアプリケーションが実行中であることを確認しています

このWebサイトは、残りのWebアプリケーションでは問題なく機能します。 hostsファイルで127.0.0.1を指すようにtest.mydomain.comを設定しました。 http://test.mydomain.com/SignalR/ServerHubService.svc にアクセスすることもでき、このサービスの使用方法を説明する.NETからの自動生成されたニースページが表示されます。

ここまでは順調ですね。

.NETによって生成されたページでは、このアドレスを使用してサービスへの接続を生成するように指示されています。

net.tcp://computername/SignalR/ServerHubService.svc/mex

クライアントとしてサービスに接続しようとしています

httpGetEnabled="true"を設定するのを忘れた場合、それへのサービス参照を作成しようとするとエラーが発生します。 WCFテストクライアント(これもVisual Studioに含まれているツール)を使用し、httpGetEnabledを設定しなかった場合、次のようなエラーが発生します。

エラー:net.tcp://computername/SignalR/ServerHubService.svc/mexからメタデータを取得できません

これがアクセス権のあるWindows(R)Communication Foundationサービスである場合は、指定されたアドレスでメタデータの発行が有効になっていることを確認してください。メタデータの公開を有効にする方法については、MSDNのドキュメント http://go.Microsoft.com/fwlink/?LinkId=65455.WS-Metadata を参照してください。

ExchangeエラーURI:net.tcp://computername/SignalR/ServerHubService.svc/mexメタデータに解決できない参照が含まれています: 'net.tcp://computername/SignalR/ServerHubService.svc/mex'。 net.tcp://computername/SignalR/ServerHubService.svc/mexに接続できませんでした。接続試行は、00:00:04.0032289の期間継続しました。

TCPエラーコード10061:ターゲットマシンがアクティブに拒否したため、接続を確立できませんでした[2001:0:4137:9e76:c81:a4c:a547:b2fd]:808。ターゲットマシンがアクティブに拒否したため、接続を確立できませんでした[2001:0:4137:9e76:c81:a4c:a547:b2fd]:808

ただし、上記のすべてを実行した場合は、サービスへの参照を追加できるはずです。

サービスのメソッドの呼び出し

WCFテストクライアントからサービスの単純なHello Worldメソッドを呼び出そうとすると、次のエラーが返されます。

Net.tcp://computername/SignalR/ServerHubService.svcに接続できませんでした。接続試行は、00:00:04.0002288の期間継続しました。 TCPエラーコード10061:ターゲットマシンがアクティブに拒否したため、接続を確立できませんでした。

これはエラーに含まれている内部スタックトレースです:

ターゲットマシンがアクティブに拒否したため、接続を確立できませんでした[2001:0:5ef5:79fb:3884:a:a547:b2fd]:808 System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot、SocketAddress socketAddress)at System .Net.Sockets.Socket.Connect(EndPoint remoteEP)at System.ServiceModel.Channels.SocketConnectionInitiator.Connect(Uri uri、TimeSpan timeout)

netstat -an |find /i "listening"を使用して、ポート808で何もリッスンしていないことを確認する場合は、おそらくNet.Tcpリスナーアダプターサービスが実行されていないことが原因です。

確認

コールは現在通りますが、成功と宣言する前に確認が必要です。これが実際にポート808でのnet.tcp呼び出しであり、実際にはhttpエンドポイントでの呼び出しではないことを確認する必要があります。私はWiresharkでこれを実行しようとしていますが、おそらくローカルマシンとの間で発生する呼び出しが原因で表示されません。

導入

征服する最後の課題は、これをWebサーバーにデプロイして、開発マシンで機能するものがWebサーバーでも機能するようにすることです。

Windows Server 2008 R2に発行した後は機能しません。共通のSocketException: An existing connection was forcibly closed by the remote Hostを提供します。

サーバーのローカルではうまく機能しますが、リモートでは機能しません。

サーバーのチェックに使用するチェックリストは次のとおりです。

  • Net.Tcp Listener Adapterサービスは実行されていますか?はい
  • IIS net.tcpへのサイトバインドは808:*に設定されていますか?はい
  • IISのサイトの詳細設定で有効なプロトコルがhttp,net.tcpに設定されていますか?はい
  • サーバーはポート808でリッスンしていますか?はい、netstat -an |find /i "listening"で確認しました
  • ファイアウォールでポート808が開いていますか?はい。
    • サーバーでファイアウォールがオフになっています。
    • telnet mydomain.com 808を使用して、外部からポート808でサーバーにTelnetで接続できます
  • サーバー上のサービスの設定で、以下が確認されました:
    • baseAddressはnet.tcp://mydomain.com:808/SignalR/ServerHubService.svcに調整されます
    • これは以前はlocalhostでしたが、サーバーで機能しなくなった後はmydomain.comに変更されました:<identity><dns value="mydomain.com" /></identity>
  • サーバー上および別のサーバー上のクライアントでテストされています。どちらもtelnetでポート808に接続でき、同じエラーメッセージが表示されます。

サーバーでどの構成が欠落している可能性がありますか?私は目標にとても近いです。これのトラブルシューティングを手伝って、質問に答えてください。

次に、サービスを呼び出すサーバーのクライアント構成を示します。

<system.serviceModel>
  <bindings>
    <netTcpBinding>
      <binding name="MyServiceEndpoint" />
    </netTcpBinding>
  </bindings>
  <client>
    <endpoint address="net.tcp://mydomain.com:808/SignalR/ServerHubService.svc"
      binding="netTcpBinding" bindingConfiguration="MyServiceEndpoint"
      contract="ServerHubService.ServerHubService" name="MyServiceEndpoint">
      <identity>
        <dns value="mydomain.com" />
      </identity>
    </endpoint>
  </client>
</system.serviceModel>

また、これがnet.tcp接続のデフォルトポートであると噂されているため、エンドポイントで808を設定せずに試してみました。ただし、それでも同じ結果が得られます。

多くのことをランダムに試すのではなく、良い質問はおそらく次のとおりです。 この呼び出しがブロックされている理由を正確に通知するプログラムをどちらのサーバーにもインストールできますか?

このように設定されたWiresharkを使用すると、ポート808でサーバーに着信する通話を確認し、通話が機能しない理由を特定することができます。しかし、現時点でこれをどのように分析するのか私にはわかりません。

wireshark

がんばって

代わりに、これをあきらめてソケット層に実装しました。それはすぐに働きました。しかし、これが他の誰かの助けになることを願っています。多くの問題が解決され、最終的にはローカルで機能したため、答えを設定します。残っている問題は、おそらく特定の環境に関連しています。

29
Niels Brinch

Tcp用にHTTP経由で公開されたメタデータに基づいてプロキシを生成する必要があります(httpGetEnabledがtrueに設定されていることを確認してください)。クライアントで使用するアドレスは、ホストされているアドレスでなければなりません。下記の投稿を参考にしてください。

http://blogs.msdn.com/b/swiss_dpe_team/archive/2008/02/08/iis-7-support-for-non-http-protocols.aspx

7
Prasath

「test.mydomain.com」に接続したとのことですが、エラーによりサーバーが「computername」に変更されました。それからあなたのコメントであなたはまだ接続に失敗していると述べました。 WSDL/MEXでエイリアスを返す場合は、サービスの動作にuseRequestHeadersForMetadataAddressノードを追加します。このノードのMSDN情報は次のとおりです。 MSDN useRequestHeadersForMetadataAddress node

これはあなたの設定がどのように見えるべきかです。これは、Prasath(httpGetEnabled = "true")からの回答を考慮に入れています。

<serviceBehaviors>
   <behavior name="ServerHubBehavior">
      <serviceMetadata httpGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="false" />
      <useRequestHeadersForMetadataAddress>
         <defaultPorts>
            <add scheme="net.tcp" port="808" />
         </defaultPorts>
      </useRequestHeadersForMetadataAddress>
   </behavior>
</serviceBehaviors>
2
J Man

ローカルマシンのWindowsサービスで(テスト目的で)サービスをホストしようとしましたか?これにより、少なくとも問題がサービス側にあるのか、それともIIS /サーバー構成にあるのかがわかります。

0
mez

今日、asp.net Web API内からnet.tcp wcfサービスを呼び出しているときに、同様の問題が発生しました。他のすべてのマシンからこのサービスが長年にわたって機能しているとは言えませんが、呼び出しはwcfセルフホスティング、wcf iis asp.net互換性ホスティング-> net.tcpサービスセルフホスティングに対して行われました。その後、同じnet.tcpサービスを呼び出す単純なWeb APIを公開したところ、すべてが失敗し、すべての接続が理由もなく中止されました。両側(サービスとクライアント)をトレースする完全なwcfでも役に立たず、同じことを伝えました「接続が中止されました」。

Net.tcpにはトランスポート経由のセキュリティが有効になっており、Windows認証を使用して通信に署名および暗号化されることをすでに知っているので、セキュリティをオフにしようとすると、すべてが正常に機能し始めます。

この方法でセキュリティをオフにしてみてください(クライアントとサービス)。

<security mode="None"/>

完全なサービスバインディング:

<netTcpBinding>

    <binding name="netTcpBinding" portSharingEnabled="true">

        <security mode="None"/>

    </binding>

</netTcpBinding>

これもお役に立てば幸いです。

0
Michael Denny

あなたは Net.TCPポート共有サービスが実行中 をサーバー上に持っていると思います...明示的に述べられているのを見つけられませんでした。

0
Nicolai Ustinov

あなたが抱えている問題は、WCFサービス(マシン上)のSPN(サービスプリンシパル名)をセットアップし、サービスが実行されているサービスアカウントに追加する必要があることだと思います。

デフォルトのアプリプールユーザーで実行している場合は、マシンにSPNを構成する必要があります。

私はそれが厄介であることを知っています、そして通常、私たちのサービスが本番または本番前の環境に展開する準備ができてから私たちが開発者を待っているのは驚きです。

SPNは、認証プロセス中にKerberosによって使用されます。

ホスト名の代わりにマシンのIPを使用してサービスを解決してみてください。 (これはSPNを必要としないことになっています)、「test.mydomain.com」をマシンのIPアドレスに置き換えます。

<Host>
    <baseAddresses>
        <add baseAddress="net.tcp://192.168.0.253:808/SignalR/ServerHubService.svc" />
    </baseAddresses>
</Host>

以下の記事をご覧ください。- 忙しい管理者のためのKerberos
- Windows認証を使用するイントラネット上のWCF
-次の投稿について、回答として受け入れられないものを読んでみてください: net.tcpサービスに設定する必要のあるSPNは?

0
Ashraf ElSwify

ホスティングa TCPベースのサービスIISは常に弱点でした。WCFを使用すると、独自のサービスホストを簡単に実行できます。TCPポート。これを実行し、Windowsサービスとして実行するように設定することをお勧めします。

この記事を参照してください: http://msdn.Microsoft.com/en-us/library/ff649818.aspx

0
Mike Pugh