Skip to content

Latest commit

 

History

History
176 lines (133 loc) · 4.44 KB

golang.md

File metadata and controls

176 lines (133 loc) · 4.44 KB

GRPC - Golang Services

You can combine the PHP and Golang GRPC services within one application.

Make sure to read how to build application server.

To demonstrate the ability to register Golang GRPC service define the proto file with needed agreements:

syntax = "proto3";

package multiplier;

message Mult {
    int32 a = 1;
    int32 b = 2;
}

message MultResult {
    int32 result = 1;
}

service Multiplier {
    rpc Mult (multiplier.Mult) returns (multiplier.MultResult) {
    }
}

Generate the server code in multiplier folder:

$ mkdir multiplier
$ protoc -I proto/ proto/multiplier.proto --go_out=plugins=grpc:multiplier

Make sure to install protoc-gen-go. Read about installation here.

Create Service

Create RoadRunner compatible service in the multiplier directory. Register GRPC service using the *grpc.Service->AddService:

package multiplier

import (
	"context"
	grpc "github.com/spiral/php-grpc"
	grpc2 "google.golang.org/grpc"
)

const ID = "multiplier"

type Service struct {
}

func (s *Service) Init(g *grpc.Service) (bool, error) {
	return true, g.AddService(func(server *grpc2.Server) {
		RegisterMultiplierServer(server, s)
	})
}

func (s *Service) Mult(ctx context.Context, in *Mult) (*MultResult, error) {
	return &MultResult{Result: in.A * in.B}, nil
}

To activate the service, make sure to create and build a custom application server:

$ go mod init demo
$ go get google.golang.org/grpc

Make sure to request proper dependencies in go.mod:

module demo

require (
	github.com/golang/protobuf v1.3.2
	github.com/spiral/broadcast v0.0.0-20191206140608-766959683e74
	github.com/spiral/broadcast-ws v1.1.0
	github.com/spiral/jobs v2.1.3
	github.com/spiral/php-grpc v1.2.0
	github.com/spiral/roadrunner v1.6.2
	google.golang.org/genproto v0.0.0-20181016170114-94acd270e44e
	google.golang.org/grpc v1.21.0
)

Modify the main.go to activate the service:

package main

import (
	"demo/multiplier"

	rr "github.com/spiral/roadrunner/cmd/rr/cmd"

	// services (plugins)
	"github.com/spiral/broadcast"
	"github.com/spiral/broadcast-ws"
	"github.com/spiral/jobs/v2"
	"github.com/spiral/php-grpc"
	"github.com/spiral/roadrunner/service/env"
	"github.com/spiral/roadrunner/service/headers"
	"github.com/spiral/roadrunner/service/health"
	"github.com/spiral/roadrunner/service/http"
	"github.com/spiral/roadrunner/service/limit"
	"github.com/spiral/roadrunner/service/metrics"
	"github.com/spiral/roadrunner/service/reload"
	"github.com/spiral/roadrunner/service/rpc"
	"github.com/spiral/roadrunner/service/static"

	// queue brokers
	"github.com/spiral/jobs/v2/broker/amqp"
	"github.com/spiral/jobs/v2/broker/beanstalk"
	"github.com/spiral/jobs/v2/broker/ephemeral"
	"github.com/spiral/jobs/v2/broker/sqs"

	// additional commands and debug handlers
	_ "github.com/spiral/broadcast-ws/cmd/rr-ws/ws"
	_ "github.com/spiral/jobs/v2/cmd/rr-jobs/jobs"
	_ "github.com/spiral/php-grpc/cmd/rr-grpc/grpc"
	_ "github.com/spiral/roadrunner/cmd/rr/http"
	_ "github.com/spiral/roadrunner/cmd/rr/limit"
)

func main() {
	rr.Container.Register(env.ID, &env.Service{})
	rr.Container.Register(rpc.ID, &rpc.Service{})

	// http
	rr.Container.Register(http.ID, &http.Service{})
	rr.Container.Register(headers.ID, &headers.Service{})
	rr.Container.Register(static.ID, &static.Service{})

	rr.Container.Register(grpc.ID, &grpc.Service{})

	rr.Container.Register(jobs.ID, &jobs.Service{
		Brokers: map[string]jobs.Broker{
			"amqp":      &amqp.Broker{},
			"ephemeral": &ephemeral.Broker{},
			"beanstalk": &beanstalk.Broker{},
			"sqs":       &sqs.Broker{},
		},
	})

	// pub-sub
	rr.Container.Register(broadcast.ID, &broadcast.Service{})
	rr.Container.Register(ws.ID, &ws.Service{})

	// supervisor and metrics
	rr.Container.Register(limit.ID, &limit.Service{})
	rr.Container.Register(metrics.ID, &metrics.Service{})
	rr.Container.Register(health.ID, &health.Service{})

	// auto reloading
	rr.Container.Register(reload.ID, &reload.Service{})

	rr.Container.Register(multiplier.ID, &multiplier.Service{})

	// you can register additional commands using cmd.CLI
	rr.Execute()
}

Read more how to define services here and here.

You can run the server now:

$ go run main.go serve -v -d

Read here how to implement streaming and batch processing using a hybrid PHP/Go approach.