Pomelium——.NET Core下轻量级RPC框架

Published on 1/31/2017 6:20:14 AM

Background

最近在和朋友开发一款基于Unity 3D的游戏,技术栈选择了.NET Core写服务端、Unity3D写客户端,通过某种手段,已经实现了Unity对C# 6.0的支持,因此可以在Unity里愉快的使用异步函数等功能了。那么现在就要确定通讯协议了,首先虽然Unity对C# 6.0支持了,但是并不代表对netfx有完整的支持,因此无法使用SignalR,TCP协议又显得太过苍白,WCF又太heavy,所以决定造一发轮子。

Pomelium

Pomelium基于TCP协议开发,包内容为前4字节表示正文长度,正文则是一个json字符串。通过简单的协议进行服务端 call 客户端及客户端 call 服务端的操作。

此外,Pomelium还提供了类似WEB开发中的Session功能、Group机制等,开发者可以使用Pomelium进行更加灵活的开发。

Pomelium支持通过Microsoft.Extensions.Cache.Distributed.IDistrbutedCache来Scale out,构建分布式Pomelium服务器集群。支持开发者进行跨服务器的客户端方法调用等。

Getting Started

① 首先向服务端项目中添加Pomelo.Net.Pomelium.Server的引用。

  "dependencies": {
    "Pomelo.Net.Pomelium.Server": "1.1.0-*"
  }

② 调用PomeliumServer的静态方法.CreateServer(),或通过DI,向ServiceCollection中添加PomeliumServer再Inject:

    public class Program
    {
        public static void Main(string[] args)
        {
            var server = PomeliumServer.CreateServer();
            server.Start("127.0.0.1", 6000);
            Console.Read();
        }
    }

③ 编写一个Hub:

    public class TestHub : PomeliumHub
    {
        public int TestMethod(int a, int b)
        {
            return a + b;
        }
    }

④ 创建客户端程序,并引用Pomelo.Net.Pomelium.Client

⑤ 实例化一个PomeliumClient,并尝试调用客户端方法:

        public static void Main(string[] args)
        {
            Test().Wait();
            Console.Read();
        }

        public static async Task Test()
        {
            var client = new PomeliumClient("127.0.0.1", 6000);
            await client.ConnectAsync();
            var ret = await client.Server["Test"].TestMethod(1, 1);
            Console.WriteLine(ret);
        }

⑥ 调试运行,客户端输出了2,调用远程方法成功:

file

More

服务端调用客户端

调用PomeliumServer对象的Client方法可通过Session ID获取到客户端,返回的对象是一个DynamicObject,可直接调用客户端方法。

await pomeliumServer.Client("B6F2FA76-B1A5-4634-86FF-602003418215").Print("Hello World");

客户端则需要定义一个类,并继承PomeliumClient,在该类中生命void Print(string)方法以供服务端调用。

Session功能

Session功能需在Hub类中使用,通过调用HubContext中的Session来设置或获取当前客户端的Session数据。

    public class TestHub : PomeliumHub
    {
        public bool SignIn(string username, string password)
        {
            // TODO: 判断用户名密码

            Context.Session["ADMIN"] = username;
            return true;
        }
    }

Service Provider

file

HubContext中还提供了Resolver成员,Resolver是IServiceProvider对象,开发者可通过Resolver来Inject其他服务。

分享到:

Comments

使用微信扫码