Git Product home page Git Product logo

xrpc's Introduction

XRPC

dotnet high performance remote interface invoke(RPC) communication components,implemente millions RPS remote interface method calls.

samples

https://github.com/IKende/BeetleX-Samples

Install Packet

Install-Package BeetleX.XRPC -Version x

Server

    class Program
    {
        static void Main(string[] args)
        {
            var builder = new HostBuilder()
            .ConfigureServices((hostContext, services) =>
            {
                services.UseXRPC(s =>
                {
                    s.ServerOptions.LogLevel = BeetleX.EventArgs.LogType.Trace;
                    s.ServerOptions.DefaultListen.Port = 9090;
                    s.RPCOptions.ParameterFormater = new JsonPacket();//default messagepack
                },
                    typeof(Program).Assembly);
            });
            builder.Build().Run();
        }
    }

Server controller

    public interface IHello
    {
        Task<string> Hello(string name);
    }

    [Service(typeof(IHello))]
    public class HelloImpl : IHello
    {
        public Task<string> Hello(string name)
        {
            return $"hello {name} {DateTime.Now}".ToTask();
        }
    }

Client

            client = new XRPCClient("localhost", 9090);
            client.Options.ParameterFormater = new JsonPacket();//default messagepack
            hello = client.Create<IHello>();
            while(true)
            {
                Console.Write("Enter you name:");
                var name = Console.ReadLine();
                var task = hello.Hello(name);
                task.Wait();
                Console.WriteLine(task.Result);
            }

xrpc's People

Contributors

beetlex-io avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

xrpc's Issues

客户端无法主动彻底断开连接

服务器端加了RPCDisconnect事件处理

在服务器端业务方法Exit里服务器断开连接
token.Session.Socket.Close();
server.Server.CloseSession(token.Session);

在客户端
foreach (var item in client.Clients)
{
item.TcpClient.DisConnect();
}
这些断开动作,都能触发RPCDisconnect,按理说连接应该断开了,但在关闭客户端时,还会再触发一次RPCDisconnect,说明连接之前没有彻底断开。

添加委托订阅功能

主要实现多个客户端可以同时订阅服务端的委托,当客户端订阅后服务端在调用委托时都会广播到订阅的客户端。

Session信息丢失

在业务登录的方法里,
public Task Login(string name, string password)
{
//测试不检查用户名密码
var event_token = XRPCServer.EventToken;
event_token.Session.Name = name; //对登录成功的把用户名写到session里
IDataComClient client = event_token.Server.GetClient(event_token.Session);
OnlineClients[name] = client;
Console.WriteLine(name + " login,session="+event_token.Session);
return Task.FromResult("ok");
}

在服务器的RPCDisconnect里
server.RPCDisconnect += (s, e) => {
var username = e.Session.Name;
Console.WriteLine(username + " disconnected");
if (username != null)
{
IDataComClient client = null;
OnlineClients.TryRemove(username, out client);
}
};

现在测试客户端连接一段长时间后会出现打印用户名为空的“disconnected”。如果客户端短时间连接后断开,用户名不会丢失。可能说明client的Tcp连接发生过自动重连后Session信息丢失的情况。

autofac 依赖注入

我模仿autofac fasthttpapi 依赖注入
image

image
注入也成功了。但是控制台报错。程序好像只走了空的构造。。
image
我注册了这个事件。但跟踪后发现。他一直为null

Register HelloWorldService error No parameterless constructor defined for this object.@ at System.RuntimeTypeHandle.CreateInsta
nce(RuntimeType type, Boolean publicOnly, Boolean wrapExceptions, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor)
at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean wrapExceptions, Boolean skipCheckThis, Boolean fillCache)
at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, Boolean wrapExceptions)
at System.Activator.CreateInstance(Type type, Boolean nonPublic, Boolean wrapExceptions)
at System.Activator.CreateInstance(Type type, Boolean nonPublic)
at System.Activator.CreateInstance(Type type)
at EventNext.EventCenter.CreateController(Type type)
at EventNext.EventCenter.Register(Assembly[] assemblies)

依赖注入遇见了几个问题

1 由于 ServerOptions RPCOptions 都是private set 外层很难整体注入 只能通过改变其属性

image

2
image
现在基于这样的方式。感觉好别扭

如何对连接后并使用帐号登录的客户端进行标记,用于监护平台上显示客户端的在线情况?

客户端连接后调用GetToken进行身份验证,成功后可以对当前TCP Session连接进行标记身份标识,并通知第三方当前设备上线,如果TCP Session断开连接时可以通知第三方当前设备下线。

认证接口代码

public interface IAuthService
    {
        /// <summary>
        /// 登录获取Token
        /// </summary>
        /// <param name="deviceID"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        Task<string> GetToken(string deviceID, string password);
    }

服务端实现:

[Service(typeof(IAuthService))]
    public class AuthService : IAuthService
    {

        public Task<string> GetToken(string deviceID, string password)
        {
            //写验证并生成Token的业务逻辑
            //……

            //标记通道
            //???

            return "admin".ToTask();
        }
    }

关于Xrpc的XRPCServer.EventToken设计解耦的问题

现有的是通过唯一的静态属性XRPCServer.EventToken 去获取当前的连接信息的。不够优雅~~
我有个思路,你看下:

using System;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    interface IMyInterFace
    {
        Task HelloWorld(string s);
    }

    //服务端这么设计:
    //MyInterFaceImpl继承IMyInterFace和“当前连接会话”的类(XRPCEventToken)
    //这个MyInterFaceImpl具体的对象也是你Xrpc底层反射创建的,创建好后,先转成XRPCEventToken 赋值好当前的“链接信息”等信息
    //最后调用MyInterFaceImpl实例的HelloWorld方法
    //这样解决了XRPCServer.EventToken的静态属性的问题。
    class MyInterFaceImpl :  XRPCEventToken,IMyInterFace
    {
        public Task HelloWorld(string s)
        {
            var 当前的Session = this.Session;//这个字段来自XRPCEventToken
            var 当前的Server = this.Server;
            var 当前的Request = this.Request;
            //...业务操作。
            return Task.CompletedTask;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
        }
    }
}

增加内部ping/pong机制

在广域网上,仅依赖于tcp自身的探测机制很容易导致超时无法有效重置,加入可选逻辑ping/pong进行一个自我探测并进行重置连接。

Support security mode

Support security mode, in secure mode, the client must configure the username and password.

1.0.3.4使用默认的MsgPacket向客户端返回实体信息报错

nuget中1.0.3.4版本,使用默认的MsgPacket向客户端返回实体信息报错,指定JsonPacket后,问题解决,看日志像是实体类的内容还是被JSON序列华后没处理"号。

报错内容:

[20:50:02] [Debug] [10000004][::ffff:127.0.0.1]:54703 send event data:{"ID":10000004,"EventPath":null,"Properties":{},"Data":[{"ReportID":2,"UserID":"123456","DeviceID":"4569356885","ReportDate":"2020-09-13T20:50:02.4845313+08:00","HeartRate":98.0,"BreatheRate":15.0,"Remark":null}],"EventError":200,"ResponseTime":0.0,"Token":null}
[20:50:02] [Error] Next queue process EventNext.EventActionHandlerContext error Write protocol data error Failed to serialize BCGChair.Model.ReportInfo value.@ at BeetleX.XRPC.RPCPacket.Write(Options rpcOption, PipeStream stream)
at BeetleX.XRPC.Packets.ServerPacket.OnEncode(ISession session, Object data, Stream stream)
at BeetleX.XRPC.Packets.ServerPacket.Encode(Object data, ISession session, Stream stream)
at BeetleX.TcpSession.WriterData(Object data, Stream stream)
at BeetleX.TcpSession.ProcessSendMessages()
at BeetleX.TcpSession.Send(Object data)
at BeetleX.XRPC.XRPCServer.OnResponse(RPCPacket request, RPCPacket response)
at BeetleX.XRPC.XRPCServer.EventCompleted.Completed(IEventOutput data)
at EventNext.EventActionHandlerContext.Execute()
at EventNext.NextQueue.OnStart(Object state)

传输的实体类结构

public class ReportInfo

 {

        public int ReportID { set; get; }

        public string UserID { set; get; }

        public string DeviceID { set; get; }

        public DateTime ReportDate { set; get; }

        public double HeartRate { set; get; }

        public double BreatheRate { set; get; }

        public string Remark { set; get; }

}

移除 NewtonSoft.Json 依赖项。

既然XRPC 默认是 message-pack那么 NewtonSoft.Json 那个依赖 能不能从默认依赖中删除。

目的:减少发布程序的依赖项。

序列化的问题

当客户端和服务端数据交互的类 的特性不一致 就会RPC调用失败:
这句话可能说的不太明白,请看代码:
服务端:

public class student
{
  public int a{get;set;}
  public int b{get;set;}
}
public interface IStudentService
{
     AddStudent(student s);
}

客户端

[JsonObject] //添加特性
public class student
{
[JsonProperty]
  public int a{get;set;}
[JsonProperty]
  public int b{get;set;}
}
.....

student stu= DeserializeObject(file.readtext());

Client.AddStudent(stu);//调用失败!!!!!

在客户端,上述代码中的student类即作为json的存储类,又作为和server交互的数据类,上述写法会调用失败,除非我把student的特性去掉。现阶段我的解决方案是这么写的:

[JsonObject] //添加特性
public class  JsonStudent
{
[JsonProperty]
  public int a{get;set;}
[JsonProperty]
  public int b{get;set;}
}
public class student
{
  public int a{get;set;}
  public int b{get;set;}
}
JsonStudent jsonstu= DeserializeObject(file.readtext());
student rpc_stu=new stduent();
rpc_stu.a=jsonstu.a;
rpc_stu.b=jsonstu.b;

Client.AddStudent(rpc_stu);//调用成功!!!

可见,客户端的类和服务器的类必须一致才可以,在这个例子中束缚了写法,必须定义两个类,我认为客户端和服务端的数据交互 传递的有效数据是 各个类中的具体字段、属性等等, 特性这个应该被忽略掉,这样我最开始的第一种写法就可以了,就不用重新定义类了

一些小问题

1.有没有QQ群?
2.我在测试,大文件传输,5MB左右,提示 buffer decoding error! @the message to long! 请问有没有这样稍微大一点文件传输的例子? 多谢。

` Hello World!
[10:12:57] [Info] Register IMyService->MyService@SetValue to /IMyService/SetValue[ThreadType:None|UniqueID:]
[10:12:57] [Info] Register IMyService->MyService@GetValue to /IMyService/GetValue[ThreadType:None|UniqueID:]
[10:12:57] [Info] Register IMyService->MyService@SetBytes to /IMyService/SetBytes[ThreadType:None|UniqueID:]
[10:12:57] [Info] Register IMyService->MyService@GetBytes to /IMyService/GetBytes[ThreadType:None|UniqueID:]
[10:12:58] [Info]


BeetleX xrpc service framework
Copyright ? ikende.com 2019-2020 email:[email protected]
ServerGC [False]
BeetleX Version [1.4.8.0]
XRPC Version [0.8.2.3]

Listen :9090 [SSL:False] [Status:success]


[10:13:06] [Error] session [::ffff:127.0.0.1]:59436@1 error [::ffff:127.0.0.1]:59436 session buffer decoding error! @the message to long!
at BeetleX.XRPC.RPCPacket.Read(Options rpcOption, PipeStream stream)
at BeetleX.XRPC.Packets.ServerPacket.Decode(ISession session, Stream stream)
at BeetleX.TcpServer.SessionReceive(SessionReceiveEventArgs e)

`

双向调用的讨论

关于双向调用,目前现有的例子,服务端和客户端耦合太高,并且代码有些繁琐,我觉得服务端完全可以把客户端的那部分代码拿过来,类似于这么写:
场景:假定服务器发生了一些事情要通知客户端:
服务器端:

var delInstance= xrpcserver.Create<MyDelegateType>(
);

之后,只要想通知客户端,那么就可以这么写delInstance?.Invoke(...)
当然如果客户端不想监听这个事件的话,也没关系,完全自由的。

客户端:

xrpcclient.AddDelegate<MyDelegateType>(方法或者代理等)。

我这种写法也是模仿您现有的写法,不知道这
样能不能实现。大佬,您觉得呢

依赖注入

有内置的IServiceCollection吗?或者我该怎么让Service的构造函数支持依赖注入呢?

客户端缺少销毁或主动断连的方法

client = new XRPCClient("localhost", 9090);
client.Options.ParameterFormater = new JsonPacket();//default messagepack
helloSession = client.Create();

其中client和helloSession都没有Close和Dispose

增加连接成功事件

增加连接成功事件,主要是方便在断线重连后可行自发起一个消息行为。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.