• 传说中的WCF(7):“单向”&“双向”


    在WCF中,服务器与客户端的通讯有单向(单工)和双向(双工)之分。要说有什么形式上的表现,那就是单向与双向生成的SOAP不同,咱们先放下代码不说。但通常情况下,我们也不太需要去研究生成的SOAP是啥样子 的,因为这些都是不需要我们动手的,我们也不必要精通它,没实际用途,你把SOAP玩透了,妹子也不会说你牛B的,我们只需知道某些概念的存在即可。

    虽然单向与双向通讯没有UI,我们看不到,但我们有的是实验,为什么说学编程要常做实验,只有实验你才能获得书上学不到的知识。

    WCF在实验阶段,为了方便,反正原理我们弄懂了就行,我基本上是使用最简单 的“控制台应用程序”,主要是方便。为了便于实验,而且我们知道,几乎每次实验,服务器端的代码几乎是一样的,所以,我建议各位在做研究实验的时候,不妨 做以下两项工作。

    一、以管理员身份运行VS,因为运行服务器端需要管理员权限,如果没有以管理员身份运行,调试运行将失败。从VS的快捷方式属性窗口,切换到“兼容性”选项卡,勾选“以管理员身份运行”。

    以后,只要你启动VS,就以管理员身份运行了。

    二、建一个控制台应用程序,命名为WCFServerTemplate1,完成以下代码,然后保存为项目模板。

    添加以下引用

    接着输入以下代码:

    namespace WCFServerTemplate1
    {
        class Program
        {
            static void Main(string[] args)
            {
                // 服务器基址
                Uri baseAddress = new Uri("http://localhost:1378/services");
                // 声明服务器主机
                using (ServiceHost host = new ServiceHost(typeof(MyService), baseAddress))
                {
                    // 添加绑定和终结点
                    WSHttpBinding binding = new WSHttpBinding();
                    host.AddServiceEndpoint(typeof(IService), binding, "/test");
                    // 添加服务描述
                    host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true });
                    try
                    {
                        // 打开服务
                        host.Open();
                        Console.WriteLine("服务已启动。");
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                    Console.ReadKey();
                }
            }
        }
    }
    namespace WCFServerTemplate1
    {
        [ServiceContract(Namespace = "MyNamespace")]
        public interface IService
        {
        }
    }
    namespace WCFServerTemplate1
    {
        public class MyService : IService
        {
        }
    }

    依次单击【文件】-【导出模板】

    随后弹出一个向导,选择“项目模板”,确认项目列表中选中的是你当前的项目名字。

    然后继续,继续,直到完成即可。

    保存模板后,以后在你新建项目时,就看到项目模板中有刚才导出的项目了。不过有一点很奇怪,导出时模板名字好像不能用中文。

    以上方法仅备参考,有没有用你自己鉴定。

    我们编写一个服务协定,如下:

        [ServiceContract(Namespace = "MyNamespace")]
        public interface IService
        {
            [OperationContract(IsOneWay = true)]
            void DoTestWork(string message);
        }

    将操作协定特性的IsOneWay设置为true,表明该操作是单向的,现在,我们实现这个接口。

        public class MyService : IService
        {
            public void DoTestWork(string message)
            {
                Console.WriteLine("从客户端发来的消息:" + message);
            }
        }

    在解决方案中添加一个客户端项目,并且引用该服务。并测试调用。

            static void Main(string[] args)
            {
                WS.ServiceClient cl = new WS.ServiceClient();
                cl.DoTestWork("尼玛!");
                Console.ReadKey();
            }

    OK,调用成功。

    下面我们回到服务器端代码,把服务协定和服务类改成这样:

        [ServiceContract(Namespace = "MyNamespace")]
        public interface IService
        {
            [OperationContract(IsOneWay = true)]
            DateTime DoTestWork(string message);
        }
        public class MyService : IService
        {
            public DateTime DoTestWork(string message)
            {
                Console.WriteLine("从客户端发来的消息:" + message);
                return DateTime.Now;
            }
        }

    仍然是单向模式,但操作方法返回一个DateTime结构,重新生成一下服务器端,并更新客户端的引用,看看这回运行结果如何。

    哈 哈,这回够精彩了吧!从错误信息我们得出了这么一个结论:

    启用单向通讯的方法,不能有返回值(void可以),不能有out参数,只允许传入参数。

    现在,我们把操作改为双向通讯,看看能不能执行。

        [ServiceContract(Namespace = "MyNamespace")]
        public interface IService
        {
            [OperationContract(IsOneWay = false)]
            DateTime DoTestWork(string message);
        }

    更新客户端引用,并修改调用代码。

            static void Main(string[] args)
            {
                WS.ServiceClient cl = new WS.ServiceClient();
                DateTime dt = cl.DoTestWork("尼玛!");
                Console.WriteLine("服务器回复时间:" + dt.ToString("yyyy年MM月dd日 HH时mm分ss秒"));
                Console.ReadKey();
            }

    这回就成功了,既调用了服务,也得到了返回的数据。

    从上面实验,我们看到:双向通讯是有问必有答的(哪怕方法返回void,客户端也会收到一条空消息)。

    总结一句话——有来无往叫单向通讯,礼尚往来叫双向通讯

  • 相关阅读:
    osgEarath中elevation的tms切片写法
    3D数据格式
    osgearth调试源码无法打断点问题解决
    在软件中无法选择已经安装字体的解决方案
    [vb+mo] visual baisc 6.0 基于mapobjects 2.4 开发的数字化校园电子地图
    编译osg的vrml插件
    安全漏洞之grafanacve_2021_43798
    apk反编译工具dex2jar
    磁盘空间告急
    WEB漏洞扫描工具之OWASP ZAP
  • 原文地址:https://www.cnblogs.com/GoogleGetZ/p/5752331.html
Copyright © 2020-2023  润新知