私は何日もこれと戦ってきました。文字通り、Web アプリケーションで WCF TCP ベースのサービスをセットアップする方法に関する部分的なガイドラインを提供する 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 4.5 を使用して IIS 7.5 に新しい Web サイトをセットアップし、net.tcp バインディングを設定しました。
また、Web サイトの [詳細設定] に移動し、[有効なプロトコル] をhttp,net.tcp
Windows Feature Non-HTTP Activation が有効になっている (そして再起動されている) ことを確認しました。これは Windows の機能なので、「Windows の機能を有効または無効にする」を探してください。
Web アプリケーションが実行されていることを確認する
Web サイトは、Web アプリケーションの残りの部分で正常に機能します。ファイルで 127.0.0.1 を指すように test.mydomain.com を設定しましたhosts
。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 at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress) at System .Net.Sockets.Socket.Connect(EndPoint remoteEP) で System.ServiceModel.Channels.SocketConnectionInitiator.Connect(Uri uri、TimeSpan タイムアウト)
ポート 808 で何もリッスンしていないことがわかった場合netstat -an |find /i "listening"
は、おそらく 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
実行されていますか? はい net.tcp
に設定するIIS サイト バインドはあります808:*
か? はい- IIS のサイトの [詳細設定] で [有効なプロトコル] が に設定されてい
http,net.tcp
ますか? はい - サーバーはポート 808 でリッスンしていますか? はい、確認しました
netstat -an |find /i "listening"
- ファイアウォールでポート 808 が開いていますか? はい。
- サーバーでファイアウォールがオフになっています。
- 外部からポート808でサーバーにtelnetできます
telnet mydomain.com 808
- サーバー上のサービスの構成では、次のことが確認されました。
- baseAddress は次のように調整されます
net.tcp://mydomain.com:808/SignalR/ServerHubService.svc
- これは以前のものでしたが、サーバーで機能しなかった後に
localhost
変更されました。mydomain.com
<identity><dns value="mydomain.com" /></identity>
- baseAddress は次のように調整されます
- サーバー上および別のサーバー上でローカルにクライアントを使用してテストされています。どちらも 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>
また、808 が net.tcp 接続のデフォルト ポートであると噂されているため、エンドポイントに 808 を構成せずに試しました。ただし、それでも同じ結果が得られます。
多くのことを無作為に試す代わりに、良い質問はおそらく次のようなものです。この通話がブロックされている理由を正確に教えてくれるプログラムをどちらのサーバーにもインストールできますか?
Wireshark をこのように構成すると、ポート 808 でサーバーに着信する呼び出しを調べて、呼び出しが機能しない理由を特定できる可能性があります。しかし、現時点ではこれを分析する方法がわかりません。
幸運を
私はあきらめて、代わりにこれをソケット層に実装しました。すぐに機能しました。ただし、これが他の誰かに役立つことを願っています。多くの問題が解決され、最終的にはローカルで機能したため、回答を設定しています。残りの問題は、おそらく特定の環境に関連しています。