You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by li...@apache.org on 2022/07/06 09:40:33 UTC
[dubbo-rust] 21/28: feat(dubbo): define the API of protocol module, provide simple impl of tonic(grpc)
This is an automated email from the ASF dual-hosted git repository.
liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-rust.git
commit e03e4cd915ba76d2b977a0b3f952ce6843e510b4
Author: yang <96...@qq.com>
AuthorDate: Sun Jun 26 22:51:01 2022 +0800
feat(dubbo): define the API of protocol module, provide simple impl of tonic(grpc)
---
Cargo.toml | 2 +-
dubbo/Cargo.lock | 929 ++++++++++++++++++++++++++++++++
dubbo/Cargo.toml | 28 +
dubbo/readme.md | 1 +
dubbo/src/common/mod.rs | 1 +
dubbo/src/common/url.rs | 5 +
dubbo/src/helloworld/client.rs | 23 +
dubbo/src/helloworld/helloworld.rs | 272 ++++++++++
dubbo/src/helloworld/mod.rs | 1 +
dubbo/src/helloworld/server.rs | 0
dubbo/src/lib.rs | 6 +
dubbo/src/main.rs | 10 +
dubbo/src/service/grpc/grpc_exporter.rs | 34 ++
dubbo/src/service/grpc/grpc_invoker.rs | 73 +++
dubbo/src/service/grpc/grpc_protocol.rs | 60 +++
dubbo/src/service/grpc/grpc_server.rs | 116 ++++
dubbo/src/service/grpc/mod.rs | 59 ++
dubbo/src/service/invocation.rs | 45 ++
dubbo/src/service/mod.rs | 4 +
dubbo/src/service/protocol.rs | 31 ++
dubbo/src/utils/boxed.rs | 74 +++
dubbo/src/utils/boxed_clone.rs | 88 +++
dubbo/src/utils/mod.rs | 2 +
protocol/Cargo.toml | 8 -
protocol/src/lib.rs | 25 -
25 files changed, 1863 insertions(+), 34 deletions(-)
diff --git a/Cargo.toml b/Cargo.toml
index 3720b7d..8c2e58e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,9 +1,9 @@
[workspace]
members = [
"xds",
- "protocol",
"registry",
"metadata",
"common",
"config",
+ "dubbo"
]
\ No newline at end of file
diff --git a/dubbo/Cargo.lock b/dubbo/Cargo.lock
new file mode 100644
index 0000000..a69c71b
--- /dev/null
+++ b/dubbo/Cargo.lock
@@ -0,0 +1,929 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "adler"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
+
+[[package]]
+name = "anyhow"
+version = "1.0.57"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc"
+
+[[package]]
+name = "async-stream"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dad5c83079eae9969be7fadefe640a1c566901f05ff91ab221de4b6f68d9507e"
+dependencies = [
+ "async-stream-impl",
+ "futures-core",
+]
+
+[[package]]
+name = "async-stream-impl"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "async-trait"
+version = "0.1.56"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96cf8829f67d2eab0b2dfa42c5d0ef737e0724e4a82b01b3e292456202b19716"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "autocfg"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
+
+[[package]]
+name = "axum"
+version = "0.5.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc47084705629d09d15060d70a8dbfce479c842303d05929ce29c74c995916ae"
+dependencies = [
+ "async-trait",
+ "axum-core",
+ "bitflags",
+ "bytes 1.1.0",
+ "futures-util",
+ "http",
+ "http-body",
+ "hyper",
+ "itoa",
+ "matchit",
+ "memchr",
+ "mime",
+ "percent-encoding",
+ "pin-project-lite",
+ "serde",
+ "sync_wrapper",
+ "tokio",
+ "tower",
+ "tower-http",
+ "tower-layer",
+ "tower-service",
+]
+
+[[package]]
+name = "axum-core"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c2efed1c501becea07ce48118786ebcf229531d0d3b28edf224a720020d9e106"
+dependencies = [
+ "async-trait",
+ "bytes 1.1.0",
+ "futures-util",
+ "http",
+ "http-body",
+ "mime",
+]
+
+[[package]]
+name = "base64"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
+
+[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "bytes"
+version = "0.5.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
+
+[[package]]
+name = "bytes"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "crc32fast"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "dubbo"
+version = "0.1.0"
+dependencies = [
+ "async-trait",
+ "futures-util",
+ "h2",
+ "http",
+ "http-body",
+ "hyper",
+ "lazy_static",
+ "prost 0.10.4",
+ "prost-derive 0.10.1",
+ "prost-types",
+ "tokio",
+ "tonic",
+ "tower",
+ "tower-layer",
+ "tower-service",
+]
+
+[[package]]
+name = "either"
+version = "1.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
+
+[[package]]
+name = "flate2"
+version = "1.0.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6"
+dependencies = [
+ "crc32fast",
+ "miniz_oxide",
+]
+
+[[package]]
+name = "fnv"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
+[[package]]
+name = "futures-channel"
+version = "0.3.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010"
+dependencies = [
+ "futures-core",
+]
+
+[[package]]
+name = "futures-core"
+version = "0.3.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3"
+
+[[package]]
+name = "futures-sink"
+version = "0.3.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868"
+
+[[package]]
+name = "futures-task"
+version = "0.3.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a"
+
+[[package]]
+name = "futures-util"
+version = "0.3.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a"
+dependencies = [
+ "futures-core",
+ "futures-task",
+ "pin-project-lite",
+ "pin-utils",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi",
+]
+
+[[package]]
+name = "h2"
+version = "0.3.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57"
+dependencies = [
+ "bytes 1.1.0",
+ "fnv",
+ "futures-core",
+ "futures-sink",
+ "futures-util",
+ "http",
+ "indexmap",
+ "slab",
+ "tokio",
+ "tokio-util",
+ "tracing",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
+
+[[package]]
+name = "hermit-abi"
+version = "0.1.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "http"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399"
+dependencies = [
+ "bytes 1.1.0",
+ "fnv",
+ "itoa",
+]
+
+[[package]]
+name = "http-body"
+version = "0.4.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
+dependencies = [
+ "bytes 1.1.0",
+ "http",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "http-range-header"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29"
+
+[[package]]
+name = "httparse"
+version = "1.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c"
+
+[[package]]
+name = "httpdate"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
+
+[[package]]
+name = "hyper"
+version = "0.14.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42dc3c131584288d375f2d07f822b0cb012d8c6fb899a5b9fdb3cb7eb9b6004f"
+dependencies = [
+ "bytes 1.1.0",
+ "futures-channel",
+ "futures-core",
+ "futures-util",
+ "h2",
+ "http",
+ "http-body",
+ "httparse",
+ "httpdate",
+ "itoa",
+ "pin-project-lite",
+ "socket2",
+ "tokio",
+ "tower-service",
+ "tracing",
+ "want",
+]
+
+[[package]]
+name = "hyper-timeout"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1"
+dependencies = [
+ "hyper",
+ "pin-project-lite",
+ "tokio",
+ "tokio-io-timeout",
+]
+
+[[package]]
+name = "indexmap"
+version = "1.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6012d540c5baa3589337a98ce73408de9b5a25ec9fc2c6fd6be8f0d39e0ca5a"
+dependencies = [
+ "autocfg",
+ "hashbrown",
+]
+
+[[package]]
+name = "itertools"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "itertools"
+version = "0.10.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "itoa"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d"
+
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
+[[package]]
+name = "libc"
+version = "0.2.126"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
+
+[[package]]
+name = "log"
+version = "0.4.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "matchit"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73cbba799671b762df5a175adf59ce145165747bb891505c43d09aefbbf38beb"
+
+[[package]]
+name = "memchr"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
+
+[[package]]
+name = "mime"
+version = "0.3.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
+
+[[package]]
+name = "miniz_oxide"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc"
+dependencies = [
+ "adler",
+]
+
+[[package]]
+name = "mio"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "713d550d9b44d89174e066b7a6217ae06234c10cb47819a88290d2b353c31799"
+dependencies = [
+ "libc",
+ "log",
+ "wasi",
+ "windows-sys",
+]
+
+[[package]]
+name = "num_cpus"
+version = "1.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
+dependencies = [
+ "hermit-abi",
+ "libc",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225"
+
+[[package]]
+name = "percent-encoding"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
+
+[[package]]
+name = "pin-project"
+version = "1.0.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e"
+dependencies = [
+ "pin-project-internal",
+]
+
+[[package]]
+name = "pin-project-internal"
+version = "1.0.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "pin-project-lite"
+version = "0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
+
+[[package]]
+name = "pin-utils"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+
+[[package]]
+name = "ppv-lite86"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.39"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "prost"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ce49aefe0a6144a45de32927c77bd2859a5f7677b55f220ae5b744e87389c212"
+dependencies = [
+ "bytes 0.5.6",
+ "prost-derive 0.6.1",
+]
+
+[[package]]
+name = "prost"
+version = "0.10.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "71adf41db68aa0daaefc69bb30bcd68ded9b9abaad5d1fbb6304c4fb390e083e"
+dependencies = [
+ "bytes 1.1.0",
+ "prost-derive 0.10.1",
+]
+
+[[package]]
+name = "prost-derive"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "537aa19b95acde10a12fec4301466386f757403de4cd4e5b4fa78fb5ecb18f72"
+dependencies = [
+ "anyhow",
+ "itertools 0.8.2",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "prost-derive"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b670f45da57fb8542ebdbb6105a925fe571b67f9e7ed9f47a06a84e72b4e7cc"
+dependencies = [
+ "anyhow",
+ "itertools 0.10.3",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "prost-types"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1834f67c0697c001304b75be76f67add9c89742eda3a085ad8ee0bb38c3417aa"
+dependencies = [
+ "bytes 0.5.6",
+ "prost 0.6.1",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "rand"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
+dependencies = [
+ "libc",
+ "rand_chacha",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
+dependencies = [
+ "ppv-lite86",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
+dependencies = [
+ "getrandom",
+]
+
+[[package]]
+name = "serde"
+version = "1.0.137"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1"
+
+[[package]]
+name = "signal-hook-registry"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "slab"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32"
+
+[[package]]
+name = "socket2"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0"
+dependencies = [
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "syn"
+version = "1.0.96"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0748dd251e24453cb8717f0354206b91557e4ec8703673a4b30208f2abaf1ebf"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "sync_wrapper"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "20518fe4a4c9acf048008599e464deb21beeae3d3578418951a189c235a7a9a8"
+
+[[package]]
+name = "tokio"
+version = "1.19.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c51a52ed6686dd62c320f9b89299e9dfb46f730c7a48e635c19f21d116cb1439"
+dependencies = [
+ "bytes 1.1.0",
+ "libc",
+ "memchr",
+ "mio",
+ "num_cpus",
+ "once_cell",
+ "pin-project-lite",
+ "signal-hook-registry",
+ "socket2",
+ "tokio-macros",
+ "winapi",
+]
+
+[[package]]
+name = "tokio-io-timeout"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf"
+dependencies = [
+ "pin-project-lite",
+ "tokio",
+]
+
+[[package]]
+name = "tokio-macros"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "tokio-stream"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df54d54117d6fdc4e4fea40fe1e4e566b3505700e148a6827e59b34b0d2600d9"
+dependencies = [
+ "futures-core",
+ "pin-project-lite",
+ "tokio",
+]
+
+[[package]]
+name = "tokio-util"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cc463cd8deddc3770d20f9852143d50bf6094e640b485cb2e189a2099085ff45"
+dependencies = [
+ "bytes 1.1.0",
+ "futures-core",
+ "futures-sink",
+ "pin-project-lite",
+ "tokio",
+ "tracing",
+]
+
+[[package]]
+name = "tonic"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5be9d60db39854b30b835107500cf0aca0b0d14d6e1c3de124217c23a29c2ddb"
+dependencies = [
+ "async-stream",
+ "async-trait",
+ "axum",
+ "base64",
+ "bytes 1.1.0",
+ "flate2",
+ "futures-core",
+ "futures-util",
+ "h2",
+ "http",
+ "http-body",
+ "hyper",
+ "hyper-timeout",
+ "percent-encoding",
+ "pin-project",
+ "prost 0.10.4",
+ "prost-derive 0.10.1",
+ "tokio",
+ "tokio-stream",
+ "tokio-util",
+ "tower",
+ "tower-layer",
+ "tower-service",
+ "tracing",
+ "tracing-futures",
+]
+
+[[package]]
+name = "tower"
+version = "0.4.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a89fd63ad6adf737582df5db40d286574513c69a11dac5214dc3b5603d6713e"
+dependencies = [
+ "futures-core",
+ "futures-util",
+ "indexmap",
+ "pin-project",
+ "pin-project-lite",
+ "rand",
+ "slab",
+ "tokio",
+ "tokio-util",
+ "tower-layer",
+ "tower-service",
+ "tracing",
+]
+
+[[package]]
+name = "tower-http"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c530c8675c1dbf98facee631536fa116b5fb6382d7dd6dc1b118d970eafe3ba"
+dependencies = [
+ "bitflags",
+ "bytes 1.1.0",
+ "futures-core",
+ "futures-util",
+ "http",
+ "http-body",
+ "http-range-header",
+ "pin-project-lite",
+ "tower",
+ "tower-layer",
+ "tower-service",
+]
+
+[[package]]
+name = "tower-layer"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "343bc9466d3fe6b0f960ef45960509f84480bf4fd96f92901afe7ff3df9d3a62"
+
+[[package]]
+name = "tower-service"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6"
+
+[[package]]
+name = "tracing"
+version = "0.1.35"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160"
+dependencies = [
+ "cfg-if",
+ "log",
+ "pin-project-lite",
+ "tracing-attributes",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-attributes"
+version = "0.1.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cc6b8ad3567499f98a1db7a752b07a7c8c7c7c34c332ec00effb2b0027974b7c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "tracing-core"
+version = "0.1.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7709595b8878a4965ce5e87ebf880a7d39c9afc6837721b21a5a816a8117d921"
+dependencies = [
+ "once_cell",
+]
+
+[[package]]
+name = "tracing-futures"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2"
+dependencies = [
+ "pin-project",
+ "tracing",
+]
+
+[[package]]
+name = "try-lock"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c"
+
+[[package]]
+name = "want"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
+dependencies = [
+ "log",
+ "try-lock",
+]
+
+[[package]]
+name = "wasi"
+version = "0.11.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "windows-sys"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
+dependencies = [
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_msvc",
+]
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
diff --git a/dubbo/Cargo.toml b/dubbo/Cargo.toml
new file mode 100644
index 0000000..7ce6865
--- /dev/null
+++ b/dubbo/Cargo.toml
@@ -0,0 +1,28 @@
+[package]
+name = "dubbo"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[[bin]]
+name = "helloworld-client"
+path = "src/helloworld/client.rs"
+
+[dependencies]
+h2 = {version = "0.3", optional = true}
+hyper = "0.14.19"
+http = "0.2"
+tonic = {version ="0.7.2", features = ["compression",]}
+tower-service = "0.3.1"
+http-body = "0.4.4"
+tower = "0.4.12"
+futures-util = {version = "0.3", default-features = false}
+tokio = { version = "1.0", features = [ "rt-multi-thread", "time", "fs", "macros", "net", "signal"] }
+prost-derive = {version = "0.10", optional = true}
+prost = "0.10.4"
+prost-types = { version = "0.6", default-features = false }
+lazy_static = "1.3.0"
+async-trait = "0.1.56"
+tower-layer = "0.3"
+
diff --git a/dubbo/readme.md b/dubbo/readme.md
new file mode 100644
index 0000000..0adef95
--- /dev/null
+++ b/dubbo/readme.md
@@ -0,0 +1 @@
+# Introduce
\ No newline at end of file
diff --git a/dubbo/src/common/mod.rs b/dubbo/src/common/mod.rs
new file mode 100644
index 0000000..aff8e30
--- /dev/null
+++ b/dubbo/src/common/mod.rs
@@ -0,0 +1 @@
+pub mod url;
\ No newline at end of file
diff --git a/dubbo/src/common/url.rs b/dubbo/src/common/url.rs
new file mode 100644
index 0000000..879a1a0
--- /dev/null
+++ b/dubbo/src/common/url.rs
@@ -0,0 +1,5 @@
+#[derive(Debug, Clone)]
+pub struct Url {
+ pub url: String,
+ pub service_key: String
+}
\ No newline at end of file
diff --git a/dubbo/src/helloworld/client.rs b/dubbo/src/helloworld/client.rs
new file mode 100644
index 0000000..f4517b4
--- /dev/null
+++ b/dubbo/src/helloworld/client.rs
@@ -0,0 +1,23 @@
+use dubbo::helloworld::helloworld::greeter_client::GreeterClient;
+use dubbo::helloworld::helloworld::HelloRequest;
+
+// pub mod hello_world {
+// tonic::include_proto!("helloworld");
+// }
+
+// cargo run --bin helloworld-client
+
+#[tokio::main]
+async fn main() -> Result<(), Box<dyn std::error::Error>> {
+ let mut client = GreeterClient::connect("http://[::1]:50051").await?;
+
+ let request = tonic::Request::new(HelloRequest {
+ name: "Tonic".into(),
+ });
+
+ let response = client.say_hello(request).await?;
+
+ println!("RESPONSE={:?}", response);
+
+ Ok(())
+}
\ No newline at end of file
diff --git a/dubbo/src/helloworld/helloworld.rs b/dubbo/src/helloworld/helloworld.rs
new file mode 100644
index 0000000..b951157
--- /dev/null
+++ b/dubbo/src/helloworld/helloworld.rs
@@ -0,0 +1,272 @@
+/// The request message containing the user's name.
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct HelloRequest {
+ #[prost(string, tag="1")]
+ pub name: ::prost::alloc::string::String,
+}
+/// The response message containing the greetings
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct HelloReply {
+ #[prost(string, tag="1")]
+ pub message: ::prost::alloc::string::String,
+}
+/// Generated client implementations.
+pub mod greeter_client {
+ #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)]
+ use tonic::codegen::*;
+ /// The greeting service definition.
+ #[derive(Debug, Clone)]
+ pub struct GreeterClient<T> {
+ inner: tonic::client::Grpc<T>,
+ }
+ impl GreeterClient<tonic::transport::Channel> {
+ /// Attempt to create a new client by connecting to a given endpoint.
+ pub async fn connect<D>(dst: D) -> Result<Self, tonic::transport::Error>
+ where
+ D: std::convert::TryInto<tonic::transport::Endpoint>,
+ D::Error: Into<StdError>,
+ {
+ let conn = tonic::transport::Endpoint::new(dst)?.connect().await?;
+ Ok(Self::new(conn))
+ }
+ }
+ impl<T> GreeterClient<T>
+ where
+ T: tonic::client::GrpcService<tonic::body::BoxBody>,
+ T::Error: Into<StdError>,
+ T::ResponseBody: Body<Data = Bytes> + Send + 'static,
+ <T::ResponseBody as Body>::Error: Into<StdError> + Send,
+ {
+ pub fn new(inner: T) -> Self {
+ let inner = tonic::client::Grpc::new(inner);
+ Self { inner }
+ }
+ pub fn with_interceptor<F>(
+ inner: T,
+ interceptor: F,
+ ) -> GreeterClient<InterceptedService<T, F>>
+ where
+ F: tonic::service::Interceptor,
+ T::ResponseBody: Default,
+ T: tonic::codegen::Service<
+ http::Request<tonic::body::BoxBody>,
+ Response = http::Response<
+ <T as tonic::client::GrpcService<tonic::body::BoxBody>>::ResponseBody,
+ >,
+ >,
+ <T as tonic::codegen::Service<
+ http::Request<tonic::body::BoxBody>,
+ >>::Error: Into<StdError> + Send + Sync,
+ {
+ GreeterClient::new(InterceptedService::new(inner, interceptor))
+ }
+ /// Compress requests with `gzip`.
+ ///
+ /// This requires the server to support it otherwise it might respond with an
+ /// error.
+ #[must_use]
+ pub fn send_gzip(mut self) -> Self {
+ self.inner = self.inner.send_gzip();
+ self
+ }
+ /// Enable decompressing responses with `gzip`.
+ #[must_use]
+ pub fn accept_gzip(mut self) -> Self {
+ self.inner = self.inner.accept_gzip();
+ self
+ }
+ /// Sends a greeting
+ pub async fn say_hello(
+ &mut self,
+ request: impl tonic::IntoRequest<super::HelloRequest>,
+ ) -> Result<tonic::Response<super::HelloReply>, tonic::Status> {
+ self.inner
+ .ready()
+ .await
+ .map_err(|e| {
+ tonic::Status::new(
+ tonic::Code::Unknown,
+ format!("Service was not ready: {}", e.into()),
+ )
+ })?;
+ let codec = tonic::codec::ProstCodec::default();
+ let path = http::uri::PathAndQuery::from_static(
+ "/helloworld.Greeter/SayHello",
+ );
+ self.inner.unary(request.into_request(), path, codec).await
+ }
+ }
+}
+/// Generated server implementations.
+pub mod greeter_server {
+ #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)]
+
+ use tonic::codegen::*;
+ use crate::service::protocol::Invoker;
+ use crate::service::grpc::grpc_server::DubboGrpcService;
+ use crate::service::grpc::grpc_server::ServiceDesc;
+
+ ///Generated trait containing gRPC methods that should be implemented for use with GreeterServer.
+ #[async_trait]
+ pub trait Greeter: Send + Sync + 'static {
+ /// Sends a greeting
+ async fn say_hello(
+ &self,
+ request: tonic::Request<super::HelloRequest>,
+ ) -> Result<tonic::Response<super::HelloReply>, tonic::Status>;
+ }
+ /// The greeting service definition.
+ #[derive(Debug)]
+ pub struct GreeterServer<T: Greeter, I> {
+ inner: _Inner<T>,
+ invoker: Option<_Inner<I>>,
+ accept_compression_encodings: EnabledCompressionEncodings,
+ send_compression_encodings: EnabledCompressionEncodings,
+ }
+ struct _Inner<T>(Arc<T>);
+ impl<T: Greeter, I> GreeterServer<T, I> {
+ pub fn new(inner: T) -> Self {
+ Self::from_arc(Arc::new(inner))
+ }
+ pub fn from_arc(inner: Arc<T>) -> Self {
+ let inner = _Inner(inner);
+ Self {
+ inner,
+ invoker: None,
+ accept_compression_encodings: Default::default(),
+ send_compression_encodings: Default::default(),
+ }
+ }
+ pub fn with_interceptor<F>(
+ inner: T,
+ interceptor: F,
+ ) -> InterceptedService<Self, F>
+ where
+ F: tonic::service::Interceptor,
+ {
+ InterceptedService::new(Self::new(inner), interceptor)
+ }
+ /// Enable decompressing requests with `gzip`.
+ #[must_use]
+ pub fn accept_gzip(mut self) -> Self {
+ self.accept_compression_encodings.enable_gzip();
+ self
+ }
+ /// Compress responses with `gzip`, if the client supports it.
+ #[must_use]
+ pub fn send_gzip(mut self) -> Self {
+ self.send_compression_encodings.enable_gzip();
+ self
+ }
+ }
+ impl<T, B, I> tonic::codegen::Service<http::Request<B>> for GreeterServer<T, I>
+ where
+ T: Greeter,
+ B: Body + Send + 'static,
+ B::Error: Into<StdError> + Send + 'static,
+ {
+ type Response = http::Response<tonic::body::BoxBody>;
+ type Error = std::convert::Infallible;
+ type Future = BoxFuture<Self::Response, Self::Error>;
+ fn poll_ready(
+ &mut self,
+ _cx: &mut Context<'_>,
+ ) -> Poll<Result<(), Self::Error>> {
+ Poll::Ready(Ok(()))
+ }
+ fn call(&mut self, req: http::Request<B>) -> Self::Future {
+ let inner = self.inner.clone();
+ match req.uri().path() {
+ "/helloworld.Greeter/SayHello" => {
+ #[allow(non_camel_case_types)]
+ struct SayHelloSvc<T: Greeter>(pub Arc<T>);
+ impl<T: Greeter> tonic::server::UnaryService<super::HelloRequest>
+ for SayHelloSvc<T> {
+ type Response = super::HelloReply;
+ type Future = BoxFuture<
+ tonic::Response<Self::Response>,
+ tonic::Status,
+ >;
+ fn call(
+ &mut self,
+ request: tonic::Request<super::HelloRequest>,
+ ) -> Self::Future {
+ let inner = self.0.clone();
+ let fut = async move { (*inner).say_hello(request).await };
+ Box::pin(fut)
+ }
+ }
+ let accept_compression_encodings = self.accept_compression_encodings;
+ let send_compression_encodings = self.send_compression_encodings;
+ let inner = self.inner.clone();
+ let fut = async move {
+ let inner = inner.0;
+ let method = SayHelloSvc(inner);
+ let codec = tonic::codec::ProstCodec::default();
+ let mut grpc = tonic::server::Grpc::new(codec)
+ .apply_compression_config(
+ accept_compression_encodings,
+ send_compression_encodings,
+ );
+ let res = grpc.unary(method, req).await;
+ Ok(res)
+ };
+ Box::pin(fut)
+ }
+ _ => {
+ Box::pin(async move {
+ Ok(
+ http::Response::builder()
+ .status(200)
+ .header("grpc-status", "12")
+ .header("content-type", "application/grpc")
+ .body(empty_body())
+ .unwrap(),
+ )
+ })
+ }
+ }
+ }
+ }
+ impl<T: Greeter, I: Invoker+ Send+ Sync + 'static> Clone for GreeterServer<T, I> {
+ fn clone(&self) -> Self {
+ let inner = self.inner.clone();
+ Self {
+ inner,
+ invoker: None,
+ // invoker: if let Some(v) = self.invoker.borrow_mut() {
+ // Some(v.clone())
+ // } else {
+ // None
+ // },
+ accept_compression_encodings: self.accept_compression_encodings,
+ send_compression_encodings: self.send_compression_encodings,
+ }
+ }
+
+ }
+
+ impl<T: Greeter> Clone for _Inner<T> {
+ fn clone(&self) -> Self {
+ Self(self.0.clone())
+ }
+ }
+ impl<T: std::fmt::Debug> std::fmt::Debug for _Inner<T> {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ write!(f, "{:?}", self.0)
+ }
+ }
+ impl<T: Greeter, I: Invoker> DubboGrpcService<I> for GreeterServer<T, I> {
+ fn set_proxy_impl(&mut self, invoker: I) {
+ self.invoker = Some(_Inner(Arc::new(invoker)));
+ }
+
+ fn service_desc(&self) -> ServiceDesc {
+ ServiceDesc::new("helloworld.Greeter".to_string(), std::collections::HashMap::new())
+ }
+ }
+
+ impl<T: Greeter, I> tonic::transport::NamedService for GreeterServer<T, I> {
+ const NAME: &'static str = "helloworld.Greeter";
+ }
+}
diff --git a/dubbo/src/helloworld/mod.rs b/dubbo/src/helloworld/mod.rs
new file mode 100644
index 0000000..5f1509d
--- /dev/null
+++ b/dubbo/src/helloworld/mod.rs
@@ -0,0 +1 @@
+pub mod helloworld;
\ No newline at end of file
diff --git a/dubbo/src/helloworld/server.rs b/dubbo/src/helloworld/server.rs
new file mode 100644
index 0000000..e69de29
diff --git a/dubbo/src/lib.rs b/dubbo/src/lib.rs
new file mode 100644
index 0000000..7a10cf1
--- /dev/null
+++ b/dubbo/src/lib.rs
@@ -0,0 +1,6 @@
+pub mod helloworld;
+pub mod service;
+pub mod common;
+pub mod utils;
+
+pub(crate) type Error = Box<dyn std::error::Error + Send + Sync>;
\ No newline at end of file
diff --git a/dubbo/src/main.rs b/dubbo/src/main.rs
new file mode 100644
index 0000000..ecc7b56
--- /dev/null
+++ b/dubbo/src/main.rs
@@ -0,0 +1,10 @@
+pub mod service;
+pub mod common;
+pub mod utils;
+pub mod helloworld;
+
+#[tokio::main]
+async fn main() {
+ println!("hello, dubbo-rust~")
+}
+
diff --git a/dubbo/src/service/grpc/grpc_exporter.rs b/dubbo/src/service/grpc/grpc_exporter.rs
new file mode 100644
index 0000000..2940429
--- /dev/null
+++ b/dubbo/src/service/grpc/grpc_exporter.rs
@@ -0,0 +1,34 @@
+
+use crate::service::protocol::*;
+use crate::service::protocol::Invoker;
+
+pub struct GrpcExporter<T> {
+ invoker: T
+}
+
+impl<T> GrpcExporter<T> {
+ pub fn new(key: String, invoker: T) -> GrpcExporter<T> {
+ Self { invoker }
+ }
+}
+
+impl<T: Invoker+Clone> Exporter for GrpcExporter<T>
+{
+ type InvokerType = T;
+
+ fn unexport(&self) {
+ }
+
+ fn get_invoker(&self) -> Self::InvokerType {
+ self.invoker.clone()
+ }
+
+}
+
+impl<T: Invoker+Clone> Clone for GrpcExporter<T> {
+
+ fn clone(&self) -> Self {
+ Self { invoker: self.invoker.clone() }
+ }
+
+}
\ No newline at end of file
diff --git a/dubbo/src/service/grpc/grpc_invoker.rs b/dubbo/src/service/grpc/grpc_invoker.rs
new file mode 100644
index 0000000..fd48e73
--- /dev/null
+++ b/dubbo/src/service/grpc/grpc_invoker.rs
@@ -0,0 +1,73 @@
+use std::sync::Once;
+
+use tonic::client::Grpc;
+use tonic::transport::Channel;
+use tonic::transport::Endpoint;
+
+use crate::service::protocol::*;
+use crate::service::invocation;
+use crate::common::url::Url;
+
+pub struct GrpcInvoker {
+ client: Grpc<Channel>,
+ url: Url,
+ once: Once
+}
+
+
+
+impl GrpcInvoker {
+ pub fn new(url: Url) -> GrpcInvoker {
+
+ let endpoint = Endpoint::new(url.url.clone()).unwrap();
+ let conn = endpoint.connect_lazy();
+ Self {
+ url,
+ client: Grpc::new(conn),
+ once: Once::new()
+ }
+ }
+}
+
+impl Invoker for GrpcInvoker {
+
+ fn is_available(&self) -> bool {
+ true
+ }
+
+ fn destroy(&self) {
+ self.once.call_once(|| {
+ println!("destroy...")
+ })
+ }
+
+ fn get_url(&self) -> Url {
+ self.url.to_owned()
+ }
+
+ // 根据req中的数据发起req,由Client发起请求,获取响应
+ fn invoke<M1>(&self, req: invocation::Request<M1>) -> invocation::Response<String>
+ where
+ M1: Send + 'static,
+ {
+ let (metadata, _) = req.into_parts();
+
+ let resp = invocation::Response::new("string");
+ let (resp_meta, msg) = resp.into_parts();
+
+ invocation::Response::from_parts(metadata, msg.to_string())
+ }
+}
+
+impl<T> invocation::Request<T> {
+
+ pub(crate) fn to_tonic_req(self) -> tonic::Request<T> {
+ tonic::Request::new(self.message)
+ }
+}
+
+impl Clone for GrpcInvoker {
+ fn clone(&self) -> Self {
+ Self { client: self.client.clone(), url: self.url.clone(), once: Once::new() }
+ }
+}
\ No newline at end of file
diff --git a/dubbo/src/service/grpc/grpc_protocol.rs b/dubbo/src/service/grpc/grpc_protocol.rs
new file mode 100644
index 0000000..08fe921
--- /dev/null
+++ b/dubbo/src/service/grpc/grpc_protocol.rs
@@ -0,0 +1,60 @@
+
+use std::collections::HashMap;
+
+use super::grpc_invoker::GrpcInvoker;
+use super::grpc_exporter::GrpcExporter;
+use crate::common::url::Url;
+use crate::service::protocol::Protocol;
+use super::grpc_server::GrpcServer;
+
+pub struct GrpcProtocol {
+ server_map: HashMap<String, GrpcServer>,
+ export_map: HashMap<String, GrpcExporter<GrpcInvoker>>
+}
+
+impl GrpcProtocol {
+ pub fn new() -> Self {
+ Self {
+ server_map: HashMap::new(),
+ export_map: HashMap::new(),
+ }
+ }
+}
+
+impl Default for GrpcProtocol {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
+#[async_trait::async_trait]
+impl Protocol for GrpcProtocol
+{
+ type Invoker = GrpcInvoker;
+
+ type Exporter = GrpcExporter<Self::Invoker>;
+
+ fn destroy(&self) {
+ todo!()
+ }
+
+ async fn refer(&self, url: Url) -> Self::Invoker {
+ GrpcInvoker::new(url)
+ }
+
+ async fn export(self, url: Url) -> Self::Exporter {
+ let service_key = url.service_key.clone();
+
+ let exporter: GrpcExporter<GrpcInvoker> = GrpcExporter::new(service_key.clone(), GrpcInvoker::new(url.clone()));
+ let mut export = self.export_map;
+ export.insert(service_key.clone(), exporter.clone());
+
+ // 启动服务
+
+ let server = super::grpc_server::GrpcServer::new(service_key.clone());
+ let mut server_map = self.server_map;
+ server_map.insert(service_key.clone(), server.clone());
+ server.serve(url.clone()).await;
+ exporter
+ }
+}
\ No newline at end of file
diff --git a/dubbo/src/service/grpc/grpc_server.rs b/dubbo/src/service/grpc/grpc_server.rs
new file mode 100644
index 0000000..3a9c6a8
--- /dev/null
+++ b/dubbo/src/service/grpc/grpc_server.rs
@@ -0,0 +1,116 @@
+use std::collections::HashMap;
+use std::task::Context;
+use std::task::Poll;
+
+use tonic::transport;
+use tower::Service;
+use tonic::transport::NamedService;
+use tonic::codegen::BoxFuture;
+
+
+use crate::common::url::Url;
+use crate::helloworld::helloworld::greeter_server::GreeterServer;
+use super::grpc_invoker::GrpcInvoker;
+use crate::helloworld::helloworld::greeter_server::*;
+use crate::utils::boxed_clone::BoxCloneService;
+
+pub trait DubboGrpcService<T>
+{
+ fn set_proxy_impl(&mut self, invoker: T);
+ fn service_desc(&self) -> ServiceDesc;
+}
+
+//type ServiceDesc struct {
+// ServiceName string
+// // The pointer to the service interface. Used to check whether the user
+// // provided implementation satisfies the interface requirements.
+// HandlerType interface{}
+// Methods []MethodDesc
+// Streams []StreamDesc
+// Metadata interface{}
+// }
+
+pub struct ServiceDesc {
+ service_name: String,
+ methods: HashMap<String, String> // "/Greeter/hello": "unary"
+}
+
+impl ServiceDesc {
+ pub fn new(service_name: String, methods: HashMap<String, String>) -> Self {
+ Self { service_name, methods }
+ }
+
+ pub fn get_service_name(&self) -> String {
+ self.service_name.clone()
+ }
+}
+
+// codegen
+pub fn register_greeter_server<T: Greeter>(server: T) -> (super::GrpcBoxCloneService, super::DubboGrpcBox) {
+ let hello = GreeterServer::<T, GrpcInvoker>::new(server);
+ (BoxCloneService::new(hello.clone()), Box::new(hello.clone()))
+}
+
+// 每个service对应一个Server
+#[derive(Clone)]
+pub struct GrpcServer {
+ inner: transport::Server,
+ name: String,
+}
+
+impl GrpcServer
+{
+ pub fn new(name: String) -> GrpcServer {
+ Self {
+ inner: transport::Server::builder(),
+ name
+ }
+ }
+
+ pub async fn serve(mut self, url: Url)
+ where
+ {
+ let addr = url.url.clone().parse().unwrap();
+ let svc = super::GRPC_SERVICES.read().unwrap().get(self.name.as_str()).unwrap().clone();
+ println!("server{:?} start...", url);
+ self.inner.add_service(MakeSvc::new(svc)).serve(
+ addr
+ ).await.unwrap();
+ println!("server{:?} start...", url);
+ }
+
+}
+
+struct MakeSvc<T, U, E> {
+ inner: BoxCloneService<T, U, E>
+}
+
+impl<T, U, E> MakeSvc<T, U, E> {
+ pub fn new(inner: BoxCloneService<T, U, E>) -> Self {
+ Self { inner}
+ }
+}
+
+impl<T, U, E> NamedService for MakeSvc<T, U, E> {
+ const NAME: &'static str = "helloworld.Greeter";
+}
+
+impl<T, U, E> Service<T> for MakeSvc<T, U, E> {
+ type Response = U;
+ type Error = E;
+ type Future = BoxFuture<U, E>;
+
+ fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), E>> {
+ self.inner.poll_ready(cx)
+ }
+
+ fn call(&mut self, request: T) -> BoxFuture<U, E> {
+ self.inner.call(request)
+ }
+}
+
+impl<T, U, E> Clone for MakeSvc<T, U, E> {
+ fn clone(&self) -> Self {
+ Self { inner: self.inner.clone() }
+ }
+}
\ No newline at end of file
diff --git a/dubbo/src/service/grpc/mod.rs b/dubbo/src/service/grpc/mod.rs
new file mode 100644
index 0000000..3350638
--- /dev/null
+++ b/dubbo/src/service/grpc/mod.rs
@@ -0,0 +1,59 @@
+pub mod grpc_protocol;
+pub mod grpc_invoker;
+pub mod grpc_exporter;
+pub mod grpc_server;
+
+use std::collections::HashMap;
+use std::sync::RwLock;
+use lazy_static::lazy_static;
+
+use grpc_server::DubboGrpcService;
+use grpc_invoker::GrpcInvoker;
+use crate::helloworld::helloworld::greeter_server::Greeter;
+use crate::utils::boxed_clone::BoxCloneService;
+use crate::helloworld::helloworld::{HelloRequest, HelloReply};
+
+pub type GrpcBoxCloneService = BoxCloneService<http::Request<hyper::Body>, http::Response<tonic::body::BoxBody>, std::convert::Infallible>;
+
+pub type DubboGrpcBox = Box<dyn DubboGrpcService<GrpcInvoker>+ Send + Sync + 'static>;
+
+lazy_static! {
+ pub static ref DUBBO_GRPC_SERVICES: RwLock<HashMap<String, Box<dyn DubboGrpcService<GrpcInvoker> + Send + Sync + 'static>>> = RwLock::new(HashMap::new());
+ pub static ref GRPC_SERVICES: RwLock<HashMap<String, GrpcBoxCloneService>> = RwLock::new(HashMap::new());
+}
+
+#[tokio::test]
+async fn test_hello() {
+ use grpc_server::register_greeter_server;
+ use crate::service::protocol::Protocol;
+ use crate::common::url::Url;
+
+ let (svc, dubbo_svc) = register_greeter_server(MyGreeter{});
+ let svc_name = dubbo_svc.service_desc().get_service_name();
+ DUBBO_GRPC_SERVICES.write().unwrap().insert(svc_name.clone(), dubbo_svc);
+ GRPC_SERVICES.write().unwrap().insert(svc_name.clone(), svc);
+
+ // server start, api: 0.0.0.0:8888/helloworld.Greeter/SayHello
+ let pro = grpc_protocol::GrpcProtocol::new();
+ pro.export(Url{url: "[::1]:50051".to_string(), service_key: svc_name.clone()}).await;
+
+}
+
+
+#[derive(Default)]
+pub struct MyGreeter {}
+
+#[tonic::async_trait]
+impl Greeter for MyGreeter {
+ async fn say_hello(
+ &self,
+ request: tonic::Request<HelloRequest>,
+ ) -> Result<tonic::Response<HelloReply>, tonic::Status> {
+ println!("Got a request from {:?}", request.remote_addr());
+
+ let reply = HelloReply {
+ message: format!("Hello {}!", request.into_inner().name),
+ };
+ Ok(tonic::Response::new(reply))
+ }
+}
\ No newline at end of file
diff --git a/dubbo/src/service/invocation.rs b/dubbo/src/service/invocation.rs
new file mode 100644
index 0000000..dff46fa
--- /dev/null
+++ b/dubbo/src/service/invocation.rs
@@ -0,0 +1,45 @@
+use tonic::metadata::MetadataMap;
+
+pub struct Request<T> {
+ pub message: T,
+ pub metadata: MetadataMap,
+}
+
+
+impl<T> Request<T> {
+ pub fn new(message: T) -> Request<T> {
+ Self {
+ message,
+ metadata: MetadataMap::new()
+ }
+ }
+
+ pub fn into_parts(self) -> (MetadataMap, T) {
+ (self.metadata, self.message)
+ }
+}
+
+pub struct Response<T> {
+ message: T,
+ metadata: MetadataMap,
+}
+
+impl<T> Response<T> {
+ pub fn new(message: T) -> Response<T> {
+ Self {
+ message,
+ metadata: MetadataMap::new(),
+ }
+ }
+
+ pub fn from_parts(metadata: MetadataMap, message: T) -> Self {
+ Self {
+ message,
+ metadata,
+ }
+ }
+
+ pub fn into_parts(self) -> (MetadataMap, T) {
+ (self.metadata, self.message)
+ }
+}
\ No newline at end of file
diff --git a/dubbo/src/service/mod.rs b/dubbo/src/service/mod.rs
new file mode 100644
index 0000000..55bcb2f
--- /dev/null
+++ b/dubbo/src/service/mod.rs
@@ -0,0 +1,4 @@
+pub mod protocol;
+pub mod grpc;
+pub mod invocation;
+
diff --git a/dubbo/src/service/protocol.rs b/dubbo/src/service/protocol.rs
new file mode 100644
index 0000000..18d2d7b
--- /dev/null
+++ b/dubbo/src/service/protocol.rs
@@ -0,0 +1,31 @@
+use super::invocation;
+use crate::common::url::Url;
+
+use async_trait::async_trait;
+
+#[async_trait]
+pub trait Protocol {
+ type Invoker;
+ type Exporter;
+
+ fn destroy(&self);
+ async fn export(self, url: Url) -> Self::Exporter;
+ async fn refer(&self, url: Url) -> Self::Invoker;
+}
+
+
+pub trait Exporter {
+ type InvokerType: Invoker;
+
+ fn unexport(&self);
+ fn get_invoker(&self) -> Self::InvokerType;
+}
+
+pub trait Invoker {
+ fn invoke<M1>(&self, req: invocation::Request<M1>) -> invocation::Response<String>
+ where
+ M1: Send + 'static;
+ fn is_available(&self) -> bool;
+ fn destroy(&self);
+ fn get_url(&self) -> Url;
+}
\ No newline at end of file
diff --git a/dubbo/src/utils/boxed.rs b/dubbo/src/utils/boxed.rs
new file mode 100644
index 0000000..63297e9
--- /dev/null
+++ b/dubbo/src/utils/boxed.rs
@@ -0,0 +1,74 @@
+use tower::ServiceExt;
+use tower_layer::{layer_fn, LayerFn};
+use tower_service::Service;
+
+use std::fmt;
+use std::{
+ future::Future,
+ pin::Pin,
+ task::{Context, Poll},
+};
+
+/// A boxed `Service + Send` trait object.
+///
+/// [`BoxService`] turns a service into a trait object, allowing the response
+/// future type to be dynamic. This type requires both the service and the
+/// response future to be [`Send`].
+///
+/// If you need a boxed [`Service`] that implements [`Clone`] consider using
+/// [`BoxCloneService`](crate::util::BoxCloneService).
+///
+/// See module level documentation for more details.
+pub struct BoxService<T, U, E> {
+ inner: Box<dyn Service<T, Response = U, Error = E, Future = BoxFuture<U, E>> + Send+ Sync+>,
+}
+
+/// A boxed `Future + Send` trait object.
+///
+/// This type alias represents a boxed future that is [`Send`] and can be moved
+/// across threads.
+type BoxFuture<T, E> = Pin<Box<dyn Future<Output = Result<T, E>> + Send>>;
+
+impl<T, U, E> BoxService<T, U, E> {
+ #[allow(missing_docs)]
+ pub fn new<S>(inner: S) -> Self
+ where
+ S: Service<T, Response = U, Error = E> + Send + Sync + 'static,
+ S::Future: Send + 'static,
+ {
+ let inner = Box::new(inner.map_future(|f: S::Future| Box::pin(f) as _));
+ BoxService { inner }
+ }
+
+ // /// Returns a [`Layer`] for wrapping a [`Service`] in a [`BoxService`]
+ // /// middleware.
+ // ///
+ // /// [`Layer`]: crate::Layer
+ pub fn layer<S>() -> LayerFn<fn(S) -> Self>
+ where
+ S: Service<T, Response = U, Error = E> + Send + Sync + 'static,
+ S::Future: Send + 'static,
+ {
+ layer_fn(Self::new)
+ }
+}
+
+impl<T, U, E> Service<T> for BoxService<T, U, E> {
+ type Response = U;
+ type Error = E;
+ type Future = BoxFuture<U, E>;
+
+ fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), E>> {
+ self.inner.poll_ready(cx)
+ }
+
+ fn call(&mut self, request: T) -> BoxFuture<U, E> {
+ self.inner.call(request)
+ }
+}
+
+impl<T, U, E> fmt::Debug for BoxService<T, U, E> {
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ fmt.debug_struct("BoxService").finish()
+ }
+}
diff --git a/dubbo/src/utils/boxed_clone.rs b/dubbo/src/utils/boxed_clone.rs
new file mode 100644
index 0000000..0e5e6c3
--- /dev/null
+++ b/dubbo/src/utils/boxed_clone.rs
@@ -0,0 +1,88 @@
+use tower::ServiceExt;
+use futures_util::future::BoxFuture;
+use std::{
+ fmt,
+ task::{Context, Poll},
+};
+use tower_layer::{layer_fn, LayerFn};
+use tower_service::Service;
+
+pub struct BoxCloneService<T, U, E>(
+ Box<
+ dyn CloneService<T, Response = U, Error = E, Future = BoxFuture<'static, Result<U, E>>>
+ + Send+Sync,
+ >,
+);
+
+impl<T, U, E> BoxCloneService<T, U, E> {
+ /// Create a new `BoxCloneService`.
+ pub fn new<S>(inner: S) -> Self
+ where
+ S: Service<T, Response = U, Error = E> + Clone + Send + Sync + 'static,
+ S::Future: Send + 'static,
+ {
+ let inner = inner.map_future(|f| Box::pin(f) as _);
+ BoxCloneService(Box::new(inner))
+ }
+
+ /// Returns a [`Layer`] for wrapping a [`Service`] in a [`BoxCloneService`]
+ /// middleware.
+ ///
+ /// [`Layer`]: crate::Layer
+ pub fn layer<S>() -> LayerFn<fn(S) -> Self>
+ where
+ S: Service<T, Response = U, Error = E> + Clone + Send + Sync + 'static,
+ S::Future: Send + 'static,
+ {
+ layer_fn(Self::new)
+ }
+}
+
+impl<T, U, E> Service<T> for BoxCloneService<T, U, E> {
+ type Response = U;
+ type Error = E;
+ type Future = BoxFuture<'static, Result<U, E>>;
+
+ #[inline]
+ fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), E>> {
+ self.0.poll_ready(cx)
+ }
+
+ #[inline]
+ fn call(&mut self, request: T) -> Self::Future {
+ self.0.call(request)
+ }
+}
+
+impl<T, U, E> Clone for BoxCloneService<T, U, E> {
+ fn clone(&self) -> Self {
+ Self(self.0.clone_box())
+ }
+}
+
+trait CloneService<R>: Service<R> {
+ fn clone_box(
+ &self,
+ ) -> Box<
+ dyn CloneService<R, Response = Self::Response, Error = Self::Error, Future = Self::Future>
+ + Send + Sync,
+ >;
+}
+
+impl<R, T> CloneService<R> for T
+where
+ T: Service<R> + Send + Sync + Clone + 'static,
+{
+ fn clone_box(
+ &self,
+ ) -> Box<dyn CloneService<R, Response = T::Response, Error = T::Error, Future = T::Future> + Send + Sync>
+ {
+ Box::new(self.clone())
+ }
+}
+
+impl<T, U, E> fmt::Debug for BoxCloneService<T, U, E> {
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ fmt.debug_struct("BoxCloneService").finish()
+ }
+}
diff --git a/dubbo/src/utils/mod.rs b/dubbo/src/utils/mod.rs
new file mode 100644
index 0000000..a3bbaaa
--- /dev/null
+++ b/dubbo/src/utils/mod.rs
@@ -0,0 +1,2 @@
+pub mod boxed;
+pub mod boxed_clone;
\ No newline at end of file
diff --git a/protocol/Cargo.toml b/protocol/Cargo.toml
deleted file mode 100644
index 77c8260..0000000
--- a/protocol/Cargo.toml
+++ /dev/null
@@ -1,8 +0,0 @@
-[package]
-name = "protocol"
-version = "0.1.0"
-edition = "2021"
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]
diff --git a/protocol/src/lib.rs b/protocol/src/lib.rs
deleted file mode 100644
index 3e01853..0000000
--- a/protocol/src/lib.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#[cfg(test)]
-mod tests {
- #[test]
- fn it_works() {
- let result = 2 + 2;
- assert_eq!(result, 4);
- }
-}