cad跨進程通訊Remoting
正在研究cad的跨進程通訊,
難點在於cad是服務端的話,讓客戶端直接調用暴露的接口,而不會暴露實現,
因此寫了一個Remoting的案例,如下代碼就可以進行了.
至於WCF工程,由於它的App.config處理有些地方不是很理解,之后再仔細研究.
動圖演示
工程結構
- 服務端工程 --> cad的類庫,透過cad調用 --> 引用端口工程
- 客戶端工程 --> 控制台工程 --> 引用端口工程
- 端口工程 --> 類庫
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;
}
}
(完)