# GoRpc2 **Repository Path**: rotion1991/GoRpc2 ## Basic Information - **Project Name**: GoRpc2 - **Description**: 基于CsGo实现的轻量级RPC框架,用于工业自动化上位机之间通信。 - **Primary Language**: C# - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 23 - **Created**: 2026-01-30 - **Last Updated**: 2026-01-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README 基于CsGo框架开发,用于上位机之间数据交互; 每个会话使用一个套接字; 单个会话可以任意双向并发调用; 调用参数支持大型内存数据,分片同发同收; ```C# static void Main(string[] args) { Rpc.ParamTuple.AssertName(); Rpc.Methods.AssertName(); work_service work = new work_service(); work_strand strand = new work_strand(work); generator.go(strand, async delegate () { socket_tcp.acceptor accep = new socket_tcp.acceptor(); if (!accep.bind("127.0.0.1", 2001)) { return; } socket_tcp socket = new socket_tcp(); if (!await accep.accept(socket)) { return; } accep.close(); generator.children sessions = new generator.children(); Rpc.Methods methods = new Rpc.Methods(); methods.Bind("Grab", async delegate (string returnImg) {//模拟一次远端图片采集 //申请一段内存,作为图片 IntPtr imgPtr = Marshal.AllocHGlobal(10 << 20); try { generator.lock_stop();//锁定采集时不能被中止打断(否则会话被Close后会立刻执行到finally释放内存,导致写入内存数据非法) await generator.send_task(delegate () {//写入内存数据 for (int i = 0; i < 10 << 20; i++) { Marshal.WriteByte(imgPtr + i, (byte)i); } }); generator.unlock_stop(); //无拷贝传入图片内存地址,Rpc.Session.Self表示为当前会话,因为可能有多个客户端在调用本方法 int img0 = Rpc.Session.Self.PushSend(imgPtr, 0, 10 << 20, chunk: 1 << 20); //采用Post传送,不用等待回复,Post过程只有在发送完成后或会话被Close才会跳出 await Rpc.Session.Self[returnImg].Post(img0); } finally { Marshal.FreeHGlobal(imgPtr); imgPtr = IntPtr.Zero; } }); Rpc.Session sess = new Rpc.Session(strand, socket, methods); sessions.go(async delegate () { byte[] bigData = new byte[10 << 20]; //无拷贝传入bigData大内存数据(同样支持IntPtr无拷贝传入), chunk=1MB sess.PushSend(bigData, chunk: 1 << 20); //定义一个临时远端回调,让远端调用,返回后失效 await sess["Callback"].Call(sess.PushCallback(async delegate (int a, int b) {//处理远端回调 await generator.sleep(1000); return a + b; })); }); sess.Start(); await sess.Join(); Console.WriteLine($"Server.Disconnected {sess.Code}"); await sessions.wait_all(); sess.Close(); }); generator.go(strand, async delegate () { await generator.sleep(100); socket_tcp socket = new socket_tcp(); if (await socket.connect("127.0.0.1", 2001)) { Rpc.Methods methods = new Rpc.Methods(); methods.Bind("Callback", async delegate (string callback) { //弹出大内存数据接收对象 Rpc.OverRecv[] recvs = Rpc.Session.PopRecv(); byte[] bigData = new byte[recvs[0].Length]; //同步接收大内存数据到bigData while (!recvs[0].Completed) { await recvs[0].Recv(bigData, (int)recvs[0].Offset, (int)(recvs[0].Length - recvs[0].Offset)); } if (recvs[0].Full) {//判断数据是否完整接收 } //调用当前会话下的远端的回调 Rpc.Result r1 = await Rpc.Session.Self[callback, 2000].Call(123, 456); Console.WriteLine($"Client.Callback {r1.result}"); }); Rpc.Session sess = new Rpc.Session(strand, socket, methods); generator.children grabChild = new generator.children(); grabChild.go(async delegate () { IntPtr imgPtr = IntPtr.Zero; try { //从远端采集一帧图像到本地 Rpc.Result grabRes = await sess["Grab"].Call(sess.PushCallback(async delegate (int img0) {//回调方式接收远端图片,默认要等待该回调函数执行完成后,Call才会返回(如果该函数没被远端调用,则不会等待) Rpc.OverRecv[] recvs = Rpc.Session.PopRecv(); if (null == recvs || recvs.Length != 1 || img0 != 0 || (int)recvs[img0].Length != 10 << 20) {//远端调用参数错误 return; } imgPtr = Marshal.AllocHGlobal((int)recvs[img0].Length); try { while (!recvs[img0].Completed) { await recvs[img0].Recv(imgPtr, recvs[img0].Offset, (int)(recvs[img0].Length - recvs[img0].Offset)); } if (!recvs[img0].Full) {//没接收完整,可能远端中途取消 Marshal.FreeHGlobal(imgPtr); imgPtr = IntPtr.Zero; } } catch (generator.stop_exception) { //如果接收途中本地被中止,则销毁内存 Marshal.FreeHGlobal(imgPtr); imgPtr = IntPtr.Zero; throw; } }, disposable: true)); if (!grabRes.Success) {//调用失败 Console.WriteLine("Grab Err"); return; } if (imgPtr != IntPtr.Zero) {//处理接收到的图片 Console.WriteLine("Grab OK"); } } finally { if (imgPtr != IntPtr.Zero) {//销毁接收到的图片 Marshal.FreeHGlobal(imgPtr); imgPtr = IntPtr.Zero; } } }); sess.Start(); await sess.Join(); Console.WriteLine($"Client.Disconnected {sess.Code}"); sess.Close(); } }); work.run(); Console.WriteLine("work done"); Console.ReadKey(); } ```