cad.net 跨進程通訊Remoting


cad跨進程通訊Remoting

正在研究cad的跨進程通訊,
難點在於cad是服務端的話,讓客戶端直接調用暴露的接口,而不會暴露實現,
因此寫了一個Remoting的案例,如下代碼就可以進行了.

至於WCF工程,由於它的App.config處理有些地方不是很理解,之后再仔細研究.

動圖演示

工程結構

  1. 服務端工程 --> cad的類庫,透過cad調用 --> 引用端口工程
  2. 客戶端工程 --> 控制台工程 --> 引用端口工程
  3. 端口工程 --> 類庫

1.服務端工程

#if !HC2020
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Acap = Autodesk.AutoCAD.ApplicationServices.Application;
#else
using GrxCAD.ApplicationServices;
using GrxCAD.DatabaseServices;
using GrxCAD.EditorInput;
using Acap = GrxCAD.ApplicationServices.Application;
#endif
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System;
using JoinBox.IAdapter;

namespace JoinBox.Service
{
    public class Remoting
    {
        /// <summary>
        /// 注冊服務管道 Remoting,實現占用端口
        /// </summary>
        [JoinBoxInitialize]
        public void RegisterServerChannel()
        {
            var channel = new TcpServerChannel(AdapterHelper.Port);
            ChannelServices.RegisterChannel(channel, false);
            RemotingConfiguration.RegisterWellKnownServiceType(
                typeof(BaseService),            //服務端實現(通訊地址接口)的函數
                AdapterHelper.TcpPortAdapter,   //通訊地址接口
                WellKnownObjectMode.Singleton);
        }
    }

    // 服務端實現接口工程的方法,在cad命令欄打印
    public class BaseService : MarshalByRefObject, IJoinBoxAdapter
    {
        public void PostAcedString(string str)
        {
            //阻塞線程並切換上下文,另見 https://www.cnblogs.com/JJBox/p/14179921.html
            AutoGo.SyncManager.SyncContext.Post(() => {
                Document doc = Acap.DocumentManager.MdiActiveDocument;
                Database db = doc.Database;
                Editor ed = doc.Editor;
                ed.WriteMessage(str);
            });
        }
    }
}

2.客戶端工程 JoinBox.Client

using System;
using System.Threading;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using JoinBox.IAdapter;

namespace JoinBox.Client
{
    public class Program
    {
        public static void Main(string[] args)
        {
            ChannelServices.RegisterChannel(new TcpClientChannel(), false);
            var adapter = (IJoinBoxAdapter)Activator.GetObject(typeof(IJoinBoxAdapter), AdapterHelper.TcpPortFullName);
            while (true)
            {
                var str = DateTime.Now.ToString() + "\n";
                Console.WriteLine(str);
                adapter.PostAcedString(str);//調用接口工程的方法.
                Thread.Sleep(1000);
            }
        }
    }
}

3.接口工程 JoinBox.IAdapter

此工程同時暴露給服務端和客戶端利用

namespace JoinBox.IAdapter
{
    //公共接口和方法
    public interface IJoinBoxAdapter
    {
        public void PostAcedString(string str);
    }

    //公共的屬性
    public class AdapterHelper
    {
        /// <summary>
        /// 端口
        /// </summary>
        public static int Port               = 15341;
        /// <summary>
        /// 通訊地址(接口)--服務端用
        /// </summary>
        public static string TcpPortAdapter  = "jingjing/" + nameof(IJoinBoxAdapter);
        /// <summary>
        /// 通訊地址(完整)--客戶端用
        /// </summary>
        public static string TcpPortFullName = $"tcp://localhost:{Port}/" + TcpPortAdapter;
    }
}

(完)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM