创建一个简单的WCF程序2——手动开启/关闭WCF服务与动态调用WCF地址

一、创建WCF服务器

1、创建WCF服务器的窗体应用程序

打开VS2010,选择文件→新建→项目菜单项,在打开的新建项目对话框中,依次选择Visual C#→Windows→Windows窗体应用程序,然后输入项目名称(Name),存放位置(Location)和解决方案名称(Solution Name),点击“确定”生成项目。如下图:

2、在新建的WcfServer项目中右键添加→新建项,新建一个Calculate的WCF服务,接着添加服务操作,本示例中添加了一个Add的加法服务操作

 

 Add的加法服务操作代码:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace WcfServer
{
    // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“ICalculate”。
    [ServiceContract]
    public interface ICalculate
    {
        [OperationContract]
        int Add(int i, int j);
    }
}

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace WcfServer
{
    // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的类名“Calculate”。
    public class Calculate : ICalculate
    {
        public int Add(int i, int j)
        {
            return i + j;
        }
    }
}

3、将该项目中创建的Form1重命名为FrmMain,在窗体中进行WCF服务的操作,如下图:

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.ServiceModel;
using System.Configuration;
using System.ServiceModel.Configuration;

namespace WcfServer
{
    public partial class FrmMain : Form
    {
        public FrmMain()
        {
            InitializeComponent();
            txtWcfServiceURL.Text = ConfigHelper.Config.WcfServiceConnectURL;
        }

        /// <summary>
        /// 主机服务
        /// </summary>
        ServiceHost serviceHost;

        /// <summary>
        /// 开启服务
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnStart_Click(object sender, EventArgs e)
        {
            ConfigHelper.Config.WcfServiceConnectURL = txtWcfServiceURL.Text;
            if (serviceHost == null)
            {
                this.btnStart.Enabled = false;
                this.btnStop.Enabled = true;
                try
                {
                    // 实例化WCF服务对象
                    serviceHost = new ServiceHost(typeof(WcfServer.Calculate));
                    serviceHost.Opened += delegate { MessageBox.Show("启动服务OK"); };
                    serviceHost.Closed += delegate { MessageBox.Show("停止服务OK"); };
                    serviceHost.Open();
                }
                catch (Exception ex)
                {
                    MessageBox.Show("启动服务异常:" + ex.Message + "==>" + ex.StackTrace);
                }
            }
            else
            {
                btnStop_Click(sender, e);
            }
        }

        /// <summary>
        /// 停止服务
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnStop_Click(object sender, EventArgs e)
        {
            this.btnStart.Enabled = true;
            this.btnStop.Enabled = false;
            try
            {
                if (serviceHost != null)
                {
                    serviceHost.Close();
                    serviceHost = null;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("停止服务异常:" + ex.Message + "==>" + ex.StackTrace);
            }
        }
    }

    public class ConfigHelper
    {
        private static ConfigHelper _config = new ConfigHelper();

        /// <summary>
        /// 获取ServerConfig对象
        /// </summary>
        public static ConfigHelper Config
        {
            get { return _config; }
        }

        /// <summary>
        /// 获取或设置连接服务器地址
        /// </summary>
        public string WcfServiceConnectURL
        {
            get { return GetWcfServiceUri(); }
            set { SetWcfServiceUri(value); }
        }

        /// <summary>
        /// 设置Wcf服务器的地址
        /// </summary>
        private void SetWcfServiceUri(string uri)
        {
            Configuration serviceModelConfig = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            ConfigurationSectionGroup serviceModel = serviceModelConfig.SectionGroups["system.serviceModel"];
            ServiceModelSectionGroup serviceModelSectionGroup = serviceModel as ServiceModelSectionGroup;
            ServiceElement service = serviceModelSectionGroup.Services.Services["WcfServer.Calculate"];
            service.Host.BaseAddresses[0].BaseAddress = uri;
            serviceModelConfig.Save();
            // 刷新命名节,在下次检索它时将从磁盘重新读取它。记住应用程序要刷新节点
            //ConfigurationManager.RefreshSection("system.serviceModel");
            ConfigurationManager.RefreshSection("system.serviceModel/behaviors");
            ConfigurationManager.RefreshSection("system.serviceModel/bindings");
            ConfigurationManager.RefreshSection("system.serviceModel/client");
            ConfigurationManager.RefreshSection("system.serviceModel/services");
        }
        /// <summary>
        /// 获取Wcf服务器的地址
        /// </summary>
        /// <returns></returns>
        private string GetWcfServiceUri()
        {
            Configuration serviceModelConfig = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            ConfigurationSectionGroup serviceModel = serviceModelConfig.SectionGroups["system.serviceModel"];
            ServiceModelSectionGroup serviceModelSectionGroup = serviceModel as ServiceModelSectionGroup;
            ServiceElement service = serviceModelSectionGroup.Services.Services["WcfServer.Calculate"];
            return service.Host.BaseAddresses[0].BaseAddress;
        }

        /// <summary>
        /// 设置指定节点的配置值
        /// </summary>
        private void SetAppSettings(string key, string value)
        {
            Configuration appSettingConfig = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            appSettingConfig.AppSettings.Settings[key].Value = value;
            appSettingConfig.Save();
            ConfigurationManager.RefreshSection("appSettings");// 刷新命名节,在下次检索它时将从磁盘重新读取它。记住应用程序要刷新节点
        }

        /// <summary>
        /// 获取指定节点的配置值
        /// </summary>
        private string GetAppSettings(string key)
        {
            return ConfigurationManager.AppSettings[key];
        }
    }
}

这样WCF服务器基本上就做好了,接下来就是在WCF客户端调用了!

二、WCF客户端

1、新建的控制台程序项目WcfClient,右键添加服务引用,弹出添加服务引用对话框,点击前往,在地址上输入WCF服务器的地址,找到服务后,修改命名空间,点击确定,项目自动生成服务。如下图:

 

2、客户端(控制台应用程序)中调用WCF服务操作

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;

namespace WcfClient
{
    class Program
    {
        // 要想异步调用,需要在添加服务引用时,选择“高级”按钮→勾选“生成异步操作”
        static void Main(string[] args)
        {
            EndpointAddress endPoint = new EndpointAddress("http://192.168.8.184/Calculate");
            // 基于WSHttp请求方式
            Binding wshttpBinding = new WSHttpBinding();
            wshttpBinding.SendTimeout = new System.TimeSpan(0, 1, 0);
            // 手动调用WCF地址
            WcfService.CalculateClient calcTest = new WcfService.CalculateClient(wshttpBinding, endPoint);
            // 进行异步操作
            calcTest.AddCompleted += new EventHandler<WcfService.AddCompletedEventArgs>(calcTest_AddCompleted);
            calcTest.AddAsync(12, 21);

            Console.ReadKey();
        }

        /// <summary>
        /// 调用AddAsync方法完成后回调事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        static void calcTest_AddCompleted(object sender, WcfService.AddCompletedEventArgs e)
        {
            Console.WriteLine(e.Result);
        }
    }
}

 

使用ChannelFactory类动态调用WCF地址: 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;

namespace WcfClient
{
    class Program
    {
        static void Main(string[] args)
        {
            WcfService.ICalculate icalcTest = null;
            try
            {
                EndpointAddress endPoint = new EndpointAddress("http://192.168.8.184/Calculate");
                // 基于WSHttp请求方式
                Binding wshttpBinding = new WSHttpBinding();
                //using (ChannelFactory<WcfService.ICalculate> channelFactory = new ChannelFactory<WcfService.ICalculate>("ClientEndpoint", endPoint))
                using (ChannelFactory<WcfService.ICalculate> channelFactory = new ChannelFactory<WcfService.ICalculate>(wshttpBinding, endPoint))
                {
                    icalcTest = channelFactory.CreateChannel();   // 建立连接通道
                    (icalcTest as ICommunicationObject).Closed += delegate
                    {
                        Console.WriteLine("连接已关闭");
                    };
                    int addResult = icalcTest.Add(12, 21);
                    Console.WriteLine(addResult);
                }
            }
            catch (TimeoutException)
            {
                (icalcTest as ICommunicationObject).Abort();
            }
            catch (CommunicationException)
            {
                (icalcTest as ICommunicationObject).Abort();
            }
            catch (Exception)
            {
                (icalcTest as ICommunicationObject).Close();
            }

            Console.ReadKey();
        }
    }
}

 本示例的源码:https://files.cnblogs.com/lusunqing/WcfTest.rar

posted @ 2013-10-31 10:30  LS庆  阅读(2533)  评论(0编辑  收藏  举报