grpc之发布订阅
- 获取docker的pubsub包
go get github.com/moby/pubsub
- 基于之前的golang版基础上实现
- 添加proto pubsub.proto
syntax = "proto3";
//option java_package = "com.colobu.rpctest";
package pubsubService;
option go_package = "/";
// The greeting service definition.
service PubSubService {
// Sends a greeting
rpc Publish (Info) returns (Info) {}
rpc Subscribe(Info) returns(stream Info){}
}
message Info {
string Content = 1;
}
生成文件
protoc --go_out=. --go-grpc_out=. pubsub.proto
- 在server文件夹下新建pubsubSeervice.go
package server
import (
"context"
"github.com/moby/pubsub"
psb "grpc-golang/proto/pubsubS"
"strings"
)
type PubSubService struct {
pub *pubsub.Publisher
psb.UnimplementedPubSubServiceServer
}
func (p *PubSubService) Publish(ctx context.Context, in *psb.Info) (*psb.Info, error) {
p.pub.Publish(in.Content)
return in, nil
}
func (p *PubSubService) Subscribe(in *psb.Info, stream psb.PubSubService_SubscribeServer) error {
ch := p.pub.SubscribeTopic(func(v interface{}) bool {
if key, ok := v.(string); ok {
if strings.HasPrefix(key, in.Content) {
return true
}
}
return false
})
for v := range ch {
if err := stream.Send(&psb.Info{Content: v.(string)}); err != nil {
return err
}
}
return nil
}
- register文件添加服务注册
ps := &PubSubService{pub: pubsub.NewPublisher(100*time.Millisecond, 10)}
pubsubS.RegisterPubSubServiceServer(s, ps)
- 添加发布和订阅客户端 pubClient.go
package main
import (
"context"
"flag"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
rpsb "grpc-golang/proto/pubsubS"
"log"
)
type PAuth struct {
}
func (c PAuth) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {
//TODO implement me
return map[string]string{
"accessToken": "65794a3163325679546d46745a534936496e647463794973496e426863334e5862334a6b496a6f694d54497a4e445532496e303d",
}, nil
}
func (c PAuth) RequireTransportSecurity() bool {
return false
}
func main() {
var addr = flag.String("addr", "192.168.2.127:50051", "the address to connect to")
flag.Parse()
var opts []grpc.DialOption
opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials()))
opts = append(opts, grpc.WithPerRPCCredentials(new(PAuth)))
conn, err := grpc.Dial(*addr, opts...)
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
client := rpsb.NewPubSubServiceClient(conn)
_, err = client.Publish(
context.Background(), &rpsb.Info{Content: "test"},
)
if err != nil {
log.Fatal(err)
}
_, err = client.Publish(
context.Background(), &rpsb.Info{Content: "2342343242"},
)
if err != nil {
log.Fatal(err)
}
}
subClient.go
package main
import (
"context"
"flag"
"fmt"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
rpsb "grpc-golang/proto/pubsubS"
"io"
"log"
)
type SAuth struct {
}
func (c SAuth) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {
//TODO implement me
return map[string]string{
"accessToken": "65794a3163325679546d46745a534936496e647463794973496e426863334e5862334a6b496a6f694d54497a4e445532496e303d",
}, nil
}
func (c SAuth) RequireTransportSecurity() bool {
return false
}
func main() {
var addr = flag.String("addr", "192.168.2.127:50051", "the address to connect to")
flag.Parse()
var opts []grpc.DialOption
opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials()))
opts = append(opts, grpc.WithPerRPCCredentials(new(SAuth)))
conn, err := grpc.Dial(*addr, opts...)
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
client := rpsb.NewPubSubServiceClient(conn)
stream, err := client.Subscribe(
context.Background(), &rpsb.Info{Content: ""},
)
if err != nil {
log.Fatal(err)
}
for {
reply, err := stream.Recv()
if err != nil {
if err == io.EOF {
break
}
log.Fatal(err)
}
fmt.Println(reply.GetContent())
}
}
- 启动测试
go run server.go
go client/subClient.go
go client/pubClient.go
8. postman测试