kefu/cmd/server.go

186 lines
4.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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)
}