Skip to content

Commit 4726c86

Browse files
committed
add stream example
1 parent f0dd2b0 commit 4726c86

24 files changed

Lines changed: 1198 additions & 674 deletions

Makefile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
current_dir = $(shell pwd)
22

3-
PATH := $(PATH):$(PWD)/bin:$(current_dir)/frontend/node_modules/@protobuf-ts/plugin/bin
3+
PATH := $(PATH):$(PWD)/bin:$(current_dir)/frontend/node_modules/@protobuf-ts/plugin/bin
44

55
genproto:
66
rm -rf $(current_dir)/backend/pb/*
@@ -10,10 +10,11 @@ genproto:
1010
--go-grpc_out=:$(current_dir)/backend/pb \
1111
--ts_out $(current_dir)/frontend/src/api/proto \
1212
--ts_opt generate_dependencies \
13-
hello.proto
13+
example.proto
1414
npx prettier --write --log-level=error $(current_dir)/frontend/src/api/proto/*
1515

1616
start:
17+
docker compose build --no-cache
1718
docker compose up -d
1819
open http://localhost:3000
1920

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
This repository contains an example of using grpc-web with a backend written in golang.
44

5+
![Preview](https://github.com/sxwebdev/grpc-web-example/blob/master/preview.png?raw=true)
6+
57
## Tech stack
68

79
- Backend: `Golang`

backend/.air.toml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Working directory
2+
root = "."
3+
tmp_dir = ".tmp"
4+
5+
[build]
6+
# Just plain old shell command. You could use `make` as well.
7+
cmd = "make build"
8+
# Binary file yields from `cmd`.
9+
bin = ".build/app"
10+
# This log file places in your tmp_dir.
11+
log = "air_errors.log"
12+
# Watch these filename extensions.
13+
include_ext = ["go"]
14+
# Ignore these filename extensions or directories.
15+
exclude_dir = [".tmp", "/sql"]
16+
# It's not necessary to trigger build each time file changes if it's too frequent.
17+
delay = 1000 # ms
18+
19+
[log]
20+
# Show log time
21+
time = true
22+
23+
[color]
24+
# Customize each part's color. If no color found, use the raw app log.
25+
main = "magenta"
26+
watcher = "cyan"
27+
build = "yellow"
28+
runner = "green"
29+
30+
[misc]
31+
# Delete tmp directory on exit
32+
clean_on_exit = true

backend/Makefile

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
current_dir = $(shell pwd)
2+
3+
PATH := $(PATH):$(PWD)/bin:$(current_dir)/frontend/node_modules/@protobuf-ts/plugin/bin
4+
5+
start:
6+
go run -v main.go
7+
8+
build:
9+
go build -o ./.build/app -v main.go
10+
11+
watch:
12+
air -c .air.toml
13+

backend/internal/api/grpc-web.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package api
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"grpc-web-example/pb"
7+
"time"
8+
9+
"github.com/tkcrm/mx/logger"
10+
"google.golang.org/grpc"
11+
"google.golang.org/protobuf/types/known/timestamppb"
12+
)
13+
14+
type grpcWebServer struct {
15+
logger logger.Logger
16+
ctx context.Context
17+
18+
pb.UnimplementedServiceServer
19+
}
20+
21+
func NewGrpcWebServer(ctx context.Context, logger logger.Logger) *grpcWebServer {
22+
return &grpcWebServer{
23+
logger: logger,
24+
ctx: ctx,
25+
}
26+
}
27+
28+
func (s *grpcWebServer) Name() string { return "grpc-web-server" }
29+
30+
func (s *grpcWebServer) Register(srv *grpc.Server) {
31+
pb.RegisterServiceServer(srv, s)
32+
}
33+
34+
func (s *grpcWebServer) Rpc(ctx context.Context, req *pb.RpcRequest) (*pb.RpcResponse, error) {
35+
if req.Text == "" {
36+
return nil, fmt.Errorf("empty text")
37+
}
38+
39+
return &pb.RpcResponse{
40+
Response: fmt.Sprintf("You requested: %s", req.Text),
41+
Date: timestamppb.Now(),
42+
}, nil
43+
}
44+
45+
func (s *grpcWebServer) Stream(req *pb.StreamRequest, stream pb.Service_StreamServer) error {
46+
errChan := make(chan error, 1)
47+
go func() {
48+
var lastValue int32 = 0
49+
50+
for {
51+
lastValue++
52+
53+
replyMsg := &pb.StreamResponse{
54+
RandInteger: lastValue,
55+
Date: timestamppb.New(time.Now()),
56+
}
57+
58+
if err := stream.Send(replyMsg); err != nil {
59+
errChan <- err
60+
return
61+
}
62+
63+
time.Sleep(time.Second)
64+
}
65+
}()
66+
67+
select {
68+
case <-s.ctx.Done():
69+
case err := <-errChan:
70+
return err
71+
}
72+
73+
return nil
74+
}

backend/internal/api/hello.go

Lines changed: 0 additions & 39 deletions
This file was deleted.

backend/main.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ func main() {
2121
)
2222

2323
// grpc servers
24-
helloServer := api.NewHelloServer()
24+
grpcWebServer := api.NewGrpcWebServer(ln.Context(), logger)
2525

2626
// grpc instance
2727
grpcServer := grpc_transport.NewServer(
2828
grpc_transport.WithLogger(logger),
29-
grpc_transport.WithServices(helloServer),
29+
grpc_transport.WithServices(grpcWebServer),
3030
)
3131

3232
ln.ServicesRunner().Register(

0 commit comments

Comments
 (0)