1

短いバージョン:localhostクライアントが別のマシン上の Java である場合、 WCF Windows サービス エンドポイント アドレス構成をホスト名として使用できますか?

長いバージョン:

Windows サービスとして実行される WCF サービスがあります。このサービスのクライアントは Java で記述されており、プロキシ クラスは を使用して生成されwsimportます。WCF サービスのエンドポイント構成に、WCF サービスが存在するホスト名を含むアドレスが含まれている場合、Java プロキシ クラスを生成しwsimportてクライアントを正常に実行できます。このシナリオでの WCF 構成ファイルは次のようになります。

 <service name="crOps.CompanionService" behaviorConfiguration="CompanionServiceBehavior">
    <host>
      <baseAddresses>
        <add baseAddress="http://chvprdctxxa604.eu.scor.local:8432/crOpsCompanion/service"/>
      </baseAddresses>
    </host>
    <endpoint address="" binding="basicHttpBinding" contract="crOps.ICompanionService"/>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
  </service>

wsimportプロキシを生成するコマンドは次のとおりです。

C:\Program Files\Java\jdk1.7.0_17\bin\wsimport.exe  -p crOps.companion -keep http://chvprdctxxa604.eu.scor.local:8432/crOpsCompanion/service?wsdl

これはすべてうまくいきます。

ただし、この WCF サービスは約 10 台のサーバーで実行されます。私の現在の希望は、構成ファイルを「ホストに依存しない」にすることです。つまり、同じ構成ファイルがすべてのサーバーで機能することです。つまり、構成ファイルにホスト名がありません。

WCF 構成ファイルを認識する方法を少し探しましたが、何も見つかりませんでした。そこでlocalhost、ホスト名の代わりに試してみることにしました。それはこのように見えます...

      <service name="crOps.CompanionService" behaviorConfiguration="CompanionServiceBehavior">
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost:8432/crOpsCompanion/service"/>
      </baseAddresses>
    </host>
    <endpoint address="" binding="basicHttpBinding" contract="crOps.ICompanionService"/>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
  </service>

ただし、wsimportコマンド (上記) を実行すると、次のエラーが発生します。

    parsing WSDL...


[ERROR]         
    Unable to parse "http://localhost:8432/crOpsCompanion/service?wsdl=wsdl0" : 
    Connection refused: connect 
    line 1 of http://chvprdctxxa604.eu.scor.local:8432/crOpsCompanion/service?wsdl

[ERROR]         
    Unable to parse "http://localhost:8432/crOpsCompanion/service?wsdl=wsdl0" : 
    Connection refused: connect

Failed to read the WSDL document: 
    http://chvprdctxxa604.eu.scor.local:8432/crOpsCompanion/service?wsdl, because 
    1) could not find the document; 
    2) the document could not be read; 
    3) the root element of the document is not <wsdl:definitions
>.


[ERROR] failed.noservice=Could not find wsdl:service in the provided WSDL(s):

http://chvprdctxxa604.eu.scor.local:8432/crOpsCompanion/service?wsdl
 At least one WSDL with at least one service definition needs to be provided.


        Failed to parse the WSDL.

だから、私が知りたいのはlocalhost、クライアントが別のマシン上のJavaの場合、WCF Windowsサービスエンドポイントアドレス構成をホスト名として使用できますか? そうでない場合、なぜですか?もしそうなら、どのように?

24時間後:

まだ解決していません。

NLB を使用するために Shiraz Bhaiji によって提案された手法は、実際、すべてのサーバーに対して 1 つの構成ファイルという私の目標の一部を達成します。エンドポイント アドレスのホスト名は、クラスターが世界に提示する「クラスター名」になり、すべてのサーバー上のすべてのサービスが同じ名前になります。

私の場合の NLB ソリューションの問題は、このサーバーを実行している各サーバーが個別に接続できる必要があることです。これは実際にはクラスター タイプのサービスではなく、12 ほどのサーバーのそれぞれを実行する必要があり、クライアントがそれぞれに個別に接続するローカル サービスに近いものです。

そして、Yaron Naveh の返信で説明されている、ローカルの WSDL ファイルを使用してプロキシを生成する手法について説明します。Java プロキシ クラスを生成することはできますwsimportが、それらを使用して Web サービス (エンドポイント アドレスに localhost が含まれる) にアクセスすると、この例外が発生します。これは私にとって興味深いものです。これは単一の printStackTrace() 呼び出しの出力であり、他の 2 つの例外をラップしているように見えますが、スタック トレースでラップされた例外から見慣れているものとは異なります。 .

com.sun.xml.internal.ws.wsdl.parser.InaccessibleWSDLException: 2 counts of InaccessibleWSDLException.

javax.xml.stream.XMLStreamException: Invalid WSDL http://chvprdctxxa604:8432/crOpsCompanion/service, expected {http://schemas.xmlsoap.org/wsdl/}definitions found HTML at (lineLine number = 1
Column number = 7
System Id = http://chvprdctxxa604:8432/crOpsCompanion/service
Public Id = null
Location Uri= http://chvprdctxxa604:8432/crOpsCompanion/service
CharacterOffset = 10
)

java.io.IOException: Got Connection refused: connect while opening stream from http://localhost:8432/crOpsCompanion/service?wsdl=wsdl0

at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.tryWithMex(Unknown Source)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(Unknown Source)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(Unknown Source)
at com.sun.xml.internal.ws.client.WSServiceDelegate.parseWSDL(Unknown Source)
at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(Unknown Source)
at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(Unknown Source)
at com.sun.xml.internal.ws.spi.ProviderImpl.createServiceDelegate(Unknown Source)
at javax.xml.ws.Service.<init>(Unknown Source)
at crOps.companion.CompanionService.<init>(CompanionService.java:58)
at crOps.companion.Main.main(Main.java:14)

スタック トレースで、プロキシ クラスが実行時に WSDL を取得するために接続しようとしていることに気付きましたlocalhostが、プロキシは localhost への参照を含まない WSDL で生成されました。ただし、WCF サービスによって発行された WSDL には、<wsdl:import>要素に localhost 参照が含まれています。

<wsdl:import namespace="http://crOps.CompanionService" location="http://localhost:8432/crOpsCompanion/service?wsdl=wsdl0" /> 

locationそのため、Java は属性内の WSDL を取得しようとしていますが、取得できません。

C# で記述された WCF クライアントは同じことを行うのでしょうか? つまり、WCF クライアントは、実行時に<wsdl:import>location属性で指定された WSDL にアクセスする必要がありますか? Java の場合と同じ手順で WCF クライアント プロキシを作成しました。参照なしの WSDL を使用してプロキシ クラスを生成し、WCF エンドポイント アドレス構成にlocalhost構成ファイルが含まれている WCF サービスにアクセスしました。localhost

これはうまくいきます!WCF クライアントは、要素のlocation属性で指定された WSDL を実行時に取得できる必要はありません。<wsdl:import>

だから今、これは私の目には Java/wsimport の質問になりました。

私の脳は今疲れています。後で戻ってきて、このテキストの壁をきれいにして、誰かが読んで返信したくなるようなものにします.

4

3 に答える 3

1

これをチェックしてください:

http://msdn.microsoft.com/en-us/library/ee816894.aspx

また、ベース アドレスをまったく追加しないとどうなりますか?

発生する問題は、インポート プロセスにあることに注意してください。ランタイムは正常に動作します。したがって、固定 URL (またはローカル wsdl ファイル) からのインポートを Java クライアントに実行させることができます。

于 2013-07-14T17:43:36.793 に答える
1

localhost は、呼び出しを行うマシンに向かうループバック アドレスです。したがって、マシン A からマシン B に呼び出したい場合は、localhost を使用できません。

これを行う方法は、ネットワーク負荷分散 (NLB) を使用することです。

NLB を使用して、すべてのサーバーが応答する共通の IP アドレスを作成します。次に、任意のサーバーが応答できる単一のアドレスを持つことができます。

于 2013-07-14T20:01:11.413 に答える
0

私の場合の答えは、「いいえ、クライアントが Java の場合、WCF 構成ファイルのエンドポイント アドレスに localhost を使用することはできません」でした。localhost は、実行時に WSDL のいくつかの場所で発行され、上記の質問で説明したエラーを引き起こします。

クライアントが C#/WCF クライアントの場合は機能します。クライアントが C#/WCF の場合、WCF 構成ファイルのエンドポイント アドレスに localhost を含めることができます。

ただし、WCF でホスト名を含まないすべてのサーバーの単一の構成ファイルを作成し、Java クライアントを で生成するにはwsimport、すべてのエンドポイント構成をコードに入れる必要があります。

(サイドバー: Shiraz Bhaiji が提案したソリューション (NLB クラスター) は、サービスを実行する各ホストが個別にアドレス指定可能であるという追加の要件がなければ、すべてのサービスに対して単一の WCF 構成という私の目標を達成したでしょう。)

とにかく、これが私がやったことです:

1>アプリ構成ファイルからすべて<endpoint>と要素を削除します。<host>

2> 次のコードを追加して、アプリに ServiceHost を作成します。

    public ServiceHost getServiceHost()
    {
        string strURL = "http://" + System.Net.Dns.GetHostName() + ":8432/crOpsCompanion/service";
        Uri httpAddress = new Uri(strURL);
        Uri[] baseAddresses = { httpAddress };
        ServiceHost host = new ServiceHost(typeof(crOps.CompanionService), baseAddresses);
        host.AddServiceEndpoint(
            typeof(crOps.ICompanionService),
            new BasicHttpBinding(),
            "");
        ServiceMetadataBehavior mb = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
        if (mb == null)
        {
            mb = new ServiceMetadataBehavior();
            mb.HttpGetEnabled = true;
            host.Description.Behaviors.Add(mb);
        }
        host.AddServiceEndpoint(
            ServiceMetadataBehavior.MexContractName,
            MetadataExchangeBindings.CreateMexHttpBinding(),
            "mex");
        return host;
    }
于 2013-07-18T20:05:58.010 に答える