1

ここでスタックの中で多くのブログと多くの質問を読みましたが、正確なシナリオ (実際には非常に単純なもの) を見つけることができませんでした。

環境

Visual Studio 2010 プロジェクトのライブラリ内にサービスを記述しています。i は、サービス コントラクトのインターフェイスと、そのコントラクトを実装するサービス クラスを作成しました。

namespace MyNS.WebSrvLibrary {
[ServiceContract(Namespace = "http://schemas.dummy.com")]
public interface IEchoService {
  [OperationContract()]
  EchoMessageResponse Echo(EchoMessage msg);
}
}

サービス:

namespace MyNS.WebSrvLibrary {
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class EchoService : IEchoService {
  public EchoService() {}
  [OperationBehavior()]
  public virtual EchoMessageResponse Echo(EchoMessage msg) {
    return new EchoMessageResponse("Ciccio");
  }
  public static IEchoService GetChannel(string addr = "") {
    // Create the service endpoint
    Binding binding = new BasicHttpBinding();
    ServiceEndpoint endpoint =
      new ServiceEndpoint(
            ContractDescription.GetContract(typeof(IEchoService)),
            binding,
            new EndpointAddress(addr));
    // Create channel factory and get proper channel for service.
    ChannelFactory<IEchoService> channelFactory = new ChannelFactory<IEchoService>(endpoint);
    IEchoService svc = channelFactory.CreateChannel();
    return svc;
  }
}
}

クラスは likeEchoMessageResponseとs を適用しており、問題ありEchoMessageません。DataContract

前に述べたように、サービスは dll (アセンブリ) にコンパイルされ、参照を追加するだけで bin フォルダー内の Web アプリケーションにインポートされます。この Web アプリケーションにはsvc、Web サービス用のファイルがあります。

<%@ ServiceHost Language="C#" Debug="true" Service="MyNS.WebSrvLibrary.EchoService" %>

そして、これはWeb.configファイルです:

<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <services>
      <service name="MyNS.WebSrvLibrary.EchoService">
        <endpoint name="basicHttpBinding" address="" 
                                     binding="basicHttpBinding" 
                                     bindingConfiguration="basicHttpBinding_Svc"
                                     contract="MyNS.WebSrvLibrary.IEchoService"/>
        <endpoint name="mexHttpBinding" address="/Mex"
                                     binding="mexHttpBinding"
                                     contract="IMetadataExchange"/>
      </service>
    </services>
    <bindings>
      <basicHttpBinding>
        <binding maxReceivedMessageSize="2147483647" openTimeout="12:00:00" receiveTimeout="12:00:00" closeTimeout="12:00:00" sendTimeout="12:00:00">
          <readerQuotas maxStringContentLength="1310720"
                        maxArrayLength="16384"
                        maxBytesPerRead="24096"
                        maxDepth="10000"
                        maxNameTableCharCount="16384"/>
        </binding>
        <binding name="basicHttpBinding_Svc" maxReceivedMessageSize="2147483647" openTimeout="12:00:00" receiveTimeout="12:00:00" closeTimeout="12:00:00" sendTimeout="12:00:00">
          <readerQuotas maxStringContentLength="1310720"
                        maxArrayLength="16384"
                        maxBytesPerRead="24096"
                        maxDepth="10000"
                        maxNameTableCharCount="16384"/>
        </binding>
      </basicHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
</configuration>

最後に、次のような実行可能.exeファイルにコンパイルするクライアント アプリケーションがあります。

class Program {
  static void Main(string[] args) {
    IEchoService svc = EchoService.GetChannel("http://localhost:80/T/Service.svc");
    EchoMessageResponse rmsp = svc.Echo(new EchoMessage("Hello"));
    System.Threading.Thread.Sleep(10000);
  } /* Main */
} /* Program */

サーバー側の問題に関する情報

もちろん、Web アプリケーションはデフォルト Web サイトの IIS でホストされ、ポート 80 をリッスンします。

問題

実行可能アプリケーションを実行すると、次のSystem.ServiceModel.CommunicationException例外が発生します。

への HTTP 応答の受信中にエラーが発生しました http://localhost/T/Service.svc。これは、サービス エンドポイント バインディングが HTTP プロトコルを使用していないことが原因である可能性があります。これは、HTTP 要求コンテキストがサーバーによって中止されたことが原因である可能性もあります (サービスのシャットダウンが原因である可能性があります)。詳細については、サーバー ログを参照してください。

innerExceptionのタイプ: System.Net.WebException:

基になる接続が閉じられました: 受信時に予期しないエラーが発生しました。

innerException(例外ツリーの最後) のタイプSystem.Net.Sockets.SocketException:

既存の接続がリモート ホストによって強制的に閉じられました。

完全なスタックは次のとおりです。

サーバー スタック トレース: System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException (WebException webException、HttpWebRequest 要求、HttpAbortReason abortReason) で
System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan タイムアウト) で System.ServiceModel.Channels.RequestChannel.Request(メッセージ メッセージ、TimeSpan タイムアウト) で System.ServiceModel.Dispatcher.RequestChannelBinder.Request(メッセージ メッセージ、TimeSpan) System.ServiceModel.Channels.ServiceChannel.Call(文字列アクション、Boolean oneway、ProxyOperationRuntime 操作、Object[] ins、Object[] outs、TimeSpan タイムアウト) で System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall、ProxyOperationRuntime)操作) System.ServiceModel.Channels.ServiceChannelProxy.Invoke (IMessage メッセージ) で

[0] で再スローされた例外: System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) で System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 タイプ) で DDBR.DiscoveryServiceLibrary. System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String) の C:\Data\ROOT_APPS\DistributedDataBackupAndRecovery\TestClient\Program.cs:line 20 の DDBR.TestClient.Program.Main(String[] args) の IEchoService.Echo(EchoMessage msg) [] args) で System.AppDomain.ExecuteAssembly (String assemblyFile, Evidence assemblySecurity, String[] args) で Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
で System.Threading.ThreadHelper.ThreadStart_Context(オブジェクト状態)
System.Threading.ExecutionContext.Run (ExecutionContext executionContext、ContextCallback コールバック、オブジェクト状態、ブール値の ignoreSyncCtx) で System.Threading.ExecutionContext.Run (ExecutionContext executionContext、ContextCallback コールバック、オブジェクト状態) で System.Threading.ThreadHelper.ThreadStart()

これはStackTrace、最初の例外 (内側のものではなく、最初のもの) のプロパティにあります。

非常に奇妙な何か...

非常に奇妙なことは、ブラウザを開いて次のように入力すると、

http://localhost/T/Service.svc

サービスに関するいくつかの基本的な情報を公開する Microsoft IIS の有名な画面が表示されます。これは、Web サービスが有効で、指定されたアドレス (エンドポイント) で実行されていることを意味します。

私はこの例外を探しましたが、誰もこれらの特性を持っていません...一般的に、より詳細で複雑なコンテキストが関係しています.

何をすべきか?

もう一つ...

なぜ私がサービス参照を使用しないのか疑問に思われるかもしれません...私はしたくないからです。これには理由があります。ここでのポイントは、これまでのところ、このGetChannelアプローチは常にうまく機能しているということです...なぜ私が今問題を抱えているのかわかりません...

実際にはどのような問題が想定されているのでしょうか。タイムアウトになることはありませんが、実際にはこれを信じていません。これは、考えられる多くの方法の中で最も高速に動作する単純な方法です。不思議です・・・本当に。

4

2 に答える 2

0

コンソールアプリにサービス参照を追加し、使用している実際のサービスクラスではなく、プロキシオブジェクトを使用する必要があるようです。クライアントとしてサービスを使用しています。クライアントプロジェクトにサービス参照を追加するときに作成される自動生成されたプロキシクラスを介してサービスを呼び出す代わりに。

于 2012-10-24T09:54:00.393 に答える
0

問題はDataContract関連するものでした。サービス メソッドに渡されるメッセージとして使用するクラスの 1 つで、シリアライザーがループを経験する原因となるプロパティが誤って書き込まれていました...これにより、シリアライザーがStackOverflow Exceptionバーサークになり、接続が閉じられました。

問題はデータに関連するものではなく、そのためのコードを提供していないと思いました。お騒がせしてすみません。少なくとも私の質問は、エラーに関するいくつかの有用な情報を提供できますDataContractsが、例外の説明を見て実際に把握することはできません。

于 2012-10-25T13:15:16.603 に答える