当前位置: 首页 > wzjs >正文

变装的他 wordpress股票发行ipo和seo是什么意思

变装的他 wordpress,股票发行ipo和seo是什么意思,东莞网站建设 鞋材厂,自考的真实通过率重构logger 上次写的logger.go过于繁琐,有很多没用到的功能;重构后只提供了简洁的日志接口,支持日志轮转、多级别日志记录等功能,并采用单例模式确保全局只有一个日志实例 全局变量 var (once sync.Once // 用于实现…

重构logger

上次写的logger.go过于繁琐,有很多没用到的功能;重构后只提供了简洁的日志接口,支持日志轮转、多级别日志记录等功能,并采用单例模式确保全局只有一个日志实例

全局变量

var (once    sync.Once        // 用于实现单例模式的同步控制Logger  *zap.Logger      // 全局日志实例String  = zap.String     // 导出常用的 zap.Field 构造方法Any     = zap.AnyErr     = zap.ErrorInt     = zap.IntFloat32 = zap.Float32
)

默认配置常量

const (defaultLogPath    = "./logs"      // 默认日志存储目录defaultLogLevel   = "debug"        // 默认日志级别defaultMaxSize    = 100           // 单个日志文件最大大小(MB)defaultMaxBackups = 30            // 保留的旧日志文件数量defaultMaxAge     = 7             // 日志保留天数defaultCompress   = true          // 是否压缩旧日志
)

初始化日志记录器

// Init 初始化日志记录器(单例模式)
func Init() *zap.Logger {once.Do(func() {// 确保日志目录存在if err := os.MkdirAll(defaultLogPath, 0755); err != nil {panic(err)}// 设置日志级别level := getLogLevel(defaultLogLevel)// 日志文件路径logFile := getDatedLogFilename(defaultLogPath)// 设置日志轮转writer := zapcore.AddSync(&lumberjack.Logger{Filename:   logFile,MaxSize:    defaultMaxSize,    // MBMaxBackups: defaultMaxBackups, // 保留的旧日志文件数量MaxAge:     defaultMaxAge,     // 保留天数Compress:   defaultCompress,   // 是否压缩})// 编码器配置encoderConfig := zap.NewProductionEncoderConfig()encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoderencoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder // 不带颜色// 核心配置core := zapcore.NewCore(// zapcore.NewJSONEncoder(encoderConfig), // json格式zapcore.NewConsoleEncoder(encoderConfig), // 使用 Console 编码器writer,level,)// 创建LoggerLogger = zap.New(core)})return Logger
}

获取日志实例

func GetLogger() *zap.Logger {if Logger == nil {Init() // 自动初始化}return Logger
}

直接可用的日志方法

func Debug(msg string, fields ...zap.Field) {GetLogger().Debug(msg, fields...)
}func Info(msg string, fields ...zap.Field) {GetLogger().Info(msg, fields...)
}func Warn(msg string, fields ...zap.Field) {GetLogger().Warn(msg, fields...)
}func Error(msg string, fields ...zap.Field) {GetLogger().Error(msg, fields...)
}func Fatal(msg string, fields ...zap.Field) {GetLogger().Fatal(msg, fields...)
}func Sync() error {return GetLogger().Sync()
}

代码地址:logger.go

从main函数开始

func main() {defer log.Sync() // 记录日志log.Info("start chat server...")newRouter := router.NewRouter()go chat.MyServer.Start()s := &http.Server{Addr:           ":8080",Handler:        newRouter,ReadTimeout:    10 * time.Second,WriteTimeout:   10 * time.Second,MaxHeaderBytes: 1 << 20,}err := s.ListenAndServe()if err != nil {log.Error("server start error", log.Err(err))}
}
  1. 初始化路由
    • 创建 HTTP 请求路由器。
    • 会在这里定义所有的 API 端点(endpoints)和对应的处理函数。
    • 返回一个实现了 http.Handler 接口的路由器对象。
  2. 启动后台服务
    • 使用 go 关键字启动一个 goroutine,异步运行 chat.MyServer.Start() 方法。
    • 这通常用于启动需要长期运行的 WebSocket 服务。
  3. 配置 HTTP 服务器
  4. 启动 HTTP 服务器:开始监听指定端口(8080)的 HTTP 请求。

自定义Gin路由

NewRouter 函数解析

func NewRouter() *gin.Engine {gin.SetMode(gin.ReleaseMode)server := gin.Default()server.Use(Cors())server.Use(Recovery)socket := RunSocketgroup := server.Group(""){// 用户管理功能group.GET("/user", api.GetUserList)group.GET("/user/:uuid", api.GetUserDetails)group.GET("/user/name", api.GetUserOrGroupByName)group.POST("/user/register", api.Register)group.POST("/user/login", api.Login)group.PUT("/user", api.ModifyUserInfo)group.POST("/friend", api.AddFriend)group.GET("/message", api.GetMessage)group.GET("/file/:fileName", api.GetFile)group.POST("/file", api.SaveFile)group.GET("/group/:uuid", api.GetGroup)group.POST("/group/:uuid", api.SaveGroup)group.POST("/group/join/:userUuid/:groupUuid", api.JoinGroup)group.GET("/group/user/:uuid", api.GetGroupUsers)group.GET("/socket.io", socket)}return server
}
  1. Gin 模式设置gin.SetMode(gin.ReleaseMode) 将 Gin 设置为发布模式,减少调试信息输出。
  2. 中间件使用Cors() 中间件处理跨域请求,Recovery 中间件捕获并处理 panic。
  3. 路由分组:所有路由都定义在根分组 ("") 下,清晰的 RESTful 风格路由设计。
  4. 路由类型:用户管理:GET/POST/PUT 操作;文件管理:文件上传/下载;WebSocket:实时通信端点。

跨域处理中间件 (Cors)

func Cors() gin.HandlerFunc {return func(c *gin.Context) {method := c.Request.Methodorigin := c.Request.Header.Get("Origin")if origin != "" {// 设置跨域响应头c.Header("Access-Control-Allow-Origin", "*")c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE")c.Header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization")c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Cache-Control, Content-Language, Content-Type")c.Header("Access-Control-Allow-Credentials", "true")}// 处理 OPTIONS 预检请求if method == "OPTIONS" {c.JSON(http.StatusOK, "ok!")return}// 异常捕获defer func() {if err := recover(); err != nil {log.Error("HttpError", log.Any("HttpError", err))}}()c.Next() // 处理请求}
}
  1. 跨域头设置
    • 允许所有来源 (*),生产环境应替换为具体域名
    • 允许的 HTTP 方法
    • 允许的请求头
    • 允许客户端访问的响应头
    • 允许携带凭证
  2. OPTIONS 请求处理:直接返回 200 状态码,满足浏览器的预检请求。
  3. 异常捕获:使用 defer+recover 捕获处理过程中的 panic,记录错误日志。

恢复中间件 (Recovery)

func Recovery(c *gin.Context) {defer func() {if r := recover(); r != nil {log.Error("gin catch error", log.Any("error", r))c.JSON(http.StatusOK, response.FailMsg("系统内部错误"))}}()c.Next()
}

panic 恢复:捕获路由处理函数中可能发生的 panic,记录错误日志

WebSocket 实现 (RunSocket)

var upGrader = websocket.Upgrader{CheckOrigin: func(r *http.Request) bool {return true // 允许所有跨域 WebSocket 连接},
}func RunSocket(c *gin.Context) {user := c.Query("user") // 获取用户标识if user == "" {return // 无用户标识则拒绝连接}log.Info("newUser", log.String("newUser", user))// 升级 HTTP 连接为 WebSocket 连接ws, err := upGrader.Upgrade(c.Writer, c.Request, nil)if err != nil {return}// 创建客户端对象client := &server.Client{Name: user,Conn: ws,Send: make(chan []byte),}// 注册客户端到服务器server.MyServer.Register <- client// 启动读写协程go client.Read()go client.Write()
}
  1. WebSocket 升级
    • 使用 gorilla/websocket 包的 Upgrader 将 HTTP 连接升级为 WebSocket 连接
    • CheckOrigin 返回 true 允许所有跨域连接(生产环境应做限制)
  2. 客户端管理
    • 通过 user 查询参数识别用户,创建客户端对象,包含 WebSocket 连接和消息通道
    • 通过注册通道将客户端注册到中央服务器。
  3. 并发处理:为每个客户端启动独立的读 (client.Read()) 和写 (client.Write()) 协程,实现全双工通信。

代码地址:IM-Go

http://www.dtcms.com/wzjs/296154.html

相关文章:

  • 无锡网站建设推广服务东莞营销网站建设直播
  • 减肥药可以做网站吗蚌埠seo外包
  • 阜阳网站建设高州新闻 头条 今天
  • 网站小空间做网站公司哪家比较好
  • 查建设工程规划许可证在哪个网站磁力兔子
  • 安卓做视频网站好杭州seo公司服务
  • 有什么软件做短视频网站百度游戏app下载
  • android 做电子书下载网站关键词搜索名词解释
  • 上海专业做网站公司报价整站优化cms
  • 武汉北京网站建设公司排名第一的手机清理软件
  • 镇江个人网站制作seo软件代理
  • 杭州杭州网站建设免费的seo网站
  • wordpress汇率插件网络seo营销推广
  • 杭州电商网站开发seo外链优化培训
  • 漯河网站建设服务公司google搜索中文入口
  • 永年网站制作网络销售是干嘛的
  • 漯河城乡建设管理局网站百度答主中心入口
  • 公网动态ip如何做网站南京网络营销服务
  • 网站设置ico制作网站要找什么公司
  • wordpress 多媒体图片显示不了seo会被取代吗
  • 合肥制作小程序seo裤子的关键词首页排名有哪些
  • 无锡做公司网站的怎样做一个网页
  • 网站建设如何提高转化率百度手机助手下载安装最新版
  • 服务器配置aso优化违法吗
  • 武汉教育网站重庆seo哪个强
  • 青岛企业网站建设google浏览器下载
  • 济南做网站优化哪家好附近成人电脑培训班
  • 优设网网站太原百度搜索排名优化
  • 网站流量监控怎么做东莞网络优化调查公司
  • 个人网站设计总结网站排名监控工具