简体   繁体   English

有没有办法使用NetNamedPipeBinding关闭双工模式(不支持IDuplexSessionChannel)

[英]Is there a way to turn off duplex mode using NetNamedPipeBinding (IDuplexSessionChannel is not supported)

I have a simple .NET (C#) application with three threads: Main thread and two spawned by the Main one. 我有一个简单的.NET(C#)应用程序,它具有三个线程:主线程和由主线程派生的两个线程。 The first child is used to initialize and start the ServiceHost instance using IFirstService contract to operate. 第一个孩子用于使用IFirstService合约进行初始化和启动ServiceHost实例。 The second one is a kind of a client which uses ChannelFactory to create a channel for communication with the FirstService thread. 第二种是使用ChannelFactory来创建与FirstService线程进行通信的通道的客户端。 NetNamedPipeBinding is used for this channel. NetNamedPipeBinding用于此通道。

After starting the application by executing 通过执行启动应用程序之后

mono application.exe

Expected output should be 预期输出应为

Using System.ServiceModel.NetNamedPipeBinding...
FirstService Host is opened
Hello from Second Thread
FirstService Host is closed

But the actual result is 但是实际结果是

Using System.ServiceModel.NetNamedPipeBinding...
FirstService Host is opened
NamedPipeChannelListener.OnAcceptChannel
NamedPipeChannelListener.OnAcceptChannel.2
NamedPipeChannelListener.OnAcceptChannel.3
NamedPipeChannelListener.OnAcceptChannel
System.InvalidOperationException: Channel type IDuplexSessionChannel is not supported.
at System.ServiceModel.MonoInternal.ClientRuntimeChannel..ctor (System.ServiceModel.Dispatcher.ClientRuntime runtime, System.ServiceModel.Description.ContractDescription contract, System.TimeSpan openTimeout, System.TimeSpan closeTimeout, System.ServiceModel.Channels.IChannel contextChannel, System.ServiceModel.Channels.IChannelFactory factory, System.ServiceModel.Channels.MessageVersion messageVersion, System.ServiceModel.EndpointAddress remoteAddress, System.Uri via) [0x00165] in <8cdac92fdd4b495ba10570db10926ad4>:0
at System.ServiceModel.MonoInternal.ClientRuntimeChannel..ctor (System.ServiceModel.Description.ServiceEndpoint endpoint, System.ServiceModel.ChannelFactory channelFactory, System.ServiceModel.EndpointAddress remoteAddress, System.Uri via) [0x0002c] in <8cdac92fdd4b495ba10570db10926ad4>:0
at System.ServiceModel.ChannelFactory`1[TChannel].CreateChannel (System.ServiceModel.EndpointAddress address, System.Uri via) [0x0005b] in <8cdac92fdd4b495ba10570db10926ad4>:0
at System.ServiceModel.ChannelFactory`1[TChannel].CreateChannel (System.ServiceModel.EndpointAddress address) [0x00000] in <8cdac92fdd4b495ba10570db10926ad4>:0
at System.ServiceModel.ChannelFactory`1[TChannel].CreateChannel () [0x00012] in <8cdac92fdd4b495ba10570db10926ad4>:0
at WcfNamedPipeBindingTest.MainClass.SecondPointThread (System.Object binding_info) [0x00041] in <ef4f03ef8ba048f3b924916715fa960b>:0
FirstService Host is closed

Program.cs: Program.cs:

using System;
using System.Threading;
using System.ServiceModel;
using System.ServiceModel.Channels;

namespace WcfNamedPipeBindingTest
{
    [ServiceContract]
    interface IFirstService
    {
        [OperationContract]
        void ShowMessage (string message);
    }

    [ServiceBehavior (InstanceContextMode = InstanceContextMode.Single)]
    class FirstService : IFirstService
    {
        public void ShowMessage (string message)
        {
            Console.WriteLine (message);
        }
    }

    class BindingInfo
    {
        public Binding binding;
        public Uri uri;
    }

    class MainClass
    {
        public static void Main (string[] args)
        {
            try {

                var binding_info = new BindingInfo {
                    binding = new NetNamedPipeBinding (),
                    uri = new Uri ("net.pipe://localhost/ftest")
                };


                Console.WriteLine ("Using {0}...", binding_info.binding.ToString ());

                var first_point = new Thread (FirstPointThread);
                var second_point = new Thread (SecondPointThread);

                first_point.Start (binding_info);
                second_point.Start (binding_info);

                first_point.Join ();
                second_point.Join ();
            } catch (Exception ex) {
                Console.WriteLine (ex);
            }
        }

        public static void FirstPointThread (object binding_info)
        {
            try {
                var binding = ((BindingInfo)binding_info).binding;
                var uri = ((BindingInfo)binding_info).uri;

                var instance = new FirstService ();
                var host = new ServiceHost (instance, uri);
                host.AddServiceEndpoint (typeof(IFirstService), binding, "fserv");

                host.Opened += (sender, e) => {
                    Console.WriteLine ("FirstService Host is opened");
                    Thread.Sleep (5000);
                    ((ServiceHost)sender).Close ();
                };

                host.Closed += (sender, e) => Console.WriteLine ("FirstService Host is closed");

                host.Open ();
            } catch (Exception ex) {
                Console.WriteLine (ex);
            }
        }

        public static void SecondPointThread (object binding_info)
        {
            try {
                var binding = ((BindingInfo)binding_info).binding;
                var uri = ((BindingInfo)binding_info).uri;

                Thread.Sleep (2000);

                var pipe_factory =
                    new ChannelFactory<IFirstService> (
                        binding,
                        new EndpointAddress (
                            string.Format ("{0}/fserv", uri)
                        )
                    );

                pipe_factory.Open ();
                IFirstService pipe_channel = pipe_factory.CreateChannel ();
                pipe_channel.ShowMessage ("Hello from Second Thread");
                pipe_factory.Close ();
            } catch (Exception ex) {
                Console.WriteLine (ex);
            }
        }
    }
}

Can I avoid using of a DuplexSessionChannel? 我可以避免使用DuplexSessionChannel吗?

I believe that using named pipes for WCF (which use MMFs as part of their implementation) are not available with Mono. 我相信Mono不能使用WCF命名管道(将MMF作为实现的一部分)。

However, you might be able to use NetTcpBinding with Mono. 但是,您可能可以将NetTcpBinding与Mono一起使用。 Try changing your binding to the following: 尝试将绑定更改为以下内容:

var binding_info = new BindingInfo
{
    binding = new NetTcpBinding(),
    uri = new Uri("net.tcp://localhost/ftest")
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM