Slide 1

Slide 1 text

Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench / muench.dev 1 1

Slide 2

Slide 2 text

Protocol Buffer syntax = "proto3"; service Stock { rpc Update(StockUpdateRequest) returns (StockUpdateResponse) {} } message StockUpdateRequest { string source_code = 1; string sku = 2; float qty = 3; } message StockUpdateResponse { bool ack = 1; } 2 2 Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench / muench.dev

Slide 3

Slide 3 text

Language specific settings used for client generation package stock; option go_package="git.muench.dev/grpc-demo/protos"; option php_namespace="MuenchDev\\GrpcDemo"; 3 3 Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench / muench.dev

Slide 4

Slide 4 text

Library Code Generator get github.com/golang/protobuf/protoc-gen-go 4 4 Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench / muench.dev

Slide 5

Slide 5 text

Go Code protoc \ --go_out=. \ --go_opt=paths=source_relative \ --go-grpc_out=. \ --go-grpc_opt=paths=source_relative \ protos/stock.proto 5 5 Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench / muench.dev

Slide 6

Slide 6 text

type StockClient interface { Update(ctx context.Context, in *StockUpdateRequest, opts ...grpc.CallOption) (*StockUpdateResp } type stockClient struct { cc grpc.ClientConnInterface } func NewStockClient(cc grpc.ClientConnInterface) StockClient { return &stockClient{cc} } func (c *stockClient) Update(ctx context.Context, in *StockUpdateRequest, opts ...grpc.CallOption) (*StockUpdateResponse, error) { out := new(StockUpdateResponse) err := c.cc.Invoke(ctx, "/stock.Stock/Update", in, out, opts...) if err != nil { return nil, err } return out, nil } 6 6

Slide 7

Slide 7 text

Reflection import ( "google.golang.org/grpc/reflection" // ... ) func main() { // ... s := grpc.NewServer() pb.RegisterStockServer(s, &server{}) reflection.Register(s) // ... } 7 7

Slide 8

Slide 8 text

8 8

Slide 9

Slide 9 text

grpcurl # Mac users brew install grpcurl # GO devs do this ... go get github.com/fullstorydev/grpcurl/... go install github.com/fullstorydev/grpcurl/cmd/grpcurl 9 9 Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench / muench.dev

Slide 10

Slide 10 text

With reflection $> grpcurl -plaintext localhost:9000 list grpc.reflection.v1alpha.ServerReflection stock.Stock 10 10 Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench / muench.dev

Slide 11

Slide 11 text

Without reflection $> grpcurl -plaintext \ -import-path=protos -proto=stock.proto \ localhost:9000 list stock.Stock 11 11 Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench / muench.dev

Slide 12

Slide 12 text

Describe service $> grpcurl -plaintext localhost:9000 describe stock.Stock stock.Stock is a service: service Stock { rpc Update ( .stock.StockUpdateRequest ) returns ( .stock.StockUpdateResponse ); } 12 12 Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench / muench.dev

Slide 13

Slide 13 text

Describe message grpcurl -plaintext localhost:9000 describe stock.StockUpdateRequest stock.StockUpdateRequest is a message: message StockUpdateRequest { string source_code = 1; string sku = 2; float qty = 3; } 13 13 Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench / muench.dev

Slide 14

Slide 14 text

Message Templates grpcurl -plaintext -msg-template localhost:9000 describe stock.StockUpdateRequest stock.StockUpdateRequest is a message: message StockUpdateRequest { string source_code = 1; string sku = 2; float qty = 3; } Message template: { "sourceCode": "", "sku": "", "qty": 0 } 14 14

Slide 15

Slide 15 text

CURL like post ... $> grpcurl -plaintext -d '{ "sourceCode": "default", "sku": "24-MB01", "qty": 1000.0 } ' localhost:9000 stock.Stock.Update { "ack": true } 15 15 Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench / muench.dev

Slide 16

Slide 16 text

gRPC Web UI https://github.com/fullstorydev/grpcui 16 16 Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench / muench.dev

Slide 17

Slide 17 text

17 17

Slide 18

Slide 18 text

Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench / muench.dev 18 18

Slide 19

Slide 19 text

PHP Code protoc --php_out=. \ --grpc_out=source_relative \ --plugin=protoc-gen-grpc=bins/opt/grpc_php_plugin \ protos/stock.proto 19 19 Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench / muench.dev

Slide 20

Slide 20 text

git clone -b v1.32.0 https://github.com/grpc/grpc cd grpc && git submodule update --init && make grpc_php_plugin 20 20 Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench / muench.dev

Slide 21

Slide 21 text

Generated files . ├── GPBMetadata │ └── Protos │ └── Stock.php └── Stock ├── StockClient.php ├── StockUpdateRequest.php └── StockUpdateResponse.php 21 21 Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench / muench.dev

Slide 22

Slide 22 text

_simpleRequest('/stock.Stock/Update', $argument, ['\Stock\StockUpdateResponse', 'decode'], $metadata, $options); } } 22 22 Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench / muench.dev

Slide 23

Slide 23 text

Grpc\ChannelCredentials::createInsecure()], ); $unaryCall = $client->Update( (new \MuenchDev\GrpcDemo\StockUpdateRequest\StockUpdateRequest()) ->setQty((float) mt_rand(0, 1000)) ->setSku('24-MB01') ->setSourceCode('default') ); echo $unaryCall->getPeer(); $response = $unaryCall->wait(); echo sprintf("ACK: %b\n", $response[0]->getAck()); 23 23

Slide 24

Slide 24 text

PHP Setup 24 24 Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench / muench.dev

Slide 25

Slide 25 text

ddev Setup ARG BASE_IMAGE FROM $BASE_IMAGE ENV PHP_VERSION=7.4 RUN \ apt-get update && apt-get install -y libz-dev php-dev php-pear && \ pecl install grpc && \ pecl install protobuf && \ echo "extension=grpc.so" > /etc/php/7.4/cli/conf.d/grpc.ini && \ echo "extension=protobuf.so" > /etc/php/7.4/cli/conf.d/protobuf.ini echo "extension=grpc.so" > /etc/php/7.4/fpm/conf.d/grpc.ini && \ echo "extension=protobuf.so" > /etc/php/7.4/fpm/conf.d/protobuf.ini 25 25 Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench / muench.dev

Slide 26

Slide 26 text

https://github.com/spiral/php-grpc https://roadrunner.dev 26 26 Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench / muench.dev

Slide 27

Slide 27 text

.rr.yaml config: grpc: listen: "tcp://:9001" proto: "service.proto" tls: key: "server.key" cert: "server.crt" workers: command: "php worker.php" pool: numWorkers: 4 run $ rr-grpc serve -v -d 27 27

Slide 28

Slide 28 text

Sample GRPC PHP server. registerService( \Service\EchoInterface::class, new EchoService() ); $w = new RoadRunner\Worker(new Goridge\StreamRelay(STDIN, STDOUT)); $server->serve($w); 28 28

Slide 29

Slide 29 text

Links https://grpc.io https://github.com/fullstorydev/grpcurl https://github.com/fullstorydev/grpcui https://www.yonego.com/nl/why-milliseconds-matter/ https://github.com/spiral/php-grpc 29 29 Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench / muench.dev