diff --git a/README.md b/README.md index 144c687..fa0ee4b 100644 --- a/README.md +++ b/README.md @@ -30,30 +30,3 @@ NexFrame是一款基于 Go 语言免费开源的,快速、简单的企业级 在发布本资料时,请严格遵守开放出版许可协议 1.0 或其后续版本的规定。未经版权所有者的明确书面授权,不得擅自发布本文档的修改版本。此外,除非事先获得版权所有者的特别许可,否则禁止将此作品或其衍生作品以标准纸质书籍的形式进行发行。 若您有意再发行或再版本手册的全部或部分内容,无论是否经过修改,或有任何相关疑问,请及时与版权所有者联系,邮箱地址为:nexframe@sagoo.cn。我们期待与您共同维护和尊重知识产权,确保作品的合法合规传播。 - -## web服务 - -```go -package main - -import ( - "fmt" - "github.com/sagoo-cloud/nexframe" - "net/http" -) - -func main() { - server := nexframe.Server() - // 注册控制器 - err := server.BindHandlerFunc("/", func(w http.ResponseWriter, r *http.Request) { - fmt.Println(w, "Hello, world!") - }) - if err != nil { - return - } - server.SetPort(":8080") - server.Run() -} - -``` - diff --git a/SUMMARY.md b/SUMMARY.md index 460711c..530b65c 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -3,11 +3,30 @@ * [介绍](README.md) -* [数据结构](/dataStructure/README.md) - - * [二叉树](/dataStructure/binaryTree.md) -* [Maven](/maven/README.md) - * [搭建maven仓库](/maven/nexus.md) +* [准备工作](install.md) +* [快速开始](start.md) +* [服务组件](servers.md) + * [消息队列服务](/queue.md) + * [定时器服务](/timers.md) + * [mqtt订阅服务](/mqttc.md) + * [websocket服务](/websockets.md) + +* [数据处理](/database.md) + * [数据库组件](/gorm.md) + * [redisdb组件](/redisdb.md) + * [数据聚合器组件](/aggregator.md) +* [实用工具](/tools.md) + * [数据校验](/valid.md) + * [http客户端](/httputil.md) + * [随机数](/rand.md) + * [速率限制](/retelimit.md) +* [配置管理](/config.md) +* [日志管理](/zlog.md) +* [i18n国际化](/i18n.md) +* [协程池管理](/gpool.md) +* [文件管理](/file.md) + * [文件上传/水印](/file.md) + * [文件操作工具](/fileop.md) --- * [关于作者](personalIntroduction.md) diff --git a/aggregator.md b/aggregator.md new file mode 100644 index 0000000..ee01e9a --- /dev/null +++ b/aggregator.md @@ -0,0 +1,159 @@ +# Aggregator数据聚合器 + +## 1. 概述 + +Aggregator模块是一个用于批量处理数据的高性能并发组件。它能够将输入的数据项聚合成批次,然后异步处理这些批次,同时提供了灵活的配置选项和错误处理机制。 + +## 2. 主要结构 + +### 2.1 Aggregator + +`Aggregator` 是这个模块的核心结构,它包含以下主要字段: + +- `option`: 聚合器配置选项 +- `eventQueue`: 事件队列,用于存储待处理的数据项 +- `batchProcessor`: 批处理函数 +- `pool`: 对象池,用于复用批次切片 +- `lingerTimer`: 延迟处理计时器 +- `lastProcessTime`: 上次处理时间 + +### 2.2 AggregatorOption + +`AggregatorOption` 结构体用于配置Aggregator,包括以下字段: + +- `BatchSize`: 批处理大小 +- `Workers`: 工作协程数量 +- `ChannelBufferSize`: 通道缓冲区大小 +- `LingerTime`: 延迟处理时间 +- `ErrorHandler`: 错误处理函数 +- `Logger`: 日志记录器 + +## 3. 初始化和配置 + +### 3.1 创建新的Aggregator实例 + +使用 `NewAggregator` 函数创建新的Aggregator实例: + +```go +aggregator, err := database.NewAggregator(batchProcessFunc, optionFuncs...) +``` + +### 3.2 配置选项 + +使用以下函数来设置Aggregator的配置选项: + +- `WithBatchSize(size int)`: 设置批处理大小 +- `WithWorkers(workers int)`: 设置工作协程数量 +- `WithChannelBufferSize(size int)`: 设置通道缓冲区大小 +- `WithLingerTime(duration time.Duration)`: 设置延迟处理时间 +- `WithLogger(logger *log.Logger)`: 设置日志记录器 +- `WithErrorHandler(handler ErrorHandlerFunc)`: 设置错误处理函数 + +示例: + +```go +aggregator, err := database.NewAggregator( + batchProcessFunc, + database.WithBatchSize(10), + database.WithWorkers(4), + database.WithLingerTime(time.Second * 30), +) +``` + +## 4. 主要功能 + +### 4.1 数据入队 + +#### 4.1.1 非阻塞入队 + +```go +success := aggregator.TryEnqueue(item) +``` + +#### 4.1.2 阻塞入队 + +```go +err := aggregator.Enqueue(item) +``` + +#### 4.1.3 带重试的入队 + +```go +success := aggregator.EnqueueWithRetry(item, maxRetries, backoff) +``` + +### 4.2 启动和停止 + +#### 4.2.1 启动Aggregator + +```go +aggregator.Start() +``` + +#### 4.2.2 停止Aggregator + +```go +aggregator.Stop() +``` + +#### 4.2.3 安全停止Aggregator + +```go +aggregator.SafeStop() +``` + +## 5. 批处理函数 + +批处理函数是Aggregator的核心,它定义了如何处理一批数据项: + +```go +type BatchProcessFunc func([]interface{}) error +``` + +示例: + +```go +func batchProcessFunc(items []interface{}) error { + // 处理一批数据项 + for _, item := range items { + // 处理单个数据项 + } + return nil +} +``` + +## 6. 错误处理 + +错误处理函数允许自定义如何处理批处理过程中的错误: + +```go +type ErrorHandlerFunc func(err error, items []interface{}, batchProcessFunc BatchProcessFunc, aggregator *Aggregator) +``` + +示例: + +```go +func errorHandler(err error, items []interface{}, batchProcessFunc BatchProcessFunc, aggregator *Aggregator) { + log.Printf("处理错误: %v", err) + // 可以选择重试、跳过或其他处理方式 +} +``` + +## 7. 最佳实践 + +1. 根据实际需求调整批处理大小和工作协程数量,以平衡吞吐量和资源使用。 +2. 使用 `SafeStop()` 来确保所有数据都被处理后再停止Aggregator。 +3. 实现适当的错误处理函数,以便在批处理失败时采取合适的措施。 +4. 使用日志记录器来监控Aggregator的运行状况。 +5. 在高并发场景下,考虑使用 `TryEnqueue()` 或 `EnqueueWithRetry()` 来避免阻塞。 + +## 8. 注意事项 + +1. Aggregator 不保证严格的顺序处理,如果需要保持顺序,需要在批处理函数中额外实现。 +2. 在使用 `Stop()` 或 `SafeStop()` 后,不应再尝试向Aggregator中添加新的数据项。 +3. 批处理函数应该是幂等的,因为在某些错误情况下可能会重试处理同一批数据。 +4. 注意设置合适的 `LingerTime`,以平衡实时性和批处理效率。 + +## 9. 结论 + +Aggregator模块提供了一个高效的方式来批量处理数据,特别适用于需要高吞吐量的场景。通过合理配置和使用,可以显著提高数据处理的效率和可靠性。在使用过程中,需要根据具体的应用场景和需求来调整各项参数,以达到最佳的性能和资源利用。 \ No newline at end of file diff --git a/config.md b/config.md new file mode 100644 index 0000000..c549c9c --- /dev/null +++ b/config.md @@ -0,0 +1,2 @@ +# 配置管理 + diff --git a/database.md b/database.md new file mode 100644 index 0000000..28b2ec2 --- /dev/null +++ b/database.md @@ -0,0 +1,3 @@ +# 数据组件 + + diff --git a/gorm.md b/gorm.md new file mode 100644 index 0000000..3f6fc6b --- /dev/null +++ b/gorm.md @@ -0,0 +1,8 @@ +# 数据库操作 + +nexframe中集成的是GORM,GORM是一个流行的Go语言ORM库,它提供了丰富的数据库操作功能,包括CRUD、关联查询、事务处理等。 + +在本架构中可以直接使用。 + +通过全局方法,直接获取到数据库实例。`g.DB`。 + diff --git a/i18n.md b/i18n.md new file mode 100644 index 0000000..b772fae --- /dev/null +++ b/i18n.md @@ -0,0 +1,141 @@ +# 国际化(i18n) + +## 1. 概述 + +这个国际化(i18n)支持库提供了一个简单而强大的方式来为Go应用程序添加多语言支持。它支持动态加载翻译、切换语言、添加新的翻译,以及格式化带参数的翻译。 + +## 2. 主要特性 + +- 支持多种语言的翻译 +- 动态加载和切换语言 +- 线程安全的操作 +- 支持从文件或字节数组加载翻译 +- 支持添加和更新翻译 +- 支持带参数的翻译格式化 + +## 3. 初始化 + +### 3.1 初始化全局i18n实例 + +使用 `InitGlobal` 函数初始化全局i18n实例: + +```go +err := i18n.InitGlobal("en", "path/to/translations") +if err != nil { + log.Fatalf("初始化i18n失败: %v", err) +} +``` + +参数: +- 第一个参数是初始语言代码 +- 第二个参数(可选)是翻译文件的自定义目录路径 + +## 4. 基本用法 + +### 4.1 翻译文本 + +使用 `T` 函数翻译文本: + +```go +translatedText := i18n.T("hello_world") +``` + +### 4.2 格式化翻译 + +使用 `FormatTranslation` 函数格式化带参数的翻译: + +```go +formattedText := i18n.FormatTranslation("welcome_message", "Alice") +``` + +### 4.3 切换语言 + +使用 `SetLang` 函数切换当前语言: + +```go +err := i18n.SetLang("fr") +if err != nil { + log.Printf("切换语言失败: %v", err) +} +``` + +### 4.4 获取当前语言 + +使用 `GetCurrentLang` 函数获取当前语言: + +```go +currentLang := i18n.GetCurrentLang() +``` + +## 5. 高级用法 + +### 5.1 添加新的翻译 + +使用 `AddTranslation` 函数为当前语言添加或更新翻译: + +```go +err := i18n.AddTranslation("new_key", "New translation") +if err != nil { + log.Printf("添加翻译失败: %v", err) +} +``` + +### 5.2 从字节数组加载翻译 + +使用 `LoadTranslationsFromBytes` 函数从字节数组加载翻译: + +```go +data := []byte(`{"hello": "Bonjour"}`) +err := i18n.LoadTranslationsFromBytes("fr", data) +if err != nil { + log.Printf("从字节数组加载翻译失败: %v", err) +} +``` + +## 6. 文件结构 + +翻译文件应该是JSON格式,每种语言一个文件,文件名应为语言代码加`.json`后缀。例如: + +- `en.json` +- `fr.json` +- `zh.json` + +文件内容示例(en.json): + +```json +{ + "hello_world": "Hello, World!", + "welcome_message": "Welcome, %s!" +} +``` + +## 7. 线程安全 + +这个库的所有操作都是线程安全的,可以在并发环境中安全使用。 + +## 8. 错误处理 + +所有可能失败的操作都返回一个 `error`。建议在生产环境中妥善处理这些错误。 + +## 9. 最佳实践 + +1. 在应用启动时调用 `InitGlobal` 初始化i18n库。 +2. 使用有意义的键来组织你的翻译,例如 `user.greeting` 而不是简单的 `greeting`。 +3. 对于包含变量的翻译,使用 `FormatTranslation` 函数。 +4. 定期备份你的翻译文件,特别是在使用 `AddTranslation` 函数时。 +5. 在开发过程中,可以使用 `AddTranslation` 函数快速添加新的翻译,但在生产环境中,最好通过更新翻译文件来管理翻译。 + +## 10. 性能考虑 + +- 翻译会被缓存在内存中,所以重复的翻译查询非常快。 +- 切换语言会触发新的语言文件加载,可能会有轻微的性能影响。 +- 添加新的翻译会触发文件写入操作,在高并发场景下要谨慎使用。 + +## 11. 局限性 + +- 目前不支持复数形式的处理。 +- 不支持基于地区的变体(例如 en-US 和 en-GB 的区别)。 + +## 12. 结论 + +这个i18n支持库提供了一个简单而有效的方式来为Go应用程序添加国际化支持。通过合理使用这个库,可以轻松地创建多语言应用,提高应用的国际化水平。在使用过程中,如果遇到任何问题或有改进建议,请及时反馈给开发团队。 \ No newline at end of file diff --git a/install.md b/install.md new file mode 100644 index 0000000..ffc53de --- /dev/null +++ b/install.md @@ -0,0 +1,4 @@ +# 准备工作 + +nexframe 本程序是基于golang语言编写,推荐使用golang版本高于1.23.0,golang相关信息具体可以访问其官网查询。 + diff --git a/mqtts.md b/mqtts.md new file mode 100644 index 0000000..f789751 --- /dev/null +++ b/mqtts.md @@ -0,0 +1,139 @@ +# MQTT订阅服务 + +## 1. 概述 + +这个MQTT订阅服务的MQTT客户端库是基于 `github.com/eclipse/paho.mqtt.golang` 包构建的,提供了一个简单的接口来实现MQTT的连接、发布和订阅功能。该库主要包含三个主要组件: + +1. MQTT客户端实例管理(ins.go) +2. 消息发布功能(publish.go) +3. 消息订阅服务器(subscribe_server.go) + +## 2. MQTT客户端实例管理 (ins.go) + +### 2.1 功能描述 + +`ins.go` 文件负责管理MQTT客户端实例。它使用单例模式确保整个应用程序中只有一个MQTT客户端实例。 + +### 2.2 主要函数 + +- `GetIns()`: 获取MQTT客户端实例 +- `init_mc()`: 初始化MQTT客户端 + +### 2.3 使用示例 + +```go +import "github.com/sagoo-cloud/nexframe/servers/mqtts" + +// 获取MQTT客户端实例 +client := mqtts.GetIns() + +// 使用客户端进行操作 +if client != nil { + // 执行MQTT操作 +} else { + // 处理连接失败的情况 +} +``` + +## 3. 消息发布功能 (publish.go) + +### 3.1 功能描述 + +`publish.go` 文件提供了一个简单的接口来发布MQTT消息。 + +### 3.2 主要函数 + +- `Publish(topic string, payload interface{}) error`: 发布消息到指定的主题 + +### 3.3 使用示例 + +```go +import "github.com/sagoo-cloud/nexframe/servers/mqtts" + +// 定义要发布的数据 +data := map[string]string{ + "message": "Hello, MQTT!", +} + +// 发布消息 +err := mqtts.Publish("your/topic", data) +if err != nil { + // 处理发布错误 + log.Printf("发布失败: %v", err) +} else { + log.Println("消息发布成功") +} +``` + +## 4. 消息订阅服务器 (subscribe_server.go) + +### 4.1 功能描述 + +`subscribe_server.go` 文件实现了一个MQTT订阅服务器,可以处理多个主题的订阅。 + +### 4.2 主要结构和函数 + +- `Server` 结构体:订阅服务器的主要结构 +- `NewServer()`: 创建新的订阅服务器 +- `Register(name string, handler *commons.CommHandler)`: 注册主题和对应的处理器 +- `Serve()`: 启动订阅服务 +- `Close()`: 关闭订阅服务 + +### 4.3 使用示例 + +```go +import ( + "github.com/sagoo-cloud/nexframe/servers/mqtts/mqtts" + "github.com/sagoo-cloud/nexframe/servers/commons" + "context" +) + +// 创建消息处理器 +handler := &commons.CommHandler{ + Handle: func(ctx context.Context, message []byte) ([]byte, error) { + // 处理接收到的消息 + log.Printf("收到消息: %s", string(message)) + return []byte("处理完成"), nil + }, +} + +// 创建订阅服务器 +server := mqtts.NewServer() + +// 注册主题和处理器 +server.Register("your/topic", handler) + +// 启动服务 +go func() { + if err := server.Serve(); err != nil { + log.Printf("服务器错误: %v", err) + } +}() + +// ... 主程序逻辑 ... + +// 在程序结束时关闭服务 +defer server.Close() +``` + +## 5. 配置 + +这个库使用 `configs.LoadMqttConfig()` 来加载MQTT配置。确保在你的配置文件中包含以下MQTT相关的设置: + +- Host: MQTT broker的地址 +- UserName: MQTT认证用户名 +- PassWord: MQTT认证密码 +- ClientID: 客户端ID +- PublishQos: 发布消息的QoS级别 +- SubscribeQos: 订阅消息的QoS级别 +- Parallel: 是否并行处理订阅消息 + +## 6. 注意事项 + +1. 确保在使用任何功能之前,MQTT客户端已成功连接。 +2. 处理所有可能的错误,特别是在发布消息和启动订阅服务时。 +3. 在应用程序退出时,记得调用 `Close()` 函数来清理订阅和断开连接。 +4. 根据你的需求调整 QoS 级别和并行处理选项。 + + +这个MQTT客户端库提供了一个简洁的接口来处理MQTT通信。通过合理使用这些功能,你可以轻松地在你的应用程序中集成MQTT消息传递功能。如果遇到任何问题或需要进一步的帮助,请查阅源代码或联系库的维护者。 \ No newline at end of file diff --git a/queue.md b/queue.md index 239667f..b748af7 100644 --- a/queue.md +++ b/queue.md @@ -1,4 +1,4 @@ -# 消息队列使用手册 +# 消息队列服务 ## 1. 简介 diff --git a/rand.md b/rand.md index 3ceebe9..482dda6 100644 --- a/rand.md +++ b/rand.md @@ -1,4 +1,4 @@ -# Go 随机工具包使用手册 +# 随机数 ## 1. 简介 diff --git a/ratelimit.md b/ratelimit.md index 9352aeb..5680c35 100644 --- a/ratelimit.md +++ b/ratelimit.md @@ -1,4 +1,4 @@ -# 速率限制包使用手册 +# 速率限制 ## 1. 简介 diff --git a/redisdb.md b/redisdb.md new file mode 100644 index 0000000..78f9971 --- /dev/null +++ b/redisdb.md @@ -0,0 +1,129 @@ +# 基于Redis的数据处理组件 + +基于Redis实现的基础数据库,方便将redis数据库当成普通数据库使用。它提供了一个灵活的接口来处理Redis操作,支持单机、集群和哨兵模式,并实现了数据插入、查询和监听等功能。 + +## 2. 主要结构 + +### 2.1 RedisManager + +`RedisManager` 是这个模块的核心结构,它包含以下主要字段: + +- `client`: Redis客户端 +- `recordDuration`: 记录保持时间 +- `recordLimit`: 记录限制数量 +- `pipelineBufferSize`: 管道缓冲大小 +- `pipelineCounter`: 管道计数器 +- `dbname`: 数据库名称 + +## 3. 初始化和配置 + +### 3.1 获取RedisManager实例 + +使用 `DB()` 函数获取 `RedisManager` 的单例实例: + +```go +redisManager := redisdb.DB() +``` + +### 3.2 配置选项 + +Redis配置通过 `redisOptions` 结构体进行设置,主要包括: + +- `Mode`: Redis模式(single/cluster/sentinel) +- `SentinelMasterName`: Sentinel模式下的主节点名称 +- `Addr`: Redis服务器地址 +- `DB`: Redis数据库编号 +- `UserName`: Redis用户名 +- `Password`: Redis密码 +- `PoolSize`: 连接池大小 +- `RecordDuration`: 记录的有效时间 +- `RecordLimit`: 记录的条数限制 +- `PipelineBufferSize`: 管道缓冲大小 + +## 4. 主要功能 + +### 4.1 插入数据 + +#### 4.1.1 插入单条数据 + +```go +err := redisManager.InsertData(ctx, key, data, buffer) +``` + +- `ctx`: 上下文 +- `key`: 数据的键 +- `data`: 要插入的数据 +- `buffer`: 是否使用缓冲处理 + +#### 4.1.2 批量插入数据 + +```go +err := redisManager.InsertBatchData(ctx, key, data) +``` + +- `data`: 要批量插入的数据切片 + +### 4.2 查询数据 + +#### 4.2.1 获取最新的数据 + +```go +data, err := redisManager.GetData(ctx, key) +``` + +#### 4.2.2 获取最新的一条数据 + +```go +data, err := redisManager.GetDataByLatest(ctx, key) +``` + +#### 4.2.3 分页获取数据 + +```go +data, total, currentPage, err := redisManager.GetDataByPage(ctx, deviceKey, pageNum, pageSize, types, dateRange) +``` + +- `deviceKey`: 设备键 +- `pageNum`: 页码 +- `pageSize`: 每页大小 +- `types`: 类型过滤 +- `dateRange`: 日期范围过滤 + +### 4.3 监听新数据 + +```go +redisManager.ListenForNewData(ctx, key, processor, interval) +``` + +- `processor`: 处理新数据的函数 +- `interval`: 轮询间隔 + +## 5. 错误处理 + +所有的方法都返回错误,开发者应该妥善处理这些错误。例如: + +```go +if err := redisManager.InsertData(ctx, key, data, false); err != nil { + log.Printf("Failed to insert data: %v", err) + // 处理错误... +} +``` + +## 6. 最佳实践 + +1. 使用单例模式获取 `RedisManager` 实例,避免多次创建连接池。 +2. 合理设置 `RecordDuration` 和 `RecordLimit`,避免存储过多无用数据。 +3. 在高并发场景下,考虑使用 `InsertBatchData` 和缓冲处理来提高性能。 +4. 使用 `ListenForNewData` 进行实时数据处理时,选择合适的轮询间隔。 +5. 在应用退出时,确保正确关闭Redis连接。 + +## 7. 注意事项 + +1. 这个模块使用了前缀 `deviceCacheData:` 来标识设备数据缓存,使用时需要注意避免键名冲突。 +2. 在集群模式下,需要确保所有相关的Redis操作都在同一个槽(slot)中执行。 +3. 使用 Sentinel 模式时,需要正确配置主节点名称和哨兵地址。 +4. 数据插入使用了 Redis 的列表结构,查询时需要注意数据的顺序。 + +## 8. 结论 + +这个Redis数据库管理模块提供了一个强大而灵活的接口来处理设备数据的存储和检索。通过合理使用这些功能,开发人员可以轻松地在应用中集成Redis数据库操作,实现高效的数据管理和实时处理。 \ No newline at end of file diff --git a/servers.md b/servers.md new file mode 100644 index 0000000..23792aa --- /dev/null +++ b/servers.md @@ -0,0 +1,3 @@ +# 服务组件 + +在nexframe中,服务组件是基础服务组件,对于常用的服务进行封装,方便开发者使用。 \ No newline at end of file diff --git a/start.md b/start.md new file mode 100644 index 0000000..a38727c --- /dev/null +++ b/start.md @@ -0,0 +1,60 @@ +# 快速开始 + +本章内容将通过一个示例项目的创建,来引导怎么创建与使用nexframe的项目。 + +## 创建项目 + +创建一个文件夹作为项目目录,采用开发工具打开这个目录,如使用Goland 。 + +在这个项目目录下,采用命令行初始化项目 + +```azure +go mod init github.com/yourname/yourproject + +``` + +## 添加依赖 + +在项目目录下,使用命令行添加依赖 + +```azure + +go get github.com/nexframe/nexframe + +``` +## 编写代码 +在项目目录下,创建一个main.go文件,并编写如下代码 + +```go +package main + +import ( + "fmt" + "github.com/sagoo-cloud/nexframe" + "net/http" +) + +func main() { + server := nexframe.Server() + // 注册控制器 + err := server.BindHandlerFunc("/", func(w http.ResponseWriter, r *http.Request) { + fmt.Println(w, "Hello, world!") + }) + if err != nil { + return + } + server.SetPort(":8080") + server.Run() +} + +``` + +## 运行项目 +在项目目录下,使用命令行运行项目 +```azure +go run main.go + +``` +## 访问项目 +在浏览器中访问http://localhost:8080/,即可看到nexframe的欢迎页面。 + diff --git a/timers.md b/timers.md index afbd3cc..38f808a 100644 --- a/timers.md +++ b/timers.md @@ -1,4 +1,4 @@ -# 定时器服务器包使用手册 +# 定时器服务 ## 1. 概述 diff --git a/tools.md b/tools.md new file mode 100644 index 0000000..d506b6e --- /dev/null +++ b/tools.md @@ -0,0 +1 @@ +# 实用工具 \ No newline at end of file diff --git a/websockets.md b/websockets.md new file mode 100644 index 0000000..9b5f92b --- /dev/null +++ b/websockets.md @@ -0,0 +1,153 @@ +# WebSocket服务 + +## 1. 概述 + +这个WebSocket服务器程序是基于Go语言的`gorilla/websocket`包构建的,提供了一个灵活的WebSocket服务器实现。该程序主要包含以下功能: + +1. WebSocket连接管理 +2. 消息路由和处理 +3. 服务器配置选项 +4. 并发控制 + +## 2. 主要结构 + +### 2.1 Server 结构体 + +`Server`结构体是这个WebSocket服务器的核心,它包含了以下主要字段: + +- `handlers`: 存储消息处理器的映射 +- `upgrader`: WebSocket连接升级器 +- `maxConns`: 最大连接数 +- `activeConns`: 当前活跃连接数 +- `ctx`: 服务器上下文 +- `logger`: 日志记录器 + +## 3. 服务器初始化 + +### 3.1 创建新服务器 + +使用`NewServer`函数创建一个新的WebSocket服务器实例: + +```go +server := websockets.NewServer() +``` + +### 3.2 服务器配置选项 + +你可以使用以下选项来配置服务器: + +- `WithMaxConnections(n int)`: 设置最大连接数 +- `WithLogger(logger *slog.Logger)`: 设置自定义日志记录器 + +示例: + +```go +logger := slog.New(slog.NewJSONHandler(os.Stdout, nil)) +server := websockets.NewServer( + websockets.WithMaxConnections(2000), + websockets.WithLogger(logger), +) +``` + +## 4. 注册消息处理器 + +使用`Register`方法注册消息处理器: + +```go +handler := &commons.CommHandler{ + Handle: func(ctx context.Context, message []byte) ([]byte, error) { + // 处理消息逻辑 + return []byte("Response"), nil + }, +} +server.Register("route_name", handler) +``` + +## 5. 启动服务器 + +使用`Serve`方法启动WebSocket服务器: + +```go +err := server.Serve(":8080") +if err != nil { + log.Fatal("服务器启动失败:", err) +} +``` + +## 6. 消息处理 + +### 6.1 消息格式 + +客户端发送的消息应该是JSON格式,包含以下字段: + +- `Route`: 字符串,指定要使用的处理器 +- `Params`: 任意JSON对象,作为消息参数 + +示例: + +```json +{ + "Route": "echo", + "Params": { + "message": "Hello, WebSocket!" + } +} +``` + +### 6.2 响应格式 + +服务器的响应也是JSON格式,结构取决于处理器的实现。 + +## 7. 错误处理 + +服务器会自动处理以下错误情况: + +- JSON解析错误 +- 未找到指定的消息处理器 +- 处理器执行错误 + +错误响应的格式: + +```json +{ + "code": 1, + "msg": "错误描述", + "data": null +} +``` + +## 8. 并发控制 + +服务器实现了基本的并发控制: + +- 限制最大连接数 +- 使用互斥锁保护共享资源 + +## 9. 关闭服务器 + +使用`Close`方法优雅地关闭服务器: + +```go +err := server.Close() +if err != nil { + log.Println("服务器关闭错误:", err) +} +``` + +## 10. 最佳实践 + +1. 始终处理`Serve`方法返回的错误。 +2. 实现适当的`CheckOrigin`函数来增强安全性。 +3. 根据需求调整最大连接数和超时设置。 +4. 使用自定义logger进行更好的日志管理。 +5. 在生产环境中实现更复杂的错误处理和恢复机制。 + +## 11. 注意事项 + +1. 这个实现使用了简单的JSON消息格式。根据需求,你可能需要实现更复杂的协议。 +2. 当前实现允许所有源的WebSocket连接。在生产环境中,你应该实现更严格的源检查。 +3. 错误处理和日志记录可能需要根据具体应用进行调整。 +4. 这个实现没有包含身份验证机制,如果需要,你应该添加相应的功能。 + + +这个WebSocket服务器程序提供了一个灵活、可扩展的框架来处理WebSocket连接和消息。通过合理使用这些功能,你可以轻松地在你的应用程序中集成WebSocket通信功能。如果遇到任何问题或需要进一步的帮助,请查阅源代码或联系维护者。 \ No newline at end of file