ballerina 的grpc 开发模型,对于开发者来说简单了好多,不是schema first 的方式,而是我们
只要编写简单的ballerina service 就可以了,proto 文件是自动帮我们生成的,同时我们用这个
文件方便的生成各种客户端的代码

项目参考 https://ballerina.io/learn/by-guide/grpc-service/

项目准备

  • 项目结构
├── Ballerina.toml
├── grpc_service
│ └── order_mgt_service.bal
  • grpc 代码

    可以看出就是普通的ballerina service

import ballerina/grpc;

// gRPC service endpoint definition.
endpoint grpc:Listener listener {
host:"localhost",
port:9090
}; // Order management is done using an in memory map.
// Add sample orders to the 'orderMap' at startup.
map<orderInfo> ordersMap; // Type definition for an order.
type orderInfo record {
string id;
string name;
string description;
}; // gRPC service.
@grpc:ServiceConfig
service orderMgt bind listener { // gRPC method to find an order.
findOrder(endpoint caller, string orderId) {
string payload;
// Find the requested order from the map.
if (ordersMap.hasKey(orderId)) {
json orderDetails = check <json>ordersMap[orderId];
payload = orderDetails.toString();
} else {
payload = "Order : '" + orderId + "' cannot be found.";
} // Send response to the caller.
_ = caller->send(payload);
_ = caller->complete();
} // gRPC method to create a new Order.
addOrder(endpoint caller, orderInfo orderReq) {
// Add the new order to the map.
string orderId = orderReq.id;
ordersMap[orderReq.id] = orderReq;
// Create a response message.
string payload = "Status : Order created; OrderID : " + orderId; // Send a response to the caller.
_ = caller->send(payload);
_ = caller->complete();
} // gRPC method to update an existing Order.
updateOrder(endpoint caller, orderInfo updatedOrder) {
string payload;
// Find the order that needs to be updated.
string orderId = updatedOrder.id;
if (ordersMap.hasKey(orderId)) {
// Update the existing order.
ordersMap[orderId] = updatedOrder;
payload = "Order : '" + orderId + "' updated.";
} else {
payload = "Order : '" + orderId + "' cannot be found.";
} // Send a response to the caller.
_ = caller->send(payload);
_ = caller->complete();
} // gRPC method to delete an existing Order.
cancelOrder(endpoint caller, string orderId) {
string payload;
if (ordersMap.hasKey(orderId)) {
// Remove the requested order from the map.
_ = ordersMap.remove(orderId);
payload = "Order : '" + orderId + "' removed.";
} else {
payload = "Order : '" + orderId + "' cannot be found.";
} // Send a response to the caller.
_ = caller->send(payload);
_ = caller->complete();
}
}

生成proto&&客户端代码

  • proto生成
ballerina build grpc_service/


  • 客户端代码
ballerina grpc --input target/grpc/orderMgt.proto --output grpc_client


  • 修改生成的客户端代码
import ballerina/log;
import ballerina/grpc; // This is client implementation for unary blocking scenario
public function main(string... args) {
// Client endpoint configuration
endpoint orderMgtBlockingClient orderMgtBlockingEp {
url:"http://localhost:9090"
}; // Create an order
log:printInfo("-----------------------Create a new order-----------------------");
orderInfo orderReq = {id:"100500", name:"XYZ", description:"Sample order."};
var addResponse = orderMgtBlockingEp->addOrder(orderReq);
match addResponse {
(string, grpc:Headers) payload => {
string result;
grpc:Headers resHeaders;
(result, resHeaders) = payload;
log:printInfo("Response - " + result + "\n");
}
error err => {
log:printError("Error from Connector: " + err.message + "\n");
}
} // Update an order
log:printInfo("--------------------Update an existing order--------------------");
orderInfo updateReq = {id:"100500", name:"XYZ", description:"Updated."};
var updateResponse = orderMgtBlockingEp->updateOrder(updateReq);
match updateResponse {
(string, grpc:Headers) payload => {
string result;
grpc:Headers resHeaders;
(result, resHeaders) = payload;
log:printInfo("Response - " + result + "\n");
}
error err => {
log:printError("Error from Connector: " + err.message + "\n");
}
} // Find an order
log:printInfo("---------------------Find an existing order---------------------");
var findResponse = orderMgtBlockingEp->findOrder("100500");
match findResponse {
(string, grpc:Headers) payload => {
string result;
grpc:Headers resHeaders;
(result, resHeaders) = payload;
log:printInfo("Response - " + result + "\n");
}
error err => {
log:printError("Error from Connector: " + err.message + "\n");
}
} // Cancel an order
log:printInfo("-------------------------Cancel an order------------------------");
var cancelResponse = orderMgtBlockingEp->cancelOrder("100500");
match cancelResponse {
(string, grpc:Headers) payload => {
string result;
grpc:Headers resHeaders;
(result, resHeaders) = payload;
log:printInfo("Response - " + result + "\n");
}
error err => {
log:printError("Error from Connector: " + err.message + "\n");
}
}
}

运行&&测试

  • 运行server
ballerina run grpc_service

  • client 调用
ballerina run grpc_client

参考资料

https://ballerina.io/learn/by-guide/grpc-service/
https://github.com/ballerina-guides/grpc-service

 
 
 
 

ballerina 学习二十八 快速grpc 服务开发的更多相关文章

  1. ballerina 学习二十九 数据库操作

    ballerina 数据操作也是比较方便的,官方也我们提供了数据操作的抽象,但是我们还是依赖数据库驱动的. 数据库驱动还是jdbc模式的 项目准备 项目结构 ├── mysql_demo │ ├── ...

  2. Java开发学习(二十八)----拦截器(Interceptor)详细解析

    一.拦截器概念 讲解拦截器的概念之前,我们先看一张图: (1)浏览器发送一个请求会先到Tomcat的web服务器 (2)Tomcat服务器接收到请求以后,会去判断请求的是静态资源还是动态资源 (3)如 ...

  3. ballerina 学习二十二 弹性服务

    主要包含断路器模式,负载均衡模式,故障转移,重试 Circuit Breaker 参考代码 import ballerina/http; import ballerina/log; import ba ...

  4. Python学习二十八周(vue.js)

    一.指令 1.一个例子简单实用vue: 下载vue.js(这里实用1.0.21版本) 编写html代码: <!DOCTYPE html> <html lang="en&qu ...

  5. ballerina 学习二十六 项目docker 部署&& 运行(二)

    ballerina 从发布,到现在官方文档的更新也是很给力的,同时也有好多改进,越来越好用了 可以参考官方文档 https://ballerina.io/learn/by-guide/restful- ...

  6. ballerina 学习二十五 项目docker 部署&& 运行

    ballerina 官方提供了docker 的runtime,还是比较方便的 基本项目创建 使用cli创建项目 按照提示操作就行 ballerina init -i 项目结构 添加了dockerfil ...

  7. ballerina 学习二十四 监控ballerina

    ballerina 服务的监控还是比较方便的,以及集成了Prometheus Grafana Jaeger Elastic Stack 监控服务监控的集成 主要包含以下几个步骤 a. 安装docker ...

  8. JavaWeb学习 (二十八)————文件上传和下载

    在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用 ...

  9. ballerina 学习二十 http/https

    提供http && https server && client 访问功能 client endpoint 说白了就是http client 参考代码 import b ...

随机推荐

  1. SQL 基础学习(2) Joining 和function , 作业没有做,需要看百宝箱。NOsql的概念

    SQL 基础学习(2) Joining 可以同时关联(joining)多张表进行复杂的查询. 相比于用Rails捞出数据再用Ruby进行过滤组合,使用SQL更加高效,节能. 以下是 users has ...

  2. codeforces 930b//Game with String// Codeforces Round #468 (Div. 1)

    题意:一个串,右循环移位后,告诉你第一个字母,还能告诉你一个,问你能确定移位后的串的概率. 用map记录每个字母出现的位置.对于每个字母,用arr[j][k]记录它的所有出现位置的后j位是字母k的个数 ...

  3. android--------阿里 Sophix移动热修复

    移动热修复(Mobile Hotfix)是阿里云提供的全平台App热修复服务方案.产品基于阿里巴巴首创hotpatch技术,提供最细粒度热修复能力,让您无需等待实时修复应用线上问题. 移动热修复提供的 ...

  4. H5基础知识(一)

    一.概述 HTML5  是html4.0 升级版 结构 Html5 .样式 css3 .行为: API  都有所增强 HTML5并不仅仅只是做为HTML标记语言的一个最新版本,更重要的是它制定了Web ...

  5. sql表联接

    1.join: 表:erp_orders和erp_orders_products SELECT * FROM erp_orders_products AS products, erp_orders A ...

  6. UVA-11584 Partitioning by Palindromes (简单线性DP)

    题目大意:给一个全是小写字母的字符串,判断最少可分为几个回文子序列.如:“aaadbccb” 最少能分为 “aaa” “d” “bccb” 共三个回文子序列,又如 “aaa” 最少能分为 1 个回文子 ...

  7. Oracle 11g 物理Dataguard日常操作维护(二)

    Oracle 11g 物理Dataguard日常操作维护(二) 2017年8月25日 14:34 3.3 3.3.1 查看备库进程状态 SYS(125_7)@fpyj123> select pr ...

  8. 不能将Lnode * 类型的值分配到Lnode * 类型的实体

    typedef struct { int data; struct Lnode *next;}Lnode,*LinkList; 这个地方有点问题,因为结构体定义中出现了struct Lnode但 Ln ...

  9. CentOS7系统更换YUM Repo源

    CentOS7系统更换YUM Repo源 备份原镜像 sudo mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.re ...

  10. 管道pipe与dup结合使用

    前面的例子中,子进程可以直接共享父进程的文件描述符.但是如果子进程调用exec函数执行另一个应用程序时,就不能再共享了. 这种情况下可以将子进程中的文件描述符重定向到标准输入,当新执行的程序从标准输入 ...