chore: 初始开源发布
iotlcm-sms:独立短信 HTTP/gRPC 服务,支持阿里云与腾讯云。 - Go module 迁移至 git.5iot.com/iotlcm-public/iotlcm-sms - 补 Apache-2.0 LICENSE,重写 README(特性/配置/接口/部署/目录/测试) - 配置改为 config.example.yaml + SMS_* 环境变量注入,仓库不含真实凭证 - 清理内部标识(私有镜像仓库 / 公司名 / 客户签名 / 真实模板ID / 真实手机号) - 统一 LF 行尾并加 .gitattributes
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/reflection"
|
||||
|
||||
"git.5iot.com/iotlcm-public/iotlcm-sms/api/pb"
|
||||
"git.5iot.com/iotlcm-public/iotlcm-sms/internal/grpcapi"
|
||||
"git.5iot.com/iotlcm-public/iotlcm-sms/internal/httpapi"
|
||||
"git.5iot.com/iotlcm-public/iotlcm-sms/internal/sms"
|
||||
"git.5iot.com/iotlcm-public/iotlcm-sms/internal/sms/aliyun"
|
||||
"git.5iot.com/iotlcm-public/iotlcm-sms/internal/sms/tencent"
|
||||
)
|
||||
|
||||
// 构建时通过 -ldflags 注入。
|
||||
var (
|
||||
BuildVersion = "0.0"
|
||||
BuildTime = ""
|
||||
CommitID = ""
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
||||
defer stop()
|
||||
|
||||
log.Printf("iotlcm-sms starting, version=%s buildTime=%s commit=%s", BuildVersion, BuildTime, CommitID)
|
||||
|
||||
// 默认全局配置:config.yaml 提供默认值,SMS_* 环境变量可覆盖。
|
||||
defaultConfig, source, err := sms.LoadDefaultConfig()
|
||||
if err != nil {
|
||||
log.Fatalf("load sms default config: %v", err)
|
||||
}
|
||||
log.Printf("sms default config loaded: %s", source.Describe())
|
||||
providers := sms.NewRegistryWithDefault(defaultConfig)
|
||||
providers.Register(sms.ServiceAliyun, aliyun.New())
|
||||
providers.Register(sms.ServiceTencent, tencent.New())
|
||||
|
||||
httpAddr := envOrDefault("HTTP_ADDR", ":8080")
|
||||
httpServer := &http.Server{
|
||||
Addr: httpAddr,
|
||||
Handler: httpapi.NewHandler(providers),
|
||||
ReadHeaderTimeout: 5 * time.Second,
|
||||
ReadTimeout: 10 * time.Second,
|
||||
WriteTimeout: 30 * time.Second,
|
||||
IdleTimeout: 60 * time.Second,
|
||||
}
|
||||
|
||||
grpcAddr := envOrDefault("GRPC_ADDR", ":11200")
|
||||
grpcListener, err := net.Listen("tcp", grpcAddr)
|
||||
if err != nil {
|
||||
log.Fatalf("listen on gRPC address %s: %v", grpcAddr, err)
|
||||
}
|
||||
grpcServer := grpc.NewServer()
|
||||
pb.RegisterNoticeServer(grpcServer, grpcapi.NewServer(providers))
|
||||
reflection.Register(grpcServer)
|
||||
|
||||
errCh := make(chan error, 2)
|
||||
go func() {
|
||||
log.Printf("sms http server listening on %s", httpAddr)
|
||||
if err := httpServer.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
||||
errCh <- err
|
||||
}
|
||||
}()
|
||||
go func() {
|
||||
log.Printf("sms gRPC server listening on %s", grpcAddr)
|
||||
if err := grpcServer.Serve(grpcListener); err != nil {
|
||||
errCh <- err
|
||||
}
|
||||
}()
|
||||
|
||||
select {
|
||||
case err := <-errCh:
|
||||
log.Printf("server stopped unexpectedly: %v", err)
|
||||
stop()
|
||||
case <-ctx.Done():
|
||||
}
|
||||
|
||||
shutdownCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
if err := httpServer.Shutdown(shutdownCtx); err != nil {
|
||||
log.Printf("shutdown HTTP server: %v", err)
|
||||
}
|
||||
grpcServer.GracefulStop()
|
||||
}
|
||||
|
||||
func envOrDefault(name, fallback string) string {
|
||||
if value := os.Getenv(name); value != "" {
|
||||
return value
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
Reference in New Issue
Block a user