🐡

gRPCを使ったwebチャットをenvoy無しで作る

2021/02/14に公開

今回も次のqiita記事のWebチャットを触ってみます。
https://qiita.com/okmttdhr/items/a37563047904ac98f3ed
コードはここに公開されていています。

前回は、redisでpubsubをmysqlでデータ永続化をさせてみました。今回は、grpcwebを使って、envoyを除きます。
https://zenn.dev/nnabeyang/articles/bad34e6fec718d419220

今回は変更がmainに集中しているので、diffのみ示します。

grpc-web-react-hooks/server/main.go
@@ -3,7 +3,7 @@ package main
 import (
        "context"
        "log"
-       "net"
+       "net/http"
        "time"
 
        "github.com/golang/protobuf/ptypes/empty"
@@ -12,8 +12,8 @@ import (
        "encoding/json"
 
        "github.com/go-redis/redis/v7"
+       "github.com/improbable-eng/grpc-web/go/grpcweb"
        "google.golang.org/grpc"
-       "google.golang.org/grpc/reflection"
 )
 
 const (
@@ -92,14 +92,16 @@ func main() {
                log.Fatalf("failed to listen: %v", err)
        }
        defer dbClose()
-       lis, err := net.Listen("tcp", port)
-       if err != nil {
-               log.Fatalf("failed to listen: %v", err)
-       }
        s := grpc.NewServer()
        pb.RegisterMessengerServer(s, &server{})
-       reflection.Register(s)
-       if err := s.Serve(lis); err != nil {
-               log.Fatalf("failed to serve: %v", err)
+       mux := http.NewServeMux()
+       ws := grpcweb.WrapServer(s,
+               grpcweb.WithOriginFunc(func(origin string) bool { return true }))
+       mux.Handle("/", http.HandlerFunc(ws.ServeHTTP))
+
+       hs := &http.Server{
+               Addr:    port,
+               Handler: mux,
        }
+       hs.ListenAndServe()
 }

grpcweb.WithOriginFunc(func(origin string) bool { return true })はCORSサポートを有効にするために追加しています。あとはenvoyは9090ポートと8080ポートを繋いでいますが、それがなくなるのでそこを修正します。

grpc-web-react-hooks/client/src/gRPCClients.ts
 
 export const gRPCClients = {
-  messengerClient: new MessengerClient(`http://localhost:8080`)
+  messengerClient: new MessengerClient(`http://localhost:9090`)
};

最後は使用しなくなったenvoyをdocker-compose.ymlを削除します。

docker-compose.yml
@@ -23,14 +23,6 @@ services:
     depends_on:
       - proto
       - redis
-  envoy:
-    build:
-      context: .
-      dockerfile: DockerfileEnvoy
-    ports:
-      - "8080:8080"
-    links:
-      - server
   client:
     command: ./scripts/client.sh
     build:

まとめ

本格的なサービスとして提供する場合はenvoynginxを使うことになると思いますが、簡単な実験やローカルネットワーク内でgRPC-Webを使ったアプリを提供するときなどはgrpcwebも選択肢に入るかもしれません。

Discussion