kefu/cmd/server.go

186 lines
4.8 KiB
Go
Raw Normal View History

2024-12-10 02:50:12 +00:00
package cmd
import (
"context"
"fmt"
"github.com/gin-contrib/pprof"
"github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/cookie"
"github.com/gin-gonic/gin"
"github.com/robfig/cron/v3"
"github.com/spf13/cobra"
"github.com/zh-five/xdaemon"
"html/template"
"io/ioutil"
"kefu/common"
"kefu/controller"
"kefu/middleware"
"kefu/models"
"kefu/router"
"kefu/service"
"kefu/static"
"kefu/tools"
"kefu/ws"
"log"
"net/http"
"os"
"time"
)
var (
port string
daemon bool
rootPath string
)
var serverCmd = &cobra.Command{
Use: "server",
Short: "启动客服http服务",
Example: "kefu server",
Run: run,
}
func init() {
serverCmd.PersistentFlags().StringVarP(&rootPath, "rootPath", "r", "", "程序根目录")
serverCmd.PersistentFlags().StringVarP(&port, "port", "p", "8081", "监听端口号")
serverCmd.PersistentFlags().BoolVarP(&daemon, "daemon", "d", false, "是否为守护进程模式")
}
func run(cmd *cobra.Command, args []string) {
//初始化目录
initDir()
//初始化守护进程
initDaemon()
baseServer := "0.0.0.0:" + port
//if common.RpcStatus {
// go frpc.NewRpcServer(common.RpcServer)
// log.Println("start rpc server...\r\ngotcp://" + common.RpcServer)
//}
engine := gin.Default()
//模板函数
engine.SetFuncMap(template.FuncMap{
"DateFormat": tools.DateFormat, //格式化日期
})
//是否编译模板
if common.IsCompireTemplate {
templ := template.Must(template.New("").ParseFS(static.TemplatesEmbed, "templates/**/*.html"))
engine.SetHTMLTemplate(templ)
} else {
engine.LoadHTMLGlob(common.StaticDirPath + "templates/**/*")
}
engine.Static("/static", common.StaticDirPath)
engine.Static("/h5", common.RootPath+"/h5")
store := cookie.NewStore([]byte("secret"))
sessionNames := []string{"go-session", "go-session-a", "go-session-b"}
engine.Use(sessions.SessionsMany(sessionNames, store))
//engine.Use(tools.Session("kefu"))
engine.Use(middleware.CrossSite)
router.InitViewRouter(engine)
router.InitApiRouter(engine)
//限流类
tools.NewLimitQueue()
//清理
//ws.CleanVisitorExpire()
//后端websocket
//go ws.WsServerBackend()
//初始化数据
//logger := lib.NewLogger()
err := models.NewConnect(common.ConfigDirPath + "/mysql.json")
if err != nil {
common.MySQLConnectFaild = true
}
//后端定时客服
//go ws.UpdateVisitorStatusCron()
//初始化定时任务
// 创建定时任务调度器
cr := cron.New()
// 添加定时任务,每分钟执行一次
cr.AddFunc("*/1 * * * *", func() {
log.Println("定时任务执行:", time.Now().Format("2006-01-02 15:04:05"), "给客服websocket链接发送ping")
// 这里可以添加你的定时任务逻辑
ws.SendPingToKefuClient()
})
// 添加定时任务,每小时执行一次,更新抖音
douyinClientKey := models.FindConfig("DouyinClientKey")
douyinClientSecret := models.FindConfig("DouyinClientSecret")
if douyinClientKey != "" && douyinClientSecret != "" {
cr.AddFunc("0 */1 * * *", func() {
log.Println("定时任务执行:", time.Now().Format("2006-01-02 15:04:05"), "更新抖音access_token,refresh_token")
service.UpdateDouyinAccessToken()
})
}
// 启动定时任务调度器
cr.Start()
defer cr.Stop()
log.Println("服务开始运行:" + baseServer)
//性能监控
pprof.Register(engine)
//engine.Run(baseServer)
srv := &http.Server{
Addr: baseServer,
Handler: engine,
}
go func() {
if err := srv.ListenAndServe(); err != nil {
log.Printf("服务监听: %s\n", err)
}
}()
<-controller.StopSign
log.Println("关闭服务...")
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
log.Fatal("服务关闭失败:", err)
}
log.Println("服务已关闭")
}
// 初始化目录
func initDir() {
if rootPath == "" {
rootPath = tools.GetRootPath()
}
log.Println("服务运行路径:" + rootPath)
common.RootPath = rootPath
common.LogDirPath = rootPath + "/logs/"
common.ConfigDirPath = rootPath + "/config/"
common.StaticDirPath = rootPath + "/static/"
common.UploadDirPath = rootPath + "/static/upload/"
if noExist, _ := tools.IsFileNotExist(common.RootPath + "/install.lock"); noExist {
panic("未检测到" + common.RootPath + "/install.lock,请先安装服务!")
}
if noExist, _ := tools.IsFileNotExist(common.LogDirPath); noExist {
if err := os.MkdirAll(common.LogDirPath, 0777); err != nil {
log.Println(err.Error())
}
}
isMainUploadExist, _ := tools.IsFileExist(common.UploadDirPath)
if !isMainUploadExist {
os.Mkdir(common.UploadDirPath, os.ModePerm)
}
}
// 初始化守护进程
func initDaemon() {
if daemon == true {
d := xdaemon.NewDaemon(common.LogDirPath + "kefu.log")
d.MaxError = 5
d.Run()
}
//记录pid
ioutil.WriteFile(common.RootPath+"/kefu.sock", []byte(fmt.Sprintf("%d %d", os.Getppid(), os.Getpid())), 0666)
}