Revit二次开发之Socket通信实现自动化处理任务(一)
2016-04-14 13:30
393 查看
本例将在Revit ExternalApplication中启动一个服务器,监听客户端发送的消息,并通过这个消息,打开对应的rvt文件,当然你可以基于此定义更多消息并处理这些消息,以实现更多可能。
本例将分为以下几个部分:
1、需要构建一个ExternalApplication常驻Revit,并获取UIApplication对象,用以打开项目文件
2、在ExternalApplication中启动Socket服务器,监听客户端消息
3、由于Revit可能会处理耗时任务,需要建立一个单例的消息队列,管理来自不同客户端的不同消息,以便Revit顺序处理
4、Client程序发送消息给Revit服务器
第一部分,Revit外部应用,以打开一个Revit文档为例
第二部分,Socket服务器
第三部分,消息队列,单例
第四部分,客户端程序,WindowsConsoleApplication
所有组件都准备完毕了,接下来可以用Addin文件配置插件了,之后运行Revit,不用打开任何图纸,直接运行Client,Revit会依次打开这两个项目文件,运行的结果如下:
本例将分为以下几个部分:
1、需要构建一个ExternalApplication常驻Revit,并获取UIApplication对象,用以打开项目文件
2、在ExternalApplication中启动Socket服务器,监听客户端消息
3、由于Revit可能会处理耗时任务,需要建立一个单例的消息队列,管理来自不同客户端的不同消息,以便Revit顺序处理
4、Client程序发送消息给Revit服务器
第一部分,Revit外部应用,以打开一个Revit文档为例
public class Exporter : IExternalApplication { private UIApplication uiApp = null; public Result OnStartup(UIControlledApplication application) { System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false; /创建并启动第二部分创建的服务器 Communicator server = new Communicator("127.0.0.1", 2000); server.StartListening(); application.ControlledApplication.ApplicationInitialized += OnApplicationInitialized; return Result.Succeeded; } public Result OnShutdown(UIControlledApplication application) { return Result.Succeeded; } private void OnApplicationInitialized(object sender, ApplicationInitializedEventArgs e) { //获取UIApplication对象 Application app = sender as Application; uiApp = new UIApplication(app); uiApp.Idling += HandleMessage; } //循环处理消息 private void HandleMessage(object sender, IdlingEventArgs e) { if (MessageStation.Messages.HasMessage) { KeyValuePair<int, string> message = MessageStation.Messages.GetMessage(); try { Document document = uiApp.Application.OpenDocumentFile(message.Value); TaskDialog.Show("document", document.PathName); } catch (Exception ex) { TaskDialog.Show("error", ex.ToString()); } } } }
第二部分,Socket服务器
internal class Communicator { private int target_port = 2000; private string target_host = "127.0.0.1"; private Socket server_socket = null; private int connection_max = 10; internal Communicator() { } internal Communicator(string ip, int port) { this.target_host = ip; this.target_port = port; } internal int Port { get { return target_port; } set { target_port = value; } } internal string Host { get { return target_host; } set { target_host = value; } } internal int MaxConnection { get { return connection_max; } set { connection_max = value; } } //建立与客户端的连接 internal bool StartListening() { try { IPAddress ip_address = IPAddress.Parse(target_host); IPEndPoint ip_endpoint = new IPEndPoint(ip_address, target_port); server_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); server_socket.Bind(ip_endpoint); server_socket.Listen(connection_max); Thread listenThread = new Thread(listen); listenThread.Start(); return true; } catch (Exception ex) { return false; } } internal bool StartListening(string ip, int port) { this.target_host = ip; this.target_port = port; return StartListening(); } //监听客户端消息 private void listen() { while (true) { Socket clientSocket = server_socket.Accept(); Thread receiveThread = new Thread(receive); receiveThread.Start(clientSocket); } } //接收客户端消息 private void receive(object socket) { Socket clientSocket = socket as Socket; if (clientSocket == null) return; while (true) { try { string receiveStr = ""; byte[] receiveBytes = new byte[1024]; int bytes = clientSocket.Receive(receiveBytes, receiveBytes.Length, 0); receiveStr += Encoding.ASCII.GetString(receiveBytes, 0, bytes); if (receiveStr != "") { //客户端消息入列 MessageStation.Messages.AppendMessage(Thread.CurrentThread.ManagedThreadId, receiveStr); } } catch (Exception ex) { clientSocket.Shutdown(SocketShutdown.Both); clientSocket.Close(); MessageBox.Show(ex.ToString()); break; } } } }
第三部分,消息队列,单例
internal class MessageStation { //构造函数私有化 private MessageStation() { _messages = new Queue<KeyValuePair<int, string>>(); } //C#语言特性实现单例 internal static readonly MessageStation Messages = new MessageStation(); private Queue<KeyValuePair<int, string>> _messages = null; //是否有消息 internal bool HasMessage { get { return _messages.Count > 0; } } //入列 internal void AppendMessage(int clientId, string message) { _messages.Enqueue(new KeyValuePair<int, string>(clientId, message)); } //出列 internal KeyValuePair<int, string> GetMessage() { if (_messages.Count > 0) return _messages.Dequeue(); return new KeyValuePair<int, string>(-1, "no message"); } }
第四部分,客户端程序,WindowsConsoleApplication
class Client { static void Main(string[] args) { try { int port = 2000; string host = "127.0.0.1"; IPAddress ip = IPAddress.Parse(host); IPEndPoint ipe = new IPEndPoint(ip, port); Socket c = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); Console.WriteLine("Connecting..."); c.Connect(ipe); string sendStr = ""; byte[] bs; //向服务器发送一个文件路径 sendStr = @"C:\Users\Kennan\Desktop\Project1.rvt"; bs = Encoding.ASCII.GetBytes(sendStr); Console.WriteLine("Send message:" + sendStr); c.Send(bs, bs.Length, 0); Thread.Sleep(1000); //向服务器发送另一个文件路径 sendStr = @"C:\Users\Kennan\Desktop\Project2.rvt"; bs = Encoding.ASCII.GetBytes(sendStr); Console.WriteLine("Send message:" + sendStr); c.Send(bs, bs.Length, 0); Console.ReadLine(); c.Close(); } catch (ArgumentException e) { Console.WriteLine("argumentNullException:{0}", e); } catch (SocketException e) { Console.WriteLine("SocketException:{0}", e); } } }
所有组件都准备完毕了,接下来可以用Addin文件配置插件了,之后运行Revit,不用打开任何图纸,直接运行Client,Revit会依次打开这两个项目文件,运行的结果如下:
相关文章推荐
- 【笔记】第一个socket程序
- WCF常用绑定选择
- 图形渲染流水线
- JAVA Thread Dump 分析综述
- Java Web基础知识之Servlet(1):初识Servlet
- 得到某个数据库的路径 删除APP中所有的数据
- asp.net 操作Cookie以及优缺点
- Activity启动模式(lauchMode)
- mfc学习-程序自启动
- 后台处理
- centos6.5 烦人的字符集 locale 等等问题解决记录
- 设计模式—适配器模式
- Git远程操作详解
- 某种序列
- android:shape属性详解
- 在IIS7.5中ASP.NET调用cmd程序拒绝访问决绝方法小记
- 安装wamp错误解决
- UP UP UP!(dp)
- 如何实现三栏式布局
- JAVA实现判断回文数