這篇文章給大家分享的是有關(guān)DotBPE.RPC的示例分析的內(nèi)容。小編覺得挺實(shí)用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
創(chuàng)新互聯(lián)主要從事網(wǎng)站設(shè)計制作、網(wǎng)站設(shè)計、網(wǎng)頁設(shè)計、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)大足,10多年網(wǎng)站建設(shè)經(jīng)驗(yàn),價格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):13518219792
DotBPE.RPC是一款基于dotnet core編寫的RPC框架,而它的爸爸DotBPE,目標(biāo)是實(shí)現(xiàn)一個開箱即用的微服務(wù)框架,但是它還差點(diǎn)意思,還僅僅在構(gòu)思和嘗試的階段。但不管怎么說RPC是微服務(wù)的基礎(chǔ),先來講講RPC的實(shí)現(xiàn)吧。DotBPE.RPC底層通信默認(rèn)實(shí)現(xiàn)基于DotNetty,這是由微軟Azure團(tuán)隊(duì)開發(fā)的C#的Netty實(shí)現(xiàn),非常酷。當(dāng)然你也可以替換成其他Socket通信組件。DotBPE.RPC使用的默認(rèn)協(xié)議名稱叫Amp,編解碼使用谷歌的Protobuf3,不過這些默認(rèn)實(shí)現(xiàn)都是可以替換的。
undefined
Amp(A Message Protocol) ,中文名叫 一個消息協(xié)議 ,是DotBPE.RPC默認(rèn)實(shí)現(xiàn)的消息協(xié)議,在實(shí)際開發(fā)中,其實(shí)是不需要了解消息是如何編解碼和傳輸?shù)模橇私鈪f(xié)議有助于進(jìn)一步了解框架。協(xié)議基本結(jié)構(gòu)如下圖所示:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 <length>-14 +------------+----------+---------+------+-------+---------+------------+ | <ver/argc> | <length> | <seq> |<type>|<serId>| <msgid> | <data> | +------------+----------+---------+------+-------+---------+------------+
Amp協(xié)議默認(rèn)消息頭長為14個字節(jié),不包含擴(kuò)展包頭
第0位:ver/argc // 為版本號,暫時來說,默認(rèn)為0
第1-4位: length //為包總長度(含包頭長度)
第5-8位: sequence // 為消息序列號,通過該序列號對應(yīng) 請求<--->響應(yīng)
第9位: type // 消息類型,現(xiàn)值有5種,如下:
Request = 1, Response = 2, Notify = 3,NotFound = 4, ERROR = 5
第10-11位: serviceId//消息ID ushort類型
第12-13位: msgId//消息ID ushort類型
在Amp協(xié)議中,serviceId標(biāo)識一類請求,類似應(yīng)用中的模塊,而msgId標(biāo)識模塊中的具體方法
其后緊跟實(shí)際的數(shù)據(jù)
Google Protocol Buffer( 簡稱 Protobuf) 是 Google 公司內(nèi)部的混合語言數(shù)據(jù)標(biāo)準(zhǔn),目前已經(jīng)正在使用的有超過 48,162 種報文格式定義和超過 12,183 個 .proto 文件。他們用于 RPC 系統(tǒng)和持續(xù)數(shù)據(jù)存儲系統(tǒng)。
Protocol Buffers 是一種輕便高效的結(jié)構(gòu)化數(shù)據(jù)存儲格式,可以用于結(jié)構(gòu)化數(shù)據(jù)串行化,或者說序列化。它很適合做數(shù)據(jù)存儲或 RPC 數(shù)據(jù)交換格式。可用于通訊協(xié)議、數(shù)據(jù)存儲等領(lǐng)域的語言無關(guān)、平臺無關(guān)、可擴(kuò)展的序列化結(jié)構(gòu)數(shù)據(jù)格式。目前提供了 多種語言的API,包括C++、 C# 、GO、 JAVA、 PYTHON
我在之前的博客使用CSharp編寫Google Protobuf插件中有過介紹如果通過編寫插件的方式,來通過定義proto文件,并生成我們需要的代碼。
在DotBPE.RPC 中,我使用protobuf來作為服務(wù)的描述文件,并通過自定義的插件方式來生成服務(wù)端和客戶端代理類。
因?yàn)镈otBPE是基于dotnet core開發(fā)的,你本地必須已經(jīng)有了dotnet core開發(fā)環(huán)境
使用github托管代碼,所以你必須已經(jīng)安裝了git客戶端
需要通過protoc生成模板代碼,所以你必須已經(jīng)安裝了google protobuf命令行工具
為了能夠解釋我們的快速開始程序,你需要一份本地能夠運(yùn)行的示例代碼。從github上下載我已經(jīng)寫好的示例代碼,可以讓你快速的搭建程序,免去一些繁瑣,但是又必須的步驟。
>$ # Clone the repository to get the example code: >$ git clone https://github.com/xuanye/dotbpe-sample.git >$ cd dotbpe-sample
使用VS2017,或者VSCode打開下載好的代碼,目錄結(jié)構(gòu)如下所示:
如果你使用VS2017 可以自動幫你還原,如果使用VSCode的話 ,需要運(yùn)行dotnet restore 下載依賴,成功后使用dotnet build 編譯一下看看結(jié)果:看著很完美
>$ cd HelloDotBPE.Server >$ dotnet run
>$ cd HelloDotBPE.Client >$ dotnet run
恭喜!已經(jīng)使用DotBPE.RPC運(yùn)行一個Server/Client的應(yīng)用程序。
首先是DotBPE.RPC框架中對proto的擴(kuò)展文件,所有的項(xiàng)目都需要這個文件,關(guān)于如何擴(kuò)展proto,我的這篇博客有比較詳細(xì)的介紹,這里就不重復(fù)說了
//dotbpe_option.proto 文件
syntax = "proto3";
package dotbpe;
option csharp_namespace = "DotBPE.ProtoBuf";
import "google/protobuf/descriptor.proto";
//擴(kuò)展服務(wù)
extend google.protobuf.ServiceOptions {
int32 service_id = 51001;
bool disable_generic_service_client = 51003; //禁止生成客戶端代碼
bool disable_generic_service_server = 51004; //禁止生成服務(wù)端代碼
}
extend google.protobuf.MethodOptions {
int32 message_id = 51002;
}
extend google.protobuf.FileOptions {
bool disable_generic_services_client = 51003; //禁止生成客戶端代碼
bool disable_generic_services_server = 51004; //禁止生成服務(wù)端代碼
bool generic_markdown_doc = 51005; //是否生成文檔 本示例中無用
bool generic_objectfactory = 51006; //是否生成objectfactory 本示例中無用
}下面的服務(wù)描述文件 greeter.proto 才是真正的示例的服務(wù)描述文件:比較簡單,定義一個Greeter Rpc服務(wù),并定義一個Hello的方法
//greeter.proto
syntax = "proto3";
package dotbpe;
option csharp_namespace = "HelloDotBPE.Common";
// 引入擴(kuò)展
import public "dotbpe_option.proto";
// 定義一個服務(wù)
service Greeter {
option (service_id)= 100 ;//消息ID,全局必須唯一
// Sends a greeting
rpc Hello (HelloRequest) returns (HelloResponse) {
option (message_id)= 1 ;//設(shè)定消息ID,同一服務(wù)內(nèi)唯一
}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloResponse {
string message = 1;
}通過protoc工具生成模板代碼,示例中的代碼生成到了 HelloDotBPE.Common_g 目錄下,本地可以運(yùn)行shell命令的同學(xué)可以直接到
dotbpe-sample\script\generate 目錄運(yùn)行sh generate_hello.sh (windows下一般安裝cgywin),不能運(yùn)行的同學(xué)也可以在HelloDotBPE目錄下,直接運(yùn)行命令行
protoc -I=../protos --csharp_out=./HelloDotBPE.Common/_g/ --dotbpe_out=./HelloDotBPE.Common/_g/ ../protos/dotbpe_option.proto ../protos/greeter.proto --plugin=protoc-gen-dotbpe=../../tool/protoc_plugin/Protobuf.Gen.exe
當(dāng)然我還是建議大家安裝以下cgywin運(yùn)行環(huán)境,可以運(yùn)行unix上的一些常用命令。同時在部署到正式環(huán)境的時候可以公用開發(fā)環(huán)境的一些腳本。
服務(wù)實(shí)現(xiàn):
// 服務(wù)實(shí)現(xiàn)代碼
public class GreeterImpl : GreeterBase
{
public override Task<HelloResponse> HelloAsync(HelloRequest request)
{
// 直接返回Hello Name
return Task.FromResult(new HelloResponse() { Message = "Hello " + request.Name });
}
}服務(wù)端啟動類
public class Startup : IStartup
{
public void Configure(IAppBuilder app, IHostingEnvironment env)
{
}
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddDotBPE(); // 添加DotBPE.RPC的核心依賴
services.AddServiceActors<AmpMessage>(actors => {
actors.Add<GreeterImpl>(); // 注冊服務(wù)實(shí)現(xiàn)
});
return services.BuildServiceProvider();
}
}啟動服務(wù)端
class Program
{
static void Main(string[] args)
{
Console.OutputEncoding = System.Text.Encoding.UTF8;
//在控制臺輸出調(diào)試日志
DotBPE.Rpc.Environment.SetLogger(new DotBPE.Rpc.Logging.ConsoleLogger());
var host = new RpcHostBuilder()
.UseServer("0.0.0.0:6201") //綁定本地端口6201
.UseStartup<Startup>()
.Build();
host.StartAsync().Wait();
Console.WriteLine("Press any key to quit!");
Console.ReadKey();
host.ShutdownAsync().Wait();
}
} class Program
{
static void Main(string[] args)
{
Console.OutputEncoding = Encoding.UTF8;
var client = AmpClient.Create("127.0.0.1:6201"); //建立鏈接通道
var greeter = new GreeterClient(client); //客戶端代理類
while (true)
{
Console.WriteLine("input your name and press enter:");
string name = Console.ReadLine();
if ("bye".Equals(name))
{
break;
}
try
{
var request = new HelloRequest() { Name = name };
var result = greeter.HelloAsync(request).Result;
Console.WriteLine($"---------------receive form server:{result.Message}-----------");
}
catch (Exception ex)
{
Console.WriteLine("發(fā)生錯誤:" + ex.Message);
}
}
Console.WriteLine($"---------------close connection-----------");
client.CloseAsync();
}
}感謝各位的閱讀!關(guān)于“DotBPE.RPC的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學(xué)到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
當(dāng)前標(biāo)題:DotBPE.RPC的示例分析
當(dāng)前地址:http://www.chinadenli.net/article28/pgcdjp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供電子商務(wù)、網(wǎng)站設(shè)計、定制開發(fā)、微信小程序、Google、商城網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)