package main import ( "github.com/nats-io/nats.go" "github.com/redis/go-redis/v9" clientv3 "go.etcd.io/etcd/client/v3" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/resolver" "sonet/internal/gateway_ws/server" "sonet/internal/postal/logic" "sonet/pkg/config" "sonet/pkg/grpc/client" "sonet/pkg/grpc/discovery" "sonet/pkg/grpc/generic" "sonet/pkg/plugins/cache" "sonet/pkg/plugins/mq" "sonet/pkg/utils/conver" "sonet/pkg/utils/shutdown" "sync" ) type GatewayWsConfig struct { HttpPort int EndpointAddress string SubjectCacheTopic string SubjectLrcExpiration string SubjectLrcCleanupInterval string } // websocket server with postalService func main() { appConf := &GatewayWsConfig{} conf := config.LoadConfig(appConf, "cmd/gateway_ws") // registry and run etcdClient, err := clientv3.New(conf.Etcd) if err != nil { panic(err) } sessionStore := &sync.Map{} subjectStore, err := getSubjectMultiCache(appConf, conf.Redis, conf.Nats) if err != nil { panic(err) } clientFactory := client.NewGrpcDirectClientFactory(grpc.WithTransportCredentials(insecure.NewCredentials())) etcdResolver := discovery.NewResolver(etcdClient) resolver.Register(etcdResolver) grpcFactory := generic.NewGpcGenericClientFactory(etcdResolver, grpc.WithTransportCredentials(insecure.NewCredentials())) grpcFactory.Init() postalAddr := discovery.MustRegisterAddress(conf.Grpc.Address) connHandler := server.NewConnHandler(postalAddr, grpcFactory, sessionStore, subjectStore) httpServer := server.NewHttpServer(connHandler) go func() { err = httpServer.Run(appConf.HttpPort) if err != nil { panic(err) } }() // run postal server registry := discovery.NewRegister(etcdClient) shutdown.AddShutdownHook(registry.Stop) postalServer := logic.NewPostalServer(appConf.EndpointAddress, sessionStore, subjectStore, clientFactory) go func() { err = postalServer.Run(conf.Grpc, registry) if err != nil { panic(err) } }() // run postal cluster server postalClusterServer := logic.NewPostalClusterServer(postalServer) go func() { err := postalClusterServer.Run(conf.Grpc.Address, config.GetGrpcOptions(conf.Grpc)...) if err != nil { panic(err) } }() shutdown.Await() } func getSubjectMultiCache(appConf *GatewayWsConfig, redisOptions redis.Options, natsOptions nats.Options) (*cache.LocalRemoteCache, error) { // initial cache... rdb := redis.NewClient(&redisOptions) subjectRedisCache := cache.NewRedisCache(appConf.SubjectCacheTopic, rdb) shutdown.AddShutdownHook(func() { _ = rdb.Close() }) // nats mq producer, err := mq.NewNatsProducer(natsOptions) if err != nil { return nil, err } shutdown.AddShutdownHook(func() { producer.Stop() }) consumer, err := mq.NewNatsConsumer(natsOptions) if err != nil { return nil, err } shutdown.AddShutdownHook(func() { consumer.Stop() }) // 多级缓存 subjectLrcOpts := cache.LocalRemoteCacheOptions{ Topic: appConf.SubjectCacheTopic, LocalExpiration: conver.MustParseDuration(appConf.SubjectLrcExpiration), CleanupInterval: conver.MustParseDuration(appConf.SubjectLrcCleanupInterval), Remote: subjectRedisCache, Producer: producer, Consumer: consumer, } subjectLrc, err := cache.NewLocalRemoteCache(subjectLrcOpts) return subjectLrc, err }