03
2014
01

.Net中使用WCF构建简单的基于B/S和C/S的服务

第1步:创建接口

namespace WCF.Interface
{
    //[ServiceContract(CallbackContract=typeof(ICallback))]//回调接口(全双工)
    [ServiceContract]
    public interface ICalculator
    {
        [OperationContract]
        double Add(double x, double y);
    }
}


第2步:实现接口服务

namespace WCF.Service
{
    [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
    public class Calculator : ICalculator
    {
        #region ICalculator Members
        public double Add(double x, double y)
        {
            
            double result = x + y;
            #region 全双工回调
            //ICallback callback = OperationContext.Current.GetCallbackChannel<ICallback>();
            //callback.DisplayResult(x, y, result); 
            #endregion
            return result;
        }
        #endregion
    }
}

第3步:建立WinForm服务端

        #region 通过代码直接定义和开启服务
        /// <summary>
        /// 通过代码直接定义和开启服务(在启动之前必须把相应的配置文件注释或删除)
        /// </summary>
        private void HostCalculatorServiceViaCode()
        {
            try
            {
                Uri httpBaseAddress = new Uri("http://localhost:8888/Calculator");//1、基于http
                Uri tcpBaseAddress = new Uri("net.tcp://localhost:9999/Calculator");//2、基于tcp
                calculatorSerivceHost = new ServiceHost(typeof(Calculator), httpBaseAddress, tcpBaseAddress);
                BasicHttpBinding httpBinding = new BasicHttpBinding();
                NetTcpBinding tcpBinding = new NetTcpBinding();
                Type type1 = typeof(ICalculator);
                calculatorSerivceHost.AddServiceEndpoint(type1, httpBinding, "");
                calculatorSerivceHost.AddServiceEndpoint(type1, tcpBinding, "");
                ServiceMetadataBehavior behavior = calculatorSerivceHost.Description.Behaviors.Find<ServiceMetadataBehavior>();
                if (behavior == null)
                {
                    behavior = new ServiceMetadataBehavior();
                    behavior.HttpGetEnabled = true;
                    calculatorSerivceHost.Description.Behaviors.Add(behavior);
                }
                else
                {
                    behavior.HttpGetEnabled = true;
                }
                calculatorSerivceHost.Opened += delegate
                {
                    txt_info.AppendText("Calculator server has begain to listen ...使用cmd命令 netstat -aon|findstr \"9999\" 查看 ...\r\n");
                };
                calculatorSerivceHost.Open();
            }
            catch (Exception ex)
            {
                MessageBox.Show("详细信息:" + ex.Message,"出错提示,请确保参数配置正确且端口不被占用!",  MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        #endregion


第4步:建立Web服务端

namespace WCF.WebServer
{
    // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码、svc 和配置文件中的类名“Calculator”。
    /// <summary>
    /// wcf服务应用程序,测试时端口为 7777 并启动服务网站
    /// 继承于Service.Calculator,不用写额外代码直接调用
    /// </summary>
    public class Calculator :WCF.Service.Calculator
    {
    }
}


第5步:客户端调用WinForm和Web服务端显示结果

private void InvocateCalclatorServiceViaCode()
        {
            System.ServiceModel.Channels.Binding httpBinding = new BasicHttpBinding();
            System.ServiceModel.Channels.Binding tcpBinding = new NetTcpBinding();
            EndpointAddress httpAddress = new EndpointAddress("http://localhost:8888/Calculator");//WinForm基于http的通道
            EndpointAddress tcpAddress = new EndpointAddress("net.tcp://localhost:9999/Calculator");//WinForm基于tcp的通道
            EndpointAddress webhttpAddress = new EndpointAddress("http://localhost:7777/Calculator.svc");//Web服务
            txt_info.AppendText("\r\nInvocate self-host calculator service... ...");
            #region Invocate Self-host service
            CalculatorClient calculator_http = new CalculatorClient(httpBinding, httpAddress);
            CalculatorClient calculator_webhttp = new CalculatorClient(httpBinding, webhttpAddress);
            CalculatorClient calculator_tcp = new CalculatorClient(tcpBinding, tcpAddress);
            try
            {
                txt_info.AppendText("\r\nBegin to invocate calculator service via http transport... ...");
                txt_info.AppendText(string.Format("\r\nx + y = {2} where x = {0} and y = {1}", 1, 2, calculator_http.Add(1, 2)));
                txt_info.AppendText("\r\nBegin to invocate calculator service via tcp transport... ...");
                txt_info.AppendText(string.Format("\r\nx + y = {2} where x = {0} and y = {1}", 1, 2, calculator_tcp.Add(1, 2)));
                
                txt_info.AppendText("\r\nBegin to invocate calculator service via webhttp transport... ...");
                txt_info.AppendText(string.Format("\r\nx + y = {2} where x = {0} and y = {1}", 1, 2, calculator_webhttp.Add(1, 2)));
            }
            catch (Exception ex)
            {
                txt_info.AppendText(Environment.NewLine + ex.Message);
            }
            finally
            {
                calculator_http.Close();
                calculator_tcp.Close();
            }
            #endregion
            #region Invocate IIS-host service
            //txt_info.AppendText("\r\nInvocate IIS-host calculator service... ...");
            //EndpointAddress httpAddress_iisHost = new EndpointAddress("http://localhost/wcfservice/CalculatorService.svc");
            //using (CalculatorClient calculator = new CalculatorClient(httpBinding, httpAddress_iisHost))
            //{
            //    try
            //    {
            //        txt_info.AppendText("\r\nBegin to invocate calculator service via http transport... ...");
            //        txt_info.AppendText(string.Format("\r\nx + y = {2} where x = {0} and y = {1}", 1, 2, calculator.Add(1, 2)));
            //    }
            //    catch (Exception ex)
            //    {
            //        txt_info.AppendText("\r\n"+ex.Message);
            //    }
            //}
            #endregion
        }




运行效果:

如果没有运行web服务,那么web调用将出错:



测试源码:WCF服务器与客户端使用示例文件v0.2(包含全双工模式和调用web中的wcf服务).zip  





版权声明:
作者:真爱无限 出处:http://www.pukuimin.top 本文为博主原创文章版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接.
« 上一篇下一篇 »

相关文章:

评论列表:

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。