package main import ( "context" "encoding/json" "log" "time" "go.uber.org/zap" "google.golang.org/grpc" "github.com/garyburd/redigo/redis" "github.com/valyala/fasthttp" "git.loafle.net/commons_go/config" "git.loafle.net/commons_go/logging" backGRpc "git.loafle.net/overflow/overflow_api_server/golang" "git.loafle.net/overflow/overflow_gateway_web/handler/file" "git.loafle.net/overflow/overflow_gateway_web/handler/web" gws "git.loafle.net/overflow/overflow_gateway_websocket" grpcPool "git.loafle.net/overflow/overflow_grpc_pool" subscriberRedis "git.loafle.net/overflow/overflow_subscriber/redis" ) var logger *zap.Logger func main() { config.SetConfigName("config") config.AddConfigPath(".") err := config.ReadInConfig() if nil != err { log.Fatalf("config error: %v", err) } ctx, cancel := NewContext() defer cancel() logger = logging.WithContext(ctx) defer logger.Sync() o := &gws.ServerOptions{ OnConnection: onConnection, OnDisconnected: onDisconnected, OnCheckOrigin: onCheckOrigin, HandshakeTimeout: time.Duration(config.GetInt("websocket.HandshakeTimeout")) * time.Second, ReadBufferSize: config.GetInt("websocket.ReadBufferSize"), WriteBufferSize: config.GetInt("websocket.WriteBufferSize"), EnableCompression: config.GetBool("websocket.EnableCompression"), } s := gws.NewServer(ctx, o) rPool := &redis.Pool{ MaxIdle: config.GetInt("redis.pool.MaxIdle"), IdleTimeout: time.Duration(config.GetInt("redis.pool.IdleTimeout")) * time.Second, Dial: func() (redis.Conn, error) { return redis.Dial(config.GetString("redis.network"), config.GetString("redis.addr")) }, } defer func() { rPool.Close() }() noti := subscriberRedis.New(ctx, rPool.Get()) noti.Subscribe("web", func(channel string, payload string) { logger.Info("Subscribe", zap.String("channel", channel), zap.String("payload", payload), ) }) bo := &grpcPool.Options{ MaxIdle: config.GetInt("grpc.pool.MaxIdle"), MaxCapacity: config.GetInt("grpc.pool.MaxCapacity"), Creators: func() (*grpc.ClientConn, interface{}, error) { var err error conn, err := grpc.Dial(config.GetString("grpc.addr"), grpc.WithInsecure()) if nil != err { return nil, nil, err } c := backGRpc.NewOverflowApiServerClient(conn) return conn, c, nil }, } bPool, err := grpcPool.New(ctx, bo) if nil != err { logger.Panic("Cannot create Pool of GRPC") } wh := web.New(ctx, bPool) fh := file.New(ctx) s.HandleSocket(config.GetString("handlers.web.entry"), wh.GetSocketOption()) s.HandleSocket(config.GetString("handlers.file.entry"), fh.GetSocketOption()) s.ListenAndServe(config.GetString("server.addr")) } func NewContext() (context.Context, context.CancelFunc) { var err error ctx := context.Background() logConfig := config.Sub("logging") buf, err := logConfig.Marshal("json") if err != nil { panic(err) } var cfg zap.Config if err = json.Unmarshal(buf, &cfg); err != nil { panic(err) } logger, err := cfg.Build() if err != nil { panic(err) } ctx = logging.NewContext(ctx, logger) ctx, cancel := context.WithCancel(ctx) return ctx, cancel } func onCheckOrigin(ctx *fasthttp.RequestCtx) bool { if origin := string(ctx.Request.Header.Peek("Origin")); origin != "" { ctx.Response.Header.Set("Access-Control-Allow-Origin", origin) if string(ctx.Method()) == "OPTIONS" && string(ctx.Request.Header.Peek("Access-Control-Request-Method")) != "" { ctx.Response.Header.Set("Access-Control-Allow-Headers", "Content-Type, Accept") ctx.Response.Header.Set("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, DELETE") } } return true } func onConnection(soc gws.Socket) { logger.Info("connect", zap.String("path", soc.Path()), zap.String("id", soc.ID()), ) } func onDisconnected(soc gws.Socket) { logger.Info("disconnect", zap.String("path", soc.Path()), zap.String("id", soc.ID()), ) }