vnpy源码学习记录(4) ----------RPC网关

RPC启动

examples/client_server/server/run_server.py 为在RPC服务在本项目中的使用方法

1.1 添加RPC应用(实例化)

1.1.1 预处理引擎

  1. 启动项目时添加RPC应用
  2. 获取RPC应用实例,并添加RPC引擎:
  3. 实例化引擎:

1.1.2 实例化服务

首先加载配置信息,然后初始化服务

  1. 加载配置信息:self.load_setting() 配置文件配置客户端的地址,因为这里是客户端,因此适配所有的ip: rep_address表示可请求地址;pub_address表示可订阅地址
  2. 初始化服务: 先实例化RPC服务,再初始化(注册)方法 a) 实例化RPC服务 继承了RpcServer类:RpcServer类是RPC服务器运行函数,运行在服务器上,里面初始化了一些变量,并定义了基本函数,如:start()、run()、stop()等 b) 注册方法 注册一些客户端会使用的方法

1.2 启动RPC服务

开启RPC服务: 先获取到rpc引擎的实例,再调用start方法开启服务 start方法调用了RpcServer类的start()方法启动RPC服务: 到此VNPY中的RPC服务启动完成

2. RPC服务应用

rpc服务可以通过广播/订阅的方式向客户端推送数据,也可以通过客户端调用服务端注册的方法返回数据。

2.1 广播/订阅

RPC服务广播,只需要调用服务中def publish(self, topic: str, data: Any):即可。topic为推送的主题,data为推送的数据 然后客户端只需要通过tc.subscribe_topic("")即可订阅服务器推送的数据。参数为订阅的主题,“”表示订阅所有主题。只有配置了的地址(配置文件中的sub_address)可使用订阅功能。**注意:截止当前的测试(2019-08-05),向subscribe_topic传递相应的主题参数获取不到广播的数据,只有使用““””订阅全部主题才可收取到信息。**现已解决。

在vnpy中,CTP接口接收到的数据就可以通过广播的形式推送,然后客户端订阅。CTP接收行情数据的接口为onRtnDepthMarketData

2.2 方法请求

可以通过在服务端注册方法,然后客户端远程调用。 比如客户端查询服务端的数据库中的数据,使用RPC服务的话,在服务端编写好查询代码: 然后在实例化服务类的时候注册该方法 目前vnpy中注册了的方法见vnpy/app/rpc_service/ engine.py中init_server() 客户端使用: 直接调用该方法即可。只有配置了的地址(配置文件中的req_address)可使用请求功能。

3. 客户端使用

3.1 启动客户端

req_address = "tcp://ip:port"  #客户端请求地址
sub_address = "tcp://ip:port"  #客户端订阅地址
tc = TestClient()  # 实例化客户端类
tc.start(req_address, sub_address)  # 启动客户端服务

3.2 接收说明

不管是通过订阅方式获取数据还是请求调用方法方式获取数据,如果返回的是一个自定义类的对象,如广播的行情数据TickData或请求查询的合约信息ContractData等,都需要在客户端有响应的类,且路径要与服务端相同。使用到自定义的类也需要同样的操作,如Exchange。

订阅指定主题的解决方法:

def subscribe_topic(self, topic: str):
        """
        Subscribe data
        订阅特定主体的广播数据
        topic = 订阅所有主题
        """
        if topic != "":
            self.topic.append(topic)
        if topic == "" or topic == :
            self.topic.append("all")
        self.__socket_sub.setsockopt_string(zmq.SUBSCRIBE, "")
def callback(self, topic, data):
        """
        Realize callable function
        """
        if "all" in self.topic:
            print(f"client received topic:{topic}, data:{data}")
        elif topic in self.topic:
            print(f"client received topic:{topic}, data:{data}")
经验分享 程序员 微信小程序 职场和发展