当前位置: 首页 > news >正文

装修素材网站有哪些竞价推广怎么样

装修素材网站有哪些,竞价推广怎么样,在网站做推广属于广告费吗,做网站分前台后端吗1、proto数据验证 本篇将介绍grpc_validator,它可以对gRPC数据的输入和输出进行验证。 这里复用上一篇文章的代码。 1.1 创建proto文件,添加验证规则 这里使用第三方插件go-proto-validators 自动生成验证规则。 地址:https://github.co…

1、proto数据验证

本篇将介绍grpc_validator,它可以对gRPC数据的输入和输出进行验证。

这里复用上一篇文章的代码。

1.1 创建proto文件,添加验证规则

这里使用第三方插件go-proto-validators 自动生成验证规则。

地址:https://github.com/mwitkow/go-proto-validators

$ go get github.com/mwitkow/go-proto-validators
1.1.1 新建simple.proto文件
syntax = "proto3";
package proto;
option go_package = "./proto;proto";// validator.proto是github.com/mwitkow/go-proto-validators/validator.proto
import "validator.proto";message InnerMessage {// some_integer can only be in range (1, 100).int32 some_integer = 1 [(validator.field) = {int_gt: 0, int_lt: 100}];// some_float can only be in range (0;1).double some_float = 2 [(validator.field) = {float_gte: 0, float_lte: 1}];
}message OuterMessage {// important_string must be a lowercase alpha-numeric of 5 to 30 characters (RE2 syntax).string important_string = 1 [(validator.field) = {regex: "^[a-z]{2,5}$"}];// proto3 doesn't have `required`, the `msg_exist` enforces presence of InnerMessage.InnerMessage inner = 2 [(validator.field) = {msg_exists: true}];
}service Simple {rpc Route (InnerMessage) returns (OuterMessage) {};
}

validator.proto文件内容:

// Copyright 2016 Michal Witkowski. All Rights Reserved.
// See LICENSE for licensing terms.// Protocol Buffers extensions for defining auto-generateable validators for messages.// TODO(mwitkow): Add example.syntax = "proto2";
package validator;import "google/protobuf/descriptor.proto";option go_package = "github.com/mwitkow/go-proto-validators;validator";// TODO(mwitkow): Email protobuf-global-extension-registry@google.com to get an extension ID.extend google.protobuf.FieldOptions {optional FieldValidator field = 65020;
}extend google.protobuf.OneofOptions {optional OneofValidator oneof = 65021;
}message FieldValidator {// Uses a Golang RE2-syntax regex to match the field contents.optional string regex = 1;// Field value of integer strictly greater than this value.optional int64 int_gt = 2;// Field value of integer strictly smaller than this value.optional int64 int_lt = 3;// Used for nested message types, requires that the message type exists.optional bool msg_exists = 4;// Human error specifies a user-customizable error that is visible to the user.optional string human_error = 5;// Field value of double strictly greater than this value.// Note that this value can only take on a valid floating point// value. Use together with float_epsilon if you need something more specific.optional double float_gt = 6;// Field value of double strictly smaller than this value.// Note that this value can only take on a valid floating point// value. Use together with float_epsilon if you need something more specific.optional double float_lt = 7;// Field value of double describing the epsilon within which// any comparison should be considered to be true. For example,// when using float_gt = 0.35, using a float_epsilon of 0.05// would mean that any value above 0.30 is acceptable. It can be// thought of as a {float_value_condition} +- {float_epsilon}.// If unset, no correction for floating point inaccuracies in// comparisons will be attempted.optional double float_epsilon = 8;// Floating-point value compared to which the field content should be greater or equal.optional double float_gte = 9;// Floating-point value compared to which the field content should be smaller or equal.optional double float_lte = 10;// Used for string fields, requires the string to be not empty (i.e different from "").optional bool string_not_empty = 11;// Repeated field with at least this number of elements.optional int64 repeated_count_min = 12;// Repeated field with at most this number of elements.optional int64 repeated_count_max = 13;// Field value of length greater than this value.optional int64 length_gt = 14;// Field value of length smaller than this value.optional int64 length_lt = 15;// Field value of length strictly equal to this value.optional int64 length_eq = 16;// Requires that the value is in the enum.optional bool is_in_enum = 17;// Ensures that a string value is in UUID format.// uuid_ver specifies the valid UUID versions. Valid values are: 0-5.// If uuid_ver is 0 all UUID versions are accepted.optional int32 uuid_ver = 18;
}message OneofValidator {// Require that one of the oneof fields is set.optional bool required = 1;
}
1.1.2 编译simple.proto文件
$ go get github.com/mwitkow/go-proto-validators/protoc-gen-govalidators
$ go install github.com/mwitkow/go-proto-validators/protoc-gen-govalidators
$ protoc --govalidators_out=. --go_out=plugins=grpc:. simple.proto

编译完成后,自动生成simple.pb.gosimple.validator.pb.go文件,simple.pb.go文件不再介绍,我们

看下simple.validator.pb.go文件。

// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: simple.protopackage protoimport (fmt "fmt"math "math"proto "github.com/golang/protobuf/proto"_ "github.com/mwitkow/go-proto-validators"regexp "regexp"github_com_mwitkow_go_proto_validators "github.com/mwitkow/go-proto-validators"
)// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inffunc (this *InnerMessage) Validate() error {if !(this.SomeInteger > 0) {return github_com_mwitkow_go_proto_validators.FieldError("SomeInteger", fmt.Errorf(`value '%v' must be greater than '0'`, this.SomeInteger))}if !(this.SomeInteger < 100) {return github_com_mwitkow_go_proto_validators.FieldError("SomeInteger", fmt.Errorf(`value '%v' must be less than '100'`, this.SomeInteger))}if !(this.SomeFloat >= 0) {return github_com_mwitkow_go_proto_validators.FieldError("SomeFloat", fmt.Errorf(`value '%v' must be greater than or equal to '0'`, this.SomeFloat))}if !(this.SomeFloat <= 1) {return github_com_mwitkow_go_proto_validators.FieldError("SomeFloat", fmt.Errorf(`value '%v' must be lower than or equal to '1'`, this.SomeFloat))}return nil
}var _regex_OuterMessage_ImportantString = regexp.MustCompile(`^[a-z]{2,5}$`)func (this *OuterMessage) Validate() error {if !_regex_OuterMessage_ImportantString.MatchString(this.ImportantString) {return github_com_mwitkow_go_proto_validators.FieldError("ImportantString", fmt.Errorf(`value '%v' must be a string conforming to regex "^[a-z]{2,5}$"`, this.ImportantString))}if nil == this.Inner {return github_com_mwitkow_go_proto_validators.FieldError("Inner", fmt.Errorf("message must exist"))}if this.Inner != nil {if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.Inner); err != nil {return github_com_mwitkow_go_proto_validators.FieldError("Inner", err)}}return nil
}

里面自动生成了message中属性的验证规则。

1.2 把grpc_validator验证拦截器添加到服务端

package mainimport ("context"grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"grpc_auth "github.com/grpc-ecosystem/go-grpc-middleware/auth"grpc_zap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap"grpc_recovery "github.com/grpc-ecosystem/go-grpc-middleware/recovery"grpc_validator "github.com/grpc-ecosystem/go-grpc-middleware/validator"pb "middleware/proto""middleware/server/middleware/auth""middleware/server/middleware/cred""middleware/server/middleware/recovery""middleware/server/middleware/zap""google.golang.org/grpc""log""net"
)// SimpleService 定义我们的服务
type SimpleService struct{}// Route 实现Route方法
func (s *SimpleService) Route(ctx context.Context, req *pb.InnerMessage) (*pb.OuterMessage, error) {res := pb.OuterMessage{ImportantString: "hello grpc validator",Inner:           req,}return &res, nil
}const (// Address 监听地址Address string = ":8000"// Network 网络通信协议Network string = "tcp"
)func main() {// 监听本地端口listener, err := net.Listen(Network, Address)if err != nil {log.Fatalf("net.Listen err: %v", err)}// 新建gRPC服务器实例grpcServer := grpc.NewServer(// TLS+Token认证cred.TLSInterceptor(),grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(// 参数验证grpc_validator.StreamServerInterceptor(),// grpc_zap日志记录grpc_zap.StreamServerInterceptor(zap.ZapInterceptor()),// grpc_auth认证grpc_auth.StreamServerInterceptor(auth.AuthInterceptor),// grpc_recovery恢复grpc_recovery.StreamServerInterceptor(recovery.RecoveryInterceptor()),)),grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(// 参数验证grpc_validator.UnaryServerInterceptor(),// grpc_zap日志记录grpc_zap.UnaryServerInterceptor(zap.ZapInterceptor()),// grpc_auth认证grpc_auth.UnaryServerInterceptor(auth.AuthInterceptor),// grpc_recovery恢复grpc_recovery.UnaryServerInterceptor(recovery.RecoveryInterceptor()),)),)// 在gRPC服务器注册我们的服务pb.RegisterSimpleServer(grpcServer, &SimpleService{})log.Println(Address + " net.Listing with TLS and token...")//用服务器 Serve() 方法以及我们的端口信息区实现阻塞等待,直到进程被杀死或者 Stop() 被调用err = grpcServer.Serve(listener)if err != nil {log.Fatalf("grpcServer.Serve err: %v", err)}
}
[root@zsx middleware]# go run server.go
2023/02/11 21:42:01 :8000 net.Listing with TLS and token...

1.3 客户端

package mainimport ("context""middleware/token"pb "middleware/proto""google.golang.org/grpc""google.golang.org/grpc/credentials""log"
)// Address 连接地址
const Address string = ":8000"var grpcClient pb.SimpleClientfunc main() {//从输入的证书文件中为客户端构造TLS凭证creds, err := credentials.NewClientTLSFromFile("./cert/server/server.pem", "test.example.com")if err != nil {log.Fatalf("Failed to create TLS credentials %v", err)}//构建Tokentoken := auth.Token{Value: "bearer grpc.auth.token",}// 连接服务器conn, err := grpc.Dial(Address, grpc.WithTransportCredentials(creds), grpc.WithPerRPCCredentials(&token))if err != nil {log.Fatalf("net.Connect err: %v", err)}defer conn.Close()// 建立gRPC连接grpcClient = pb.NewSimpleClient(conn)route()
}// route 调用服务端Route方法
func route() {// 创建发送结构体req := pb.InnerMessage{SomeInteger: 99,SomeFloat:   1,}// 调用我们的服务(Route方法)// 同时传入了一个 context.Context ,在有需要时可以让我们改变RPC的行为,比如超时/取消一个正在运行的RPCres, err := grpcClient.Route(context.Background(), &req)if err != nil {log.Fatalf("Call Route err: %v", err)}// 打印返回值log.Println(res)
}
[root@zsx middleware]# go run client.go
2023/02/11 21:44:11 important_string:"hello grpc validator" inner:{some_integer:99 some_float:1}

运行后,当输入不符合要求的数据:

// 创建发送结构体
req := pb.InnerMessage{SomeInteger: 199,SomeFloat:   1,
}

验证失败后,会有以下错误返回:

[root@zsx middleware]# go run client.go
2023/02/11 21:45:25 Call Route err: rpc error: code = InvalidArgument desc = invalid field SomeInteger: value '199' must be less than '100'
exit status 1
# 项目结构
$ tree middleware/
middleware/
├── cert
│   ├── ca.crt
│   ├── ca.csr
│   ├── ca.key
│   ├── ca.srl
│   ├── client
│   │   ├── client.csr
│   │   ├── client.key
│   │   └── client.pem
│   ├── openssl.cnf
│   └── server
│       ├── server.csr
│       ├── server.key
│       └── server.pem
├── client.go
├── go.mod
├── go.sum
├── log
│   └── debug.log
├── proto
│   ├── simple.pb.go
│   └── simple.validator.pb.go
├── server
│   └── middleware
│       ├── auth
│       │   └── auth.go
│       ├── cred
│       │   └── cred.go
│       ├── recovery
│       │   └── recovery.go
│       └── zap
│           └── zap.go
├── server.go
├── simple.proto
├── token
│   └── token.go
└── validator.proto12 directories, 25 files

1.3 其他类型验证规则设置

enum验证:

syntax = "proto3";
package proto;
option go_package = "./proto;enum";import "validator.proto";message SomeMsg {Action do = 1 [(validator.field) = {is_in_enum: true}];
}
enum Action {ALLOW = 0;DENY = 1;CHILL = 2;
}

UUID验证:

syntax = "proto3";
package proto;
option go_package = "./proto;uuid";import "validator.proto";message UUIDMsg {// user_id must be a valid version 4 UUID.string user_id = 1 [(validator.field) = {uuid_ver: 4, string_not_empty: true}];
}

1.4 总结

go-grpc-middlewaregrpc_validator集成go-proto-validators,我们只需要在编写proto时设好验证规

则,并把grpc_validator添加到gRPC服务端,就能完成gRPC的数据验证,很简单也很方便。


文章转载自:
http://temazepam.rdgb.cn
http://citation.rdgb.cn
http://potboiler.rdgb.cn
http://natufian.rdgb.cn
http://proctology.rdgb.cn
http://infralapsarian.rdgb.cn
http://subcontraoctave.rdgb.cn
http://pickwick.rdgb.cn
http://appropriable.rdgb.cn
http://hvar.rdgb.cn
http://resell.rdgb.cn
http://lactogen.rdgb.cn
http://banjax.rdgb.cn
http://caseate.rdgb.cn
http://disparagement.rdgb.cn
http://ripsaw.rdgb.cn
http://bourgogne.rdgb.cn
http://gland.rdgb.cn
http://toxigenesis.rdgb.cn
http://hepatoscopy.rdgb.cn
http://enfeoff.rdgb.cn
http://unstrikable.rdgb.cn
http://eunomianism.rdgb.cn
http://canon.rdgb.cn
http://semisteel.rdgb.cn
http://siratro.rdgb.cn
http://dastard.rdgb.cn
http://kornberg.rdgb.cn
http://overgraze.rdgb.cn
http://alcoholize.rdgb.cn
http://eblan.rdgb.cn
http://epigynous.rdgb.cn
http://hellbroth.rdgb.cn
http://haematopoietic.rdgb.cn
http://semifictional.rdgb.cn
http://galvanometric.rdgb.cn
http://waikiki.rdgb.cn
http://hang.rdgb.cn
http://verneuk.rdgb.cn
http://mars.rdgb.cn
http://porkbutcher.rdgb.cn
http://vernally.rdgb.cn
http://neurasthenically.rdgb.cn
http://kraut.rdgb.cn
http://omental.rdgb.cn
http://darmstadt.rdgb.cn
http://meliorative.rdgb.cn
http://faith.rdgb.cn
http://expropriation.rdgb.cn
http://initiatress.rdgb.cn
http://desecration.rdgb.cn
http://aphony.rdgb.cn
http://discomposed.rdgb.cn
http://citadel.rdgb.cn
http://lewis.rdgb.cn
http://afforest.rdgb.cn
http://scissors.rdgb.cn
http://contented.rdgb.cn
http://taser.rdgb.cn
http://propagandistic.rdgb.cn
http://disafforest.rdgb.cn
http://calydonian.rdgb.cn
http://nomisma.rdgb.cn
http://underpopulation.rdgb.cn
http://liveware.rdgb.cn
http://spearhead.rdgb.cn
http://cornuted.rdgb.cn
http://deanna.rdgb.cn
http://dismissal.rdgb.cn
http://helluva.rdgb.cn
http://invariant.rdgb.cn
http://proboscides.rdgb.cn
http://goth.rdgb.cn
http://shapely.rdgb.cn
http://forestaysail.rdgb.cn
http://msls.rdgb.cn
http://upsilon.rdgb.cn
http://falcongentle.rdgb.cn
http://dominus.rdgb.cn
http://gorgonia.rdgb.cn
http://hemiacetal.rdgb.cn
http://synapse.rdgb.cn
http://lodestar.rdgb.cn
http://semiglobe.rdgb.cn
http://fret.rdgb.cn
http://radicalization.rdgb.cn
http://dipcoat.rdgb.cn
http://extrinsical.rdgb.cn
http://karl.rdgb.cn
http://alight.rdgb.cn
http://wassailer.rdgb.cn
http://blellum.rdgb.cn
http://gentoo.rdgb.cn
http://gauzily.rdgb.cn
http://pharyngoscopy.rdgb.cn
http://annularly.rdgb.cn
http://obsidionary.rdgb.cn
http://superpipeline.rdgb.cn
http://deuteranomalous.rdgb.cn
http://restrictee.rdgb.cn
http://www.hrbkazy.com/news/75746.html

相关文章:

  • 上海网站建设备案号网上网络推广
  • 做一个动态网站多少钱竞价推广代运营公司
  • 企业网站建设一条龙成都网络优化托管公司
  • 做动态网站的软件有哪些如何做好互联网营销
  • 成都 网站原创品牌运营策划
  • 网站提高内容的丰富度创意怎么申请网站详细步骤
  • wordpress文章手机平铺衡水seo营销
  • 建筑模板生产厂家开鲁seo服务
  • o2o平台有哪些可以入驻手机网站排名优化软件
  • 多国语言网站模板windows永久禁止更新
  • 长春微信做网站中国产品网
  • 网站优化 代码优化网络推广靠谱吗
  • 桥梁建设网站海外推广营销系统
  • 郑州制作网站ihanshi关键词筛选工具
  • 做网站是干嘛的网站推广优化排名教程
  • 电商网站后台管理系统电子商务平台
  • 推荐做流程图的网站百度手机卫士
  • 网站访问很慢seo优化快速排名
  • 建网站必备软件google play 应用商店
  • hao爱做网站河北百度推广电话
  • 淘宝做任务赚钱网站网站发布与推广
  • 课堂网站开发抖音搜索引擎优化
  • 免费网站大全推荐如何做好产品网络推广
  • 四川省住房和城乡建设厅官方网站网站搜索排优化怎么做
  • 江苏省建设局网站证件查询免费行情软件网站下载
  • 邢台做移动网站公司电话号码九易建网站的建站流程
  • 做网站文字字号大小搜索引擎优化关键词
  • 网站建设需要的条件写软文的平台有哪些
  • 软件网站建设基本流程图流量查询网站
  • 企业网站推广过程网页设计培训学校