【仓颉三方库】 网络组件——rpc4cj

架构图

  • rpc4cj使客户端和服务端应用程序可以透明地进行通信,并简 化了连接系统的构建。

源码目录

.
├── README.md
├── doc
│   ├── assets
│   ├── cjcov
│   ├── feature_api.md
│   └── design.md
├── src
│   └── attributes
│   └── buffer
│   └── exceptions
│   └── grpc
│   └── internal
│   └── net
│   └── resolver
│   │   └── dns
│   │   └── manual
│   │   └── passthrough
│   └── transport
│   └── util     
└── test
    ├── HLT
    ├── LLT
    └── UT
  • doc存放库的设计文档、提案、库的使用文档、LLT 用例覆盖报告
  • src是库源码目录
  • test存放测试用例,包括HLT用例、LLT 用例和UT用例

接口说明

主要是核心类和成员函数说明,详情见  API

使用说明

编译

编译描述和具体 shell 命令

linux x86 编译:

需要依赖 protobuf4cj, 可在 https://gitcode.com/Cangjie-TPC/protobuf4cj.git  处编译获取 将构建完成的的 protobuf 文件夹复制到 rpc4cj 项目根目录下面

cjpm build
windows x86 编译:

前提:使用 openssl version 查看环境下有无 openssl, 版本为 OpenSSL 3.x.x,若无,可参考 https://github.com/openssl/openssl 官网的 Build and Install。

需要依赖 protobuf4cj, 可在 https://gitcode.com/Cangjie-TPC/protobuf4cj.git 处编译获取 将构建完成的的 protobuf 文件夹复制到 rpc4cj 项目根目录下面

cjpm build

功能示例

需要安装 protobuf 软件及 protobuf4cj 插件: ubuntu 系统可使用以下命令安装 protobuf

apt install -y protobuf-compiler
protoc --version # 正确显示版本号即成功

编译安装 protobuf-gen-cj 插件,可在 https://gitcode.com/Cangjie-TPC/protobuf4cj.git 处编译获取

使用 protobuf4cj 用该 proto 文件生成 helloworld_pb.cj 文件, 放入test/LLT中,可以使用以下命令,参考 README.md · Cangjie-TPC/protobuf4c - 码云 - 开源中国 (gitcode.com)

protoc --cj_out=.  --proto_path=. $(proto_files) #--cj_out= 指定输出地址,--proto_path=指定proto文件路径
一元调用功能示例

首先运行任意一版本语言的 helloworld server example,或本仓附带 go 版本 server 端 其他语言版本 server 端可于 Supported languages | gRPC 内获取

示例 proto 文件如下:

syntax = "proto3";

option go_package = "google.golang.org/grpc/examples/helloworld/helloworld";
option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";

package helloworld;

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}

示例代码如下:

使用测试框架运行,将 “xxxx" 处替换为本地代码仓库地址,并将源代码文件放入test/LLT中。

// DEPENDENCE: ./helloworld.pb.cj
// EXEC: cjc %import-path %L %l %f ./helloworld.pb.cj  %project-path %project-L/protobuf  -l protobuf-cj
// EXEC: ./main

from std import socket.*
from rpc4cj import grpc.*
from rpc4cj import transport.*
from rpc4cj import exceptions.*
from rpc4cj import util.*
from std import collection.*
from protobuf import protobuf.*
from protobuf import grpc.*
from std import time.*

var port: UInt16 = 50051
main (){
    var req = HelloRequest()
    var resp = HelloReply()
    req.name = "World"
    var con = dial("127.0.0.1:${port}")
    con.invoke("/helloworld.Greeter/SayHello", req, resp)
    println("result: ${resp}")
}

启动仓内提供测试用 go 版本服务器

./test/LLT/test_grpc_post/go_server

另开一终端执行命令

python3 ci_test/main.py test

执行结果如下:

result: {message: "Hello World"}
流式调用功能示例

cangjie 双向流式调用的示例如下:

示例代码如下:

from std import socket.*
from rpc4cj import grpc.*
from rpc4cj import transport.*
from rpc4cj import exceptions.*
from rpc4cj import util.*
from std import collection.*
from std import time.*
from std import sync.*
from protobuf import protobuf.*

let strServer: String = "20221226abc"

var port: UInt16 = 0
let num: Int64 = 5
main() {
    let ss: SocketServer = SocketServer(TCP, "127.0.0.1", port)
    port = ss.port

    spawn{ =>
        println("ss=${ss.address}")//127.0.0.1:50051/hello
        let lis: GRPCServerSocket = GRPCServerSocket(GrpcSocketS(ss))

        let server: Server = Server()
        registerGreeterServer(server, ServerTest())
        server.serve(lis)
    }

    sleep(Duration.second)

    var req = HelloRequest()
    var resp = HelloReply()
    req.name = "World"
    var con = dial("127.0.0.1:${port}")//linux

    var stream = con.newStreamClient()

    stream.doStreamRequest("/helloworld.Greeter/SayHello")
    for (i in 0..num) {
        req.name = "World-" + i.toString()
        stream.sendStreamMsg(req)
    }
    var readstream = stream.closeAndRecv()
    while (readstream.recv(resp)) {
        println(resp)
    }
  return 0
}

//protobuf 依赖
class ServerTest <: GreeterServer {
    public func SayHello(hr: HelloRequest): (HelloReply, GrpcError) {
        let hy: HelloReply = HelloReply()
        hy.message = "ceshi-20221227"
        println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~0")
        println("received: hr.name = ${hr.name}")
        println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~1")
        return (hy, GrpcError())
    }
    public func mustEmbedUnimplementedGreeterServer() {}
}

public class HelloRequest <: Message & TypedMessage<HelloRequest> {
    private var p_name = Pb3String()

    public init() {
        m_innerInit()
    }

    public mut prop name: String { get() { p_name.get() } set(i_vtmp) { p_name.set(i_vtmp); markDirty() } }

    protected func m_size(): Int64 {
        var i_tmp = 0
        if (!p_name.isEmpty()) { i_tmp += 1 + binSize(p_name.data) }
        return i_tmp
    }

    protected func m_isEmpty(): Bool {
        p_name.isEmpty()
    }

    protected func m_clear(): Unit {
        p_name.clear()
    }

    public func copyFrom(src: HelloRequest): HelloRequest {
        p_name = src.p_name
        m_innerCopyFrom(src)
        return this
    }

    public func clone(): HelloRequest {
        return HelloRequest().copyFrom(this)
    }

    public func unpack<T>(src: T): Unit where T <: BytesReader {
        while (!src.isEmpty()) {
            let i_tmp = src.parseTag()
            match (i_tmp[0]) {
                case 1 => p_name.unpack(src)
                case _ => m_unknown(src, i_tmp)
            }
        }
        markDirty()
    }

    public func pack<T>(out: T): Unit where T <: BytesWriter {
        if (!p_name.isEmpty()) { out.append(10); out.packBin(p_name.data) }
        m_unknown(out)
    }

    public func toString(): String {
        var i_tmp = StructPrinter()
        if (!p_name.isEmpty()) { i_tmp.append("name", p_name.get()) }
        return i_tmp.done().toString()
    }

    public func packi(out: BytesWriter) { match (out) { case i_tmp: SimpleWriter => pack(i_tmp) case _ => pack(out) } }
    public func unpacki(src: BytesReader) { match (src) { case i_stmp: SimpleReader => unpack(i_stmp) case _ => unpack(src) } }

    public static func empty() { HelloRequest() }
    public static func fromBytes(src: Collection<Byte>) { let i_tmp = HelloRequest(); i_tmp.unpack(src); i_tmp }
    public static func fromBytes(src: BytesReader) { let i_tmp = HelloRequest(); i_tmp.unpack(src); i_tmp }
}

public class HelloReply <: Message & TypedMessage<HelloReply> {
    private var p_message = Pb3String()

    public init() {
        m_innerInit()
    }

    public mut prop message: String { get() { p_message.get() } set(i_vtmp) { p_message.set(i_vtmp); markDirty() } }

    protected func m_size(): Int64 {
        var i_tmp = 0
        if (!p_message.isEmpty()) { i_tmp += 1 + binSize(p_message.data) }
        return i_tmp
    }

    protected func m_isEmpty(): Bool {
        p_message.isEmpty()
    }

    protected func m_clear(): Unit {
        p_message.clear()
    }

    public func copyFrom(src: HelloReply): HelloReply {
        p_message = src.p_message
        m_innerCopyFrom(src)
        return this
    }

    public func clone(): HelloReply {
        return HelloReply().copyFrom(this)
    }

    public func unpack<T>(src: T): Unit where T <: BytesReader {
        while (!src.isEmpty()) {
            let i_tmp = src.parseTag()
            match (i_tmp[0]) {
                case 1 => p_message.unpack(src)
                case _ => m_unknown(src, i_tmp)
            }
        }
        markDirty()
    }

    public func pack<T>(out: T): Unit where T <: BytesWriter {
        if (!p_message.isEmpty()) { out.append(10); out.packBin(p_message.data) }
        m_unknown(out)
    }

    public func toString(): String {
        var i_tmp = StructPrinter()
        if (!p_message.isEmpty()) { i_tmp.append("message", p_message.get()) }
        return i_tmp.done().toString()
    }

    public func packi(out: BytesWriter) { match (out) { case i_tmp: SimpleWriter => pack(i_tmp) case _ => pack(out) } }
    public func unpacki(src: BytesReader) { match (src) { case i_stmp: SimpleReader => unpack(i_stmp) case _ => unpack(src) } }

    public static func empty() { HelloReply() }
    public static func fromBytes(src: Collection<Byte>) { let i_tmp = HelloReply(); i_tmp.unpack(src); i_tmp }
    public static func fromBytes(src: BytesReader) { let i_tmp = HelloReply(); i_tmp.unpack(src); i_tmp }
}

//server 端
public abstract class GreeterServer <: Message {
    public func SayHello(hr: HelloRequest): (HelloReply, GrpcError)
    public func mustEmbedUnimplementedGreeterServer(): Unit

    protected func m_size(): Int64 { return 0 }
    protected func m_isEmpty(): Bool { return false }
    protected func m_clear(): Unit {}
    public func unpacki(_: BytesReader): Unit {}
    public func packi(_: BytesWriter): Unit {}
    public func toString(): String { return "" }
}

class UnimplementedGreeterServer <: GreeterServer {
    public func SayHello(_: HelloRequest): (HelloReply, GrpcError) {
        return (HelloReply(), GrpcError(Unimplemented, "method SayHello not implemented"))
    }
    public func mustEmbedUnimplementedGreeterServer() {}
}

interface UnsafeGreeterServer {
    func mustEmbedUnimplementedGreeterServer(): Unit
}

public func defaultAnyAndServerStreamToGrpcError(any: Any, ss: ServerStream): GrpcError {
    println("++++++++++++++++++++++++++start-------------------defaultAnyAndServerStreamToGrpcError-------0")
    println("++++++++++++++++++++++++++start-------------------defaultAnyAndServerStreamToGrpcError-------0")
    if (any is HelloRequest) {
        let hy: HelloRequest = (any as HelloRequest).getOrThrow()
        println("hy.name = ${hy.name}")
    } else if (any is HelloReply) {
        (any as HelloReply).getOrThrow()
        println("hy.message = hy.message")
    }

    let hr: HelloRequest = HelloRequest()
    for (i in 0..num) {
        hr.name = "ceshi-20221227-stream-" + i.toString()
        ss.sendMsg(hr)
    }

    var resp = HelloReply()
    for (_ in 0..num) {
        ss.recvMsg(resp)
        println("resp = ${resp}")
    }

    println("++++++++++++++++++++++++++start-------------------defaultAnyAndServerStreamToGrpcError-------1")
    println("++++++++++++++++++++++++++start-------------------defaultAnyAndServerStreamToGrpcError-------1")
    return NULL_ERR
}

var Greeter_ServiceDesc = ServiceDesc(
    serviceName: "helloworld.Greeter",
    handlerType: -1,
    streams: [StreamDesc(streamName: "SayHello", handler:  StreamHandler(defaultAnyAndServerStreamToGrpcError) )],
    metadata: "./helloworld.proto"
)

func registerGreeterServer(s: Server, srv: Message) {
    s.registerService(Greeter_ServiceDesc, srv)
}

执行结果如下:

ss=127.0.0.1:46327
++++++++++++++++++++++++++start-------------------defaultAnyAndServerStreamToGrpcError-------0
++++++++++++++++++++++++++start-------------------defaultAnyAndServerStreamToGrpcError-------0
resp = {message: "World-0"}
resp = {message: "World-1"}
resp = {message: "World-2"}
resp = {message: "World-3"}
resp = {message: "World-4"}
++++++++++++++++++++++++++start-------------------defaultAnyAndServerStreamToGrpcError-------1
++++++++++++++++++++++++++start-------------------defaultAnyAndServerStreamToGrpcError-------1
压缩功能示例

可以启用默认 gzip 算法压缩请求数据,该示例需要和 test/LLT/grpc/compressor/helloworld.pb.cj 一起编译

示例代码如下:

from std import socket.*
from rpc4cj import grpc.*
from rpc4cj import transport.*
from rpc4cj import exceptions.*
from rpc4cj import util.*
from std import sync.*
from std import time.*
from std import collection.*
from protobuf import protobuf.*

let strServer: String = "test pass"
class ServerTest <: GreeterServer {
    public func SayHello(hr: HelloRequest): (HelloReply, GrpcError) {
        let hy: HelloReply = HelloReply()
        hy.message = strServer
        return (hy, GrpcError())
    }
    public func mustEmbedUnimplementedGreeterServer() {}
}

var port: UInt16 = 50051
main() {

    let ss: SocketServer = SocketServer(TCP, "127.0.0.1", port)
    port = ss.port

    spawn{ =>
        let lis: GRPCServerSocket = GRPCServerSocket(GrpcSocketS(ss))
        let server: Server = Server()
        registerGreeterServer(server, ServerTest())
        server.serve(lis)
    }

    sleep(Duration.second)

    var req = HelloRequest()
    var resp = HelloReply()
    req.name = "World"

    var con = dial("127.0.0.1:${port}")//linux
    con.useCompressor()
    con.invoke("/helloworld.Greeter/SayHello",req,resp)
    println(resp)
    return 0
}

执行结果如下:

--------------------------111
inhr.name = World
--------------------------111
{message: "test pass"}
拦截器功能示例

拦截器提供对请求的参数和获取到的请求的拦截以实现对数据的检查和控制,一元请求拦截器示例如下,该示例需要和 test/LLT/grpc/interceptor/helloworld.pb.cj 一起编译

示例代码如下:

from std import socket.*
from rpc4cj import grpc.*
from rpc4cj import transport.*
from rpc4cj import exceptions.*
from rpc4cj import util.*
from std import collection.*
from std import sync.*
from std import time.*
from protobuf import protobuf.*

let strServer: String = "World0123456789"
class ServerTest <: GreeterServer {
    public func SayHello(_: HelloRequest): (HelloReply, GrpcError) {
        let hy: HelloReply = HelloReply()
        hy.message = strServer
        return (hy, GrpcError())
    }
    public func mustEmbedUnimplementedGreeterServer() {}
}

var port: UInt16 = 50052
main() {

    let ss: SocketServer = SocketServer(TCP, "127.0.0.1", port)
    port = ss.port

    spawn{ =>
        let lis: GRPCServerSocket = GRPCServerSocket(GrpcSocketS(ss))

        let usi: UnaryServerInterceptor = getUnaryServerInterceptor()
        let so1: ServerOption = unaryInterceptor(usi)

        var opts: Array<ServerOption> = Array<ServerOption>([so1])

        let server: Server = Server.newServer(opts)
        registerGreeterServer(server, ServerTest())

        server.serve(lis)
    }

    sleep(Duration.second)

    var req = HelloRequest()
    var resp = HelloReply()
    req.name = "World"

    var opts = ArrayList<DialOption>()
    opts.append(WithUnaryInterceptor(unary()))

    var con = dial("127.0.0.1:${port}",opts )//linux
    con.invoke("/helloworld.Greeter/SayHello",req,resp)
    return 0
}

func funcIns_1(_:Any,_:UnaryServerInfo, _:UnaryHandler): (Message, GrpcError) {
    println("测试服务端一元拦截器调用!")
    return (GrpcErrorMessage(), GrpcError())
}

public func getUnaryServerInterceptor(): UnaryServerInterceptor{
    let cal_Ins_UnaryServerInterceptor :UnaryServerInterceptor = UnaryServerInterceptor(funcIns_1)
    return cal_Ins_UnaryServerInterceptor
}

class unary <: UnaryInvoker {
    public func orderUnaryClientInterceptor(method: String, req: Message, _: Message): Unit {
        if (method == "/helloworld.Greeter/SayHello") {
            println(method)
            println("method ok")
        } else {
            throw Exception("error method")
        }
        var r = (req as HelloRequest).getOrThrow()
        if (r.name == "World") {
            println(r.name)
            println("request ok")  
        } else {
            throw Exception("error method")
        }
    }
}

执行结果如下:

--------------------------000
inhr.name = World
--------------------------000
测试服务端一元拦截器调用!
/helloworld.Greeter/SayHello
method ok
World
request ok
域名解析功能示例

客户端可以启用内置域名解析功能,提供对服务器域名的解析并连接,示例如下:

示例代码如下:

from std import socket.*
from rpc4cj import grpc.*
from rpc4cj import transport.*
from rpc4cj import exceptions.*
from rpc4cj import util.*
from std import collection.*
from std import time.*
from std import sync.*
from rpc4cj import resolver.*
from rpc4cj import resolver.dns.*

var port: UInt16 = 0
main() {
    let ss: SocketServer = SocketServer(TCP, "127.0.0.1", port)
    port = ss.port
    spawn{ =>
        let lis: GRPCServerSocket = GRPCServerSocket(GrpcSocketS(ss))
        let server: Server = Server()
        server.serve(lis)
    }
    sleep(Duration.second)
    try{
        dial("passthrough:///127.0.0.1:${port}")//reslove localhost with
    } catch (e: Exception) {
          println("reslove failed")
          return 1
    }
    println("reslove pass")
    return 0
}

执行结果如下:

reslove pass
TLS 安全连接功能示例

TLS 是一种网络传输层安全协议,可以为 rpc4cj 客户端应用程序和服务器端应用程序之间提供安全连接,示例如下: 注: 示例中使用到的密钥仅供参考,用户需要自行准备。

示例代码如下:

// DEPENDENCE: ./example-cert.pem
// DEPENDENCE: ./example-key.pem
// EXEC: cjc %import-path %L %l %f %project-path %project-L/protobuf  -l protobuf-cj
// EXEC: ./main

from std import socket.*
from std import io.*
from std import sync.*
from std import time.*
from std import collection.*
from net import tls.*

from rpc4cj import grpc.*
from rpc4cj import transport.*
from rpc4cj import exceptions.*
from rpc4cj import util.*

from protobuf import protobuf.*

class ServerTest <: GreeterServer {
	// SayHello implements helloworld.GreeterServer
	public func SayHello(hr: HelloRequest): (HelloReply, GrpcError) {
		let hy: HelloReply = HelloReply()
		hy.message = "测试server端-20230224......哈哈哈哈,测试通了!"
		println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~0")
		println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~1")
		println("测试server端-20220919")
		println("received: hr.name = ${hr.name}")
		println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~2")
		println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~3")
		return (hy, GrpcError())
	}
	public func mustEmbedUnimplementedGreeterServer() {}
}

var port: UInt16 = 50051

main(): Int64 {

    var cfgs = TlsServerConfig("./example-cert.pem","./example-key.pem")
    cfgs.alpnList = ["h2", "http/1.1"]
    let ss: TlsSocketServer = TlsSocketServer(TCP, "127.0.0.1", port, cfgs)
    port = ss.port

    spawn{ =>
        println("ss=${ss.address}")//127.0.0.1:50051/hello
        let lis: GRPCServerSocket = GRPCServerSocket(GrpcTlsS(ss))

        let server: Server = Server()
        registerGreeterServer(server, ServerTest())
        server.serve(lis)
    }

    sleep(Duration.second)

    var req = HelloRequest()
    var resp = HelloReply()
    req.name = "World"

    var cfg = TlsClientConfig("./example-cert.pem")
    cfg.alpnList = ["h2", "http/1.1"]
    cfg.verifyMode = VerifyNone

    try {
        var con = dial("127.0.0.1:${port}", cfg: cfg)//linux
        con.invoke("/helloworld.Greeter/SayHello", req, resp)
    } catch(e: Exception) {
        e.printStackTrace()
        return -1
    }

    println("result: ${resp}")
    println("result: {\"message\": \"Hello World\"}")

    return 0
}

public class HelloRequest <: Message & TypedMessage<HelloRequest> {
    private var p_name = Pb3String()

    public init() {
        m_innerInit()
    }

    public mut prop name: String { get() { p_name.get() } set(i_vtmp) { p_name.set(i_vtmp); markDirty() } }

    protected func m_size(): Int64 {
        var i_tmp = 0
        if (!p_name.isEmpty()) { i_tmp += 1 + binSize(p_name.data) }
        return i_tmp
    }

    protected func m_isEmpty(): Bool {
        p_name.isEmpty()
    }

    protected func m_clear(): Unit {
        p_name.clear()
    }

    public func copyFrom(src: HelloRequest): HelloRequest {
        p_name = src.p_name
        m_innerCopyFrom(src)
        return this
    }

    public func clone(): HelloRequest {
        return HelloRequest().copyFrom(this)
    }

    public func unpack<T>(src: T): Unit where T <: BytesReader {
        while (!src.isEmpty()) {
            let i_tmp = src.parseTag()
            match (i_tmp[0]) {
                case 1 => p_name.unpack(src)
                case _ => m_unknown(src, i_tmp)
            }
        }
        markDirty()
    }

    public func pack<T>(out: T): Unit where T <: BytesWriter {
        if (!p_name.isEmpty()) { out.append(10); out.packBin(p_name.data) }
        m_unknown(out)
    }

    public func toString(): String {
        var i_tmp = StructPrinter()
        if (!p_name.isEmpty()) { i_tmp.append("name", p_name.get()) }
        return i_tmp.done().toString()
    }

    public func packi(out: BytesWriter) { match (out) { case i_tmp: SimpleWriter => pack(i_tmp) case _ => pack(out) } }
    public func unpacki(src: BytesReader) { match (src) { case i_stmp: SimpleReader => unpack(i_stmp) case _ => unpack(src) } }

    public static func empty() { HelloRequest() }
    public static func fromBytes(src: Collection<Byte>) { let i_tmp = HelloRequest(); i_tmp.unpack(src); i_tmp }
    public static func fromBytes(src: BytesReader) { let i_tmp = HelloRequest(); i_tmp.unpack(src); i_tmp }
}

public class HelloReply <: Message & TypedMessage<HelloReply> {
    private var p_message = Pb3String()

    public init() {
        m_innerInit()
    }

    public mut prop message: String { get() { p_message.get() } set(i_vtmp) { p_message.set(i_vtmp); markDirty() } }

    protected func m_size(): Int64 {
        var i_tmp = 0
        if (!p_message.isEmpty()) { i_tmp += 1 + binSize(p_message.data) }
        return i_tmp
    }

    protected func m_isEmpty(): Bool {
        p_message.isEmpty()
    }

    protected func m_clear(): Unit {
        p_message.clear()
    }

    public func copyFrom(src: HelloReply): HelloReply {
        p_message = src.p_message
        m_innerCopyFrom(src)
        return this
    }

    public func clone(): HelloReply {
        return HelloReply().copyFrom(this)
    }

    public func unpack<T>(src: T): Unit where T <: BytesReader {
        while (!src.isEmpty()) {
            let i_tmp = src.parseTag()
            match (i_tmp[0]) {
                case 1 => p_message.unpack(src)
                case _ => m_unknown(src, i_tmp)
            }
        }
        markDirty()
    }

    public func pack<T>(out: T): Unit where T <: BytesWriter {
        if (!p_message.isEmpty()) { out.append(10); out.packBin(p_message.data) }
        m_unknown(out)
    }

    public func toString(): String {
        var i_tmp = StructPrinter()
        if (!p_message.isEmpty()) { i_tmp.append("message", p_message.get()) }
        return i_tmp.done().toString()
    }

    public func packi(out: BytesWriter) { match (out) { case i_tmp: SimpleWriter => pack(i_tmp) case _ => pack(out) } }
    public func unpacki(src: BytesReader) { match (src) { case i_stmp: SimpleReader => unpack(i_stmp) case _ => unpack(src) } }

    public static func empty() { HelloReply() }
    public static func fromBytes(src: Collection<Byte>) { let i_tmp = HelloReply(); i_tmp.unpack(src); i_tmp }
    public static func fromBytes(src: BytesReader) { let i_tmp = HelloReply(); i_tmp.unpack(src); i_tmp }
}

//server端
public abstract class GreeterServer <: Message {
	public func SayHello(hr: HelloRequest): (HelloReply, GrpcError)
	public func mustEmbedUnimplementedGreeterServer(): Unit

    protected func m_size(): Int64 { return 0 }
    protected func m_isEmpty(): Bool { return false }
    protected func m_clear(): Unit {}
    public func unpacki(_: BytesReader): Unit {}
    public func packi(_: BytesWriter): Unit {}
    public func toString(): String { return "" }

}

class UnimplementedGreeterServer <: GreeterServer {
	public func SayHello(_: HelloRequest): (HelloReply, GrpcError) {
		return (HelloReply(), GrpcError(Unimplemented, "method SayHello not implemented"))
	}
	//public func clone() { this }
	public func mustEmbedUnimplementedGreeterServer() {}
}

interface UnsafeGreeterServer {
	 func mustEmbedUnimplementedGreeterServer(): Unit
}

/*
public class DEFAULT_MESSAGELITE2 <: Message {
    public func clone() { this }
}
*/

func Greeter_SayHello_Handler(srv: Message, dec: (Message) -> GrpcError, interceptor: ?UnaryServerInterceptor): (Message, GrpcError) {
	let inhr: HelloRequest = HelloRequest()

	var err: GrpcError = dec(inhr)
	if (!err.isNull()) {
		return (inhr, err)
	}
	match(interceptor){
		case Some(v) =>
				let info: UnaryServerInfo = UnaryServerInfo(
					server:     srv,
					fullMethod: "/helloworld.Greeter/SayHello"
				)
				println("--------------------------000")
				println("inhr.name = ${inhr.name}")
				println("--------------------------000")
				inhr.name = "dec(inhr)解析到的HelloRequest是空的???-----000"
				func handlercs(req: Any): (Any, GrpcError) {
					return (srv as (GreeterServer)).getOrThrow().SayHello((req as HelloRequest).getOrThrow())
					//return srv.SayHello((req as HelloRequest).getOrThrow())
				}
				return v.f(inhr, info, UnaryHandler(handlercs))
		case None =>
				println("--------------------------111")
				println("inhr.name = ${inhr.name}")
				println("--------------------------111")
				//inhr.name = "dec(inhr)解析到的HelloRequest是空的???-----111"
				return (srv as (GreeterServer)).getOrThrow().SayHello(inhr)
				//return srv.SayHello(inhr)
	}
}

public func defaultAnyAndServerStreamToGrpcError(any: Any, ss: ServerStream): GrpcError {
    println("++++++++++++++++++++++++++start-------------------defaultAnyAndServerStreamToGrpcError-------0")
	println("++++++++++++++++++++++++++start-------------------defaultAnyAndServerStreamToGrpcError-------0")
    if (any is HelloRequest) {
        let hy: HelloRequest = (any as HelloRequest).getOrThrow()
        println("hy.name = ${hy.name}")
    } else if (any is HelloReply) {
		let hy: HelloReply = (any as HelloReply).getOrThrow()
		println("hy.message = ${hy.message}")
	}

	let hr: HelloRequest = HelloRequest()
	hr.name = "测试processStreamingRPC--20221008!仓颉666"
	ss.sendMsg(hr)

	println("++++++++++++++++++++++++++start-------------------defaultAnyAndServerStreamToGrpcError-------1")
	println("++++++++++++++++++++++++++start-------------------defaultAnyAndServerStreamToGrpcError-------1")
	return NULL_ERR
}

var Greeter_ServiceDesc = ServiceDesc(
	serviceName: "helloworld.Greeter",
	handlerType: -1,
	methods: [MethodDesc(methodName: "SayHello", handler:  Greeter_SayHello_Handler)],
	//streams: [StreamDesc(streamName: "SayHello", handler:  StreamHandler(defaultAnyAndServerStreamToGrpcError) )],
	metadata: "./helloworld.proto"
)

func registerGreeterServer(s: Server, srv: Message) {
	s.registerService(Greeter_ServiceDesc, srv)
}

执行结果如下:

ss=127.0.0.1:50051
--------------------------111
inhr.name = World
--------------------------111
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~0
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~1
测试server端-20220919
received: hr.name = World
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~2
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~3
result: {message: "测试server端-20230224......哈哈哈哈,测试通了!"}
result: {"message": "Hello World"}
  • 8
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值