简体   繁体   English

通过命名管道传输xml序列化对象(无WCF)

[英]Transmit xml serialized objects thru named pipe (without WCF)

i want to send specific objects thru a simple named pipe. 我想通过一个简单的命名管道发送特定对象。 I think the receiver does not recognize the cut between two sent objects. 我认为接收器无法识别两个已发送对象之间的剪切。 In the result, i get an xml serialization error. 结果,我得到一个xml序列化错误。 Here is my code: 这是我的代码:

Server process: 服务器进程:

using System;
using System.IO;
using System.IO.Pipes;
using System.Threading;
using System.Xml.Serialization;

namespace NamedPipe
{
class ProgramServer
    {
        static void Main(string[] args)
        {
            NamedPipeServerStream server;
            server = new NamedPipeServerStream("PipesOfPiece");

            server.WaitForConnection();

            StreamReader reader = new StreamReader(server);
            StreamWriter writer = new StreamWriter(server);
            Console.WriteLine("Start loop. ");
            Thread.Sleep(1000);

            while (true)
            {
                XmlSerializer receiver = new XmlSerializer(typeof(PayLoad));
                object testobj = receiver.Deserialize(reader);
                Console.WriteLine("Testobject: " + ((PayLoad)(testobj)).name + ((PayLoad)(testobj)).count);
            }
        }
    }
}

Client process: 客户流程:

using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Pipes;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;

namespace NamedPipe
{
    class ProgramClient
    {
        static void Main(string[] args)
        {
            //Client
            var client = new NamedPipeClientStream("PipesOfPiece");
            client.Connect();
            StreamReader reader = new StreamReader(client);

            while (true)
            {

                StreamWriter writer = new StreamWriter(client);
                PayLoad test = new PayLoad
                ()
                {
                    name = "Test",
                    count = 42
                };

                XmlSerializer sendSerializer = new XmlSerializer(typeof(PayLoad));
                sendSerializer.Serialize(writer, test);
            }
        }
    }
}

I have tried recently using NamedPipes without WCF. 我最近尝试在不使用WCF的情况下使用NamedPipes。 You can look into this code which might give you some idea. 您可以查看此代码,这可能会给您一些想法。 Here, Client is enabled with Callback functionality so server can callback the client. 在此,启用了具有回调功能的客户端,以便服务器可以回调客户端。

static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            const string PIPE_NAME = "testPipeName33";
            const string OBJECT_NAME = "test";
            const string CALLBACK_PIPE_NAME = "testPipeName34";
            const string CALLBACK_OBJECT_NAME = "testclient";

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            if ((args.Length == 0 || args[0] == "s"))
            {
                try
                {
                   IPCRegistration.RegisterServer(PIPE_NAME,OBJECT_NAME);
                }
                catch (RemotingException)
                {
                                        remoteObject = IPCRegistration.RegisterClient(typeof(RemoteObject),PIPE_NAME,OBJECT_NAME);
                    remoteObject.OnNewProcessStarted("test");
                    Application.Exit();
                    return;
                }
                MessageBox.Show("Server:" + Process.GetCurrentProcess().Id);
                Process.Start(Application.ExecutablePath, "c");
                Application.Run(new Form1("Server"));

            }
            else
            {
                IsClient = true;
                remoteObject = IPCRegistration.RegisterClient(typeof(RemoteObject), PIPE_NAME, OBJECT_NAME);
                IPCRegistration.RegisterServer(CALLBACK_PIPE_NAME, CALLBACK_OBJECT_NAME); // Here Client will listen on this channel.
                remoteObject.SetOnNewProcessStarted(OnNewProcessStarted,Process.GetCurrentProcess().Id.ToString());
                MessageBox.Show("Client:" + Process.GetCurrentProcess().Id);
                Application.Run(new Form1("Client"));

            }
        }


        static RemoteObject remoteObject;

        static bool IsClient = false;
        static bool OnNewProcessStarted(string commandLine)
        {
            MessageBox.Show("saved:"+commandLine+" Currrent:"+Process.GetCurrentProcess().Id);
            MessageBox.Show("Is Client : " + IsClient);//problem here, IsClient should be true
            return true;
        }
    }

    public delegate bool OnNewProcessStartedDelegate(string text);

    internal class RemoteObject : MarshalByRefObject
    {
        public OnNewProcessStartedDelegate OnNewProcessStartedHandler;
        public string value;
        public bool isCallBack = false;
        const string PIPE_NAME = "testPipeName33";
        const string OBJECT_NAME = "test";
        const string CALLBACK_PIPE_NAME = "testPipeName34";
        const string CALLBACK_OBJECT_NAME = "testclient";
        RemoteObject remoteObject;
        public bool OnNewProcessStarted(string commandLine)
        {
            if (!isCallBack)
            {
                remoteObject.isCallBack = true;
                return remoteObject.OnNewProcessStarted(commandLine);
            }

            if (OnNewProcessStartedHandler != null)
                return OnNewProcessStartedHandler(value);
            return false;
        }



        public void SetOnNewProcessStarted(OnNewProcessStartedDelegate onNewProcessStarted,string value)
        {
            this.value = value;
            OnNewProcessStartedHandler = onNewProcessStarted;
            if (!isCallBack)
            {
                remoteObject = IPCRegistration.RegisterClient(typeof(RemoteObject), CALLBACK_PIPE_NAME, CALLBACK_OBJECT_NAME);
                remoteObject.isCallBack = true;
                remoteObject.SetOnNewProcessStarted(onNewProcessStarted, Process.GetCurrentProcess().Id.ToString());
            }
        }

        public override object InitializeLifetimeService()
        {
            return null;
        }
    }

    internal class IPCRegistration
    {
       public  static RemoteObject RegisterClient(Type remoteObject,string PIPE_NAME,string OBJECT_NAME)
        {
            IpcClientChannel chan = new IpcClientChannel();
            ChannelServices.RegisterChannel(chan, false);

            RemoteObject remoteObjectInstance = (RemoteObject)Activator.GetObject(remoteObject,
                    string.Format("ipc://{0}/{1}", PIPE_NAME, OBJECT_NAME));
            return remoteObjectInstance;
        }
        public static void RegisterServer(string pipeName, string objectName)
        {
            BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
            serverProvider.TypeFilterLevel = TypeFilterLevel.Full;

            IpcServerChannel chan = new IpcServerChannel("", pipeName, serverProvider);
            ChannelServices.RegisterChannel(chan, false);

            RemotingServices.Marshal(new RemoteObject(), objectName);
        }
    }

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

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