• 创建一个简单的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();
            }
        }
    }

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

  • 相关阅读:
    记录一些经常被忽略的结论
    Eclipse 各种问题解决记录
    Feign 动态URL 解决记录
    Nacos 启动失败
    多git账号配置解决方案
    记一次java.lang.StackOverflowError
    StringBuilder 以及 StringBuffer默认大小与扩容
    MySQL索引背后的数据结构及原理
    我没有高并发项目经验,但是面试的时候经常被问到高并发、性能调优方面的问题,有什么办法可以解决吗?
    istio 学习之 手动注入sidecar
  • 原文地址:https://www.cnblogs.com/lusunqing/p/3398684.html
Copyright © 2020-2023  润新知