Facebook最新Libra币开发指南---接口服务器开发

7 篇文章 0 订阅
7 篇文章 0 订阅

在Libra Core中,官方提供了一个命令行工具,可以实现创建账户、挖矿和转账等基本操作,但是没有提供Restful接口,使我们想要开发的应用系统,将区块链逻辑移植到Libra Testnet上去。在本篇博文中,我们将利用Rust语言,将官方的命令行接口,改造成RESTful接口。由于我们只是临时改造,相信官方的RESTful接口很快就会出现,因此我们在这里仅使用最简实现,实现一个单线程的Web服务器来完成这一工作。

最简Web服务器

我们需要一个最简单的Web服务器,来接收客户端的请求,然后调用系统功能完成Libra Core中相关的区块链操作操作。我们先开发一个独立的应用,实现最基本的Web服务器功能,然后再将其集成到Libra Core的命令行工具中。
我们首先通过如下命令创建一个新工程:

cargo new libra_server --bin

我们创建一个名称为libra_server的工程,其为可执行文件形式。上面的命令会在当前目录下创建libra_server目录,并创建libra_server/src/main.rs文件,这个文件就是整个项目的主程序文件。
下面我们创建一个Hello World的Web服务器:

use std::io::prelude::*;
use std::net::TcpStream;
use std::net::TcpListener;

fn main() {
    start_server();
}

fn start_server() {
    println!("Libra Server v0.0.2 Starting up ...");
    let listener = TcpListener::bind("127.0.0.1:7878").unwrap();
    for stream in listener.incoming() {
        let stream = stream.unwrap();
        handle_connection(stream);
    }
}

fn handle_connection(mut stream: TcpStream) {
    let mut buffer = [0; 512];
    stream.read(&mut buffer).unwrap();
    println!("Request: {}", String::from_utf8_lossy(&buffer[..]));
    let contents = "Hello World!";
    let response = format!("HTTP/1.1 200 OK\r\n\r\n{}", contents);
    stream.write(response.as_bytes()).unwrap();
    stream.flush().unwrap();
}

我们直接编译运行程序:

cargo run

运行结果如下所示:
在这里插入图片描述
使用浏览器访问如下地址:http://127.0.0.1:7878/account_list/88 ,会显示Hello World信息,这就说明我们的Web服务器可以正常运行了。
下面我们在handle_connection方法中,求出cmd参数的值,根据cmd调用不同的处理函数,在这些函数中调用Libra Core的区块链服务,解析区块链服务的返回结果,最后再以Http响应的形式返回给客户端。
我们要做的第一件事就是求出QueryString,代码如下所示:

/**
* 获取请求中的Query String,规定参数以?cmd=开头
* @version v0.0.1 闫涛 2019.06.23
*/
fn get_query_string(request: &str) -> String {
    let pos = request.find("?cmd=");
    if pos <= Some(0) {
        return "Has no parameters in request".to_string();
    }
    let end_pos = request.find(" HTTP/1.1");
    return (&request[(pos.unwrap()+1)..end_pos.unwrap()]).to_string();
}

在这段代码中,我们首先找到QueryString开始位置,如果没找到则返回出错信息。接着我们找到结束信息,最后我们截取出子字符串作为QueryString返回。
在得到QueryString之后,我们需要找出参数cmd的值,这样我们才能根据cmd参数的值调用对应的命令处理函数,如下所示:

/**
* 获取请求cmd参数值
* @version v0.0.1 闫涛 2019.06.23
*/
fn get_cmd_param(query_string: String) -> String {
    let params: Vec<_> = query_string.split("&").collect();
    for param in params.iter() {
        println!("item: {}!", param);
        if param.find("cmd=") >= Some(0) {
            let cmd = &param[4..];
            return cmd.to_string();
        }
    }
    return "".to_string();
}

接下来我们定义生成账户的命令处理函数,如下所示:

/**
* 生成账户命令处理函数
* @version v0.0.1 闫涛 2019.06.23
*/
fn handle_account_create(_params: Vec<&str>) -> String {
    println!("生成新账户!");
    let rst: String = String::from("create account: 0");
    return rst;
}

实际中,这个函数需要调用Libra Core来创建账户,我们在这里先简单的返回一个字符串,在下一篇文章中我们再来具体讲怎么调用Libra Core服务以及解析响应结果。
接下来我们看handle_connection方法,这时这个方法的逻辑就变为接到一个请求后,首先得到QueryString,然后从QueryString得到cmd参数,然后根据cmd的值调用对应的命令处理函数,如下所示:

fn handle_connection(mut stream: TcpStream) {
    let mut contents: String = String::from("Hello World!");
    let mut buffer = [0; 1024];
    // 获取请求信息
    stream.read(&mut buffer).unwrap();
    println!("Request: {}", String::from_utf8_lossy(&buffer[..]));
    let request = String::from_utf8_lossy(&buffer[..]);
    // 不处理请求网站图标请求
    if request.find("GET /favicon.ico HTTP/1.1") >= Some(0) {
        return ;
    }
    // 请出请求中的query string
    let query_string = &get_query_string(&request);
    println!("query_string:{}", query_string);
    let cmd = get_cmd_param(query_string.to_string());
    println!("接收到命令:cmd={}!", cmd);
    let params: Vec<_> = query_string.split("&").collect();
    if cmd.find("account_create")>=Some(0) {
        contents = handle_account_create(params);
    } else if cmd.find("account_list")>=Some(0) {
        contents = handle_account_list(params);
    }
    let response = format!("HTTP/1.1 200 OK\r\n\r\n{}", contents);
    stream.write(response.as_bytes()).unwrap();
    stream.flush().unwrap();
}

我们可以按照这种方式,将下列命令先以占位符的形式写出来,我在这里就不重复贴代码了,在下一篇文章中,我们将对每个命令,学习怎样向Libra Core发送命令,以及怎样解析命令的返回结果。

  • 39
    点赞
  • 86
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
### 回答1: Libra R-CNN是Facebook AI Research团队于2019年提出的一种目标检测算法,它采用了一种新的思路——将目标检测过程分为两个阶段:先使用高效的RPN网络生成候选框,再使用分类器对候选框进行分类和回归。这种方法可以大大提高检测效率,同时保持较高的精度。与传统的Faster R-CNN相比,Libra R-CNN的检测速度快了近3倍,同时保持了相当的精度。 ### 回答2: Libra R-CNN是由Facebook AI Research团队在2019年提出的一种目标检测算法。目标检测是计算机视觉中的一个重要任务,旨在识别和定位图像中的不同目标。 Libra R-CNN的设计目标是解决目标检测中存在的两个挑战:不平衡的目标类别分布和多尺度目标的检测问题。在目标类别分布上,一些类别的目标在数据集中往往是非常罕见的,这导致传统的目标检测算法在罕见类别上的性能较差。而在多尺度目标的检测上,由于图像中的目标可能具有不同的尺度,传统的目标检测算法在检测小目标和大目标时往往表现不佳。 Libra R-CNN通过引入新的损失函数和网络结构来解决这两个问题。其中,采用了一种新的正负样本选择策略来平衡不同目标类别的分布,使得模型能够更好地处理罕见类别的目标。此外,通过引入一个多尺度特征融合模块,Libra R-CNN能够有效地处理不同尺度的目标,提高目标检测的性能。 实验证明,Libra R-CNN在多个目标检测数据集上取得了很好的性能表现,相较于其他目标检测算法具有更好的检测准确性和鲁棒性。该算法在推动目标检测技术的发展上具有重要的意义,为解决目标检测中的挑战提供了新的思路和方法。 总之,Libra R-CNN是一种解决目标检测中不平衡目标类别分布和多尺度目标检测问题的算法,通过引入新的损失函数和网络结构,取得了很好的性能表现。它对于推动目标检测技术的发展具有重要的意义。 ### 回答3: Libra R-CNN是一种基于目标检测和实例分割的深度学习模型算法。它被设计用于解决目标检测中存在的物体不平衡问题,即训练样本中不同类别的物体数量差异过大。通常,在目标检测任务中,一些常见的物体类别(如人、车)的样本数量会远远超过其他类别,这会导致模型过度关注于此类常见类别而忽略其他类别。而Libra R-CNN就是为了解决这个问题而提出的。 Libra R-CNN的核心思想是通过引入一种新的调节因子,对损失函数进行重新定义,从而有效平衡不同类别的物体样本的权重。这个调节因子综合考虑了每个类别的物体例子在整个训练集中出现的频率,以及目标检测任务中不同类别之间的难易程度。通过对不同类别样本的权重进行调整,Libra R-CNN能够更加均衡地对待训练集中的不同类别物体,提高模型对少样本类别的检测能力。 此外,Libra R-CNN还引入了一种新的网络结构,叫做Libra引导采样(Libra RoI Sampling)。这个结构能够根据样本的难易程度,自适应地调整样本的采样比例,让模型更加关注难以检测的类别。通过这种方式,Libra R-CNN在目标检测中取得了较好的性能。 综上所述,Libra R-CNN是一种通过引入调节因子和采样策略来解决目标检测中物体不平衡问题的算法模型。它的提出有效地解决了训练样本中不同类别物体数量差异过大的问题,提高了对少样本类别的检测能力,并在目标检测任务中取得了较好的性能。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值