WCF - 从客户端代码设置端点

WCF - set endpoint from client code

我刚刚学习 WCF,我想编写客户端与主机位于不同 PC 上的应用程序。我首先在同一台 PC 上编写了客户端和服务器,它工作正常(来自 msdn +- 的教程),这里是 si 代码:

服务

IService1.cs

namespace GettingStartedLib
{
    [ServiceContract]
    public interface ICalculator
    {
        [OperationContract]
        double Add(double n1, double n2);
        [OperationContract]
        double Subtract(double n1, double n2);
        [OperationContract]
        double Multiply(double n1, double n2);
        [OperationContract]
        double Divide(double n1, double n2);
    }
}

Service1.cs

namespace GettingStartedLib
{
    public class CalculatorService : ICalculator
    {
        public double Add(double n1, double n2)
        {
            double result = n1 + n2;
            Console.WriteLine("Received Add({0},{1})", n1, n2);
            // Code added to write output to the console window.
            Console.WriteLine("Return: {0}", result);
            return result;
        }

        public double Subtract(double n1, double n2)
        {
            double result = n1 - n2;
            Console.WriteLine("Received Subtract({0},{1})", n1, n2);
            Console.WriteLine("Return: {0}", result);
            return result;
        }

        public double Multiply(double n1, double n2)
        {
            double result = n1 * n2;
            Console.WriteLine("Received Multiply({0},{1})", n1, n2);
            Console.WriteLine("Return: {0}", result);
            return result;
        }

        public double Divide(double n1, double n2)
        {
            double result = n1 / n2;
            Console.WriteLine("Received Divide({0},{1})", n1, n2);
            Console.WriteLine("Return: {0}", result);
            return result;
        }
    }
}

主持人 - 我添加了所有必要的参考资料。

namespace GettingStartedHost
{
    class Program
    {
        static void Main(string[] args)
        {
            // Step 1 Create a URI to serve as the base address.
            Uri baseAddress = new Uri("http://localhost:8000/GettingStarted/");

            // Step 2 Create a ServiceHost instance
            ServiceHost selfHost = new ServiceHost(typeof(CalculatorService), baseAddress);

            try
            {
                // Step 3 Add a service endpoint.
                selfHost.AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(), "CalculatorService");

                // Step 4 Enable metadata exchange.
                ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
                smb.HttpGetEnabled = true;
                selfHost.Description.Behaviors.Add(smb);

                // Step 5 Start the service.
                selfHost.Open();
                Console.WriteLine("The service is ready.");
                Console.WriteLine("Press <ENTER> to terminate service.");
                Console.WriteLine();
                Console.ReadLine();

                // Close the ServiceHostBase to shutdown the service.
                selfHost.Close();
            }
            catch (CommunicationException ce)
            {
                Console.WriteLine("An exception occurred: {0}", ce.Message);
                selfHost.Abort();
            }
        }
    }
}

最后是客户

namespace GettingStartedClient
{
    class Program
    {
        static void Main(string[] args)
        {
            //Step 1: Create an instance of the WCF proxy.
            CalculatorClient client = new CalculatorClient();
            Console.ReadLine();
            // Step 2: Call the service operations.
            // Call the Add service operation.
            double value1 = 100.00D;
            double value2 = 15.99D;
            double result = client.Add(value1, value2);
            Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);

            // Call the Subtract service operation.
            value1 = 145.00D;
            value2 = 76.54D;
            result = client.Subtract(value1, value2);
            Console.WriteLine("Subtract({0},{1}) = {2}", value1, value2, result);

            // Call the Multiply service operation.
            value1 = 9.00D;
            value2 = 81.25D;
            result = client.Multiply(value1, value2);
            Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result);

            // Call the Divide service operation.
            value1 = 22.00D;
            value2 = 7.00D;
            result = client.Divide(value1, value2);
            Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result);

            //Step 3: Closing the client gracefully closes the connection and cleans up resources.
            client.Close();

            Console.ReadLine();
        }
    }
}

我也添加了服务参考(添加服务参考 - 发现 - select 并确定)。

App.config:

<?xml version="1.0"?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
    </startup>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="BasicHttpBinding_ICalculator" />
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost:8733/Design_Time_Addresses/GettingStartedLib/Service1/"
                binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ICalculator"
                contract="ServiceReference1.ICalculator" name="BasicHttpBinding_ICalculator" />
        </client>
    </system.serviceModel>
</configuration>

我有点困惑,因为 app.config 中的地址与我在主机 Uri baseAddress = new Uri("http://localhost:8000/GettingStarted/"); 中设置的地址不同,但它有效,所以没问题...

现在我想在 运行 客户端应用程序中设置客户端端点,所以首先我想写一些简单的东西,所以我试试这个(来自另一个 Whosebug 页面):

namespace GettingStartedClient
{
    class Program
    {
        static void Main(string[] args)
        {
            //Step 1: Create an instance of the WCF proxy.
            Console.ReadLine();

            EndpointIdentity spn = EndpointIdentity.CreateSpnIdentity("host/mikev-ws");
            Uri uri = new Uri("http://localhost:8733/Design_Time_Addresses/GettingStartedLib/Service1/");
            var address = new EndpointAddress(uri, spn);
            var client = new CalculatorClient("WSHttpBinding_IEchoService", address);

            // Step 2: Call the service operations.
            // Call the Add service operation.
            double value1 = 100.00D;
            double value2 = 15.99D;
            double result = client.Add(value1, value2);
            Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);

            // Call the Subtract service operation.
            value1 = 145.00D;
            value2 = 76.54D;
            result = client.Subtract(value1, value2);
            Console.WriteLine("Subtract({0},{1}) = {2}", value1, value2, result);

            // Call the Multiply service operation.
            value1 = 9.00D;
            value2 = 81.25D;
            result = client.Multiply(value1, value2);
            Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result);

            // Call the Divide service operation.
            value1 = 22.00D;
            value2 = 7.00D;
            result = client.Divide(value1, value2);
            Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result);

            //Step 3: Closing the client gracefully closes the connection and cleans up resources.
            client.Close();

            Console.ReadLine();
        }
    }
}

.....但是它掉了。有人可以帮我设置吗?在这个项目的最终版本中,我想要客户端应用程序,其中客户端设置服务器的 IP,然后可以从服务器(主机)调用操作。

请更新托管服务的计算机的服务器 name/ip-address:

例如你的配置:

还有你的代码:Uri baseAddress = new Uri"http://{ServerName/Ip-Address}/GettingStarted/

我自己解决了。这是我的解决方案。首先,我必须将 localhost 更改为我的 IP,并将主机中的 Http 绑定更改为 basicHttpBindig:

   selfHost.AddServiceEndpoint(typeof(ICalculator), new BasicHttpBinding(), "CalculatorService");

然后我不得不从客户端删除我的服务引用并为这个新主机添加新的服务引用,所以我的 App.config 更改为:

<?xml version="1.0"?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
    </startup>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="BasicHttpBinding_ICalculator" />

            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://ip:8000/PokusWPF/CalculatorService"
                binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ICalculator"
                contract="ServiceReference1.ICalculator" name="BasicHttpBinding_ICalculator" />
        </client>
    </system.serviceModel>
</configuration>

最后我在客户端中更改了这个:

Uri uri = new Uri("http://ip:8000/PokusWPF/CalculatorService");
            var address = new EndpointAddress(uri);
            var client = new CalculatorClient();
            client.Endpoint.Address = address;
            client.Open();

现在一切都适用于不同的 PC。我希望它会对某人有所帮助。

请验证 remote/client PC 通过 LAN 或互联网处于正确的网络中,首先通过在 Internet Explorer 等网络浏览器中打开客户端电脑来验证您的服务。当它开始在任何网络中工作时浏览器然后它也将在客户端应用程序中工作。

验证您的服务托管,尝试在 IIS 等中托管相同的服务,如果它是自托管的,请确保端口正确并且远程请求使用正确的端口。