重构:main.go 直接 import 各 internal/ 子包,删除全部 bridge
最后一步:把 main.go 里所有指向桥接小写名的引用(store / config / blocking / bot / runtimesettings / mqttforward / web 等)改写成直接调用 internal/* 子包的导出 API,从而拆掉所有 *_bridge.go。 变更点 - main.go 顶部 import 区改为引用 11 个 internal/ 子包:auth、blocking、 bot、config、mqttforward、runtimesettings、store、web 等。 - meshtasticFilterHook 字段类型改为 *storepkg.WriteQueue / *blockingpkg.Cache / *rspkg.Cache / *mqttforwardpkg.Stats;不再依赖 main 包内别名。 - mqttClientInfoFromClient 返回 storepkg.MQTTClientInfo(之前为 main 包别名)。 - run() 里 newSessionManager → auth.NewManager;newRouter → webpkg.NewRouter; serveHTTPUnixSocket → webpkg.ServeUnixSocket;mqttRuntimeStatus → webpkg.MQTTRuntimeStatus;botSendTextRequest → botpkg.SendTextRequest; newBlockingCache / newRuntimeSettingsCache / newMQTTForwardManager 都改为 对应包的 New / NewManager。 - main_test.go 里的 BlockingViolationForRecord 测试改用 testutil.OpenStore + blockingpkg.New,全部通过 store.Store 的公开 API 构造数据,不再需要 根目录 test_helpers_test.go。 删除根目录文件 - config.go、auth.go(已删)、blocking_bridge.go、bot_bridge.go、 help_bridge.go、llmadmin_bridge.go、mapsource_bridge.go、 mqttforward_bridge.go、runtime_settings_bridge.go、sign_bridge.go、 store_bridge.go、web_bridge.go、test_helpers_test.go。 最终结果 - 根目录只剩 main.go (~370 行) 和 main_test.go (~110 行)。 - internal/ 下 13 个独立子包:auth / blocking / bot / config / help / llmadmin / mapsource / mqttforward / runtimesettings / sign / store / store/testutil / web / webutil。 - go build ./... / go test ./... 全部通过;测试数量与重构前一致; go build . 可以产出可执行二进制(约 50 MB)。 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,21 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
// 桥接到 internal/blocking — 让根目录其余文件可以继续使用旧名字
|
|
||||||
// blockingCache / newBlockingCache / registerAdminBlockingRoutes,
|
|
||||||
// 而无须改动 main.go / web.go 等十几处调用点。
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
|
|
||||||
blockingpkg "meshtastic_mqtt_server/internal/blocking"
|
|
||||||
)
|
|
||||||
|
|
||||||
type blockingCache = blockingpkg.Cache
|
|
||||||
|
|
||||||
func newBlockingCache(s *store) (*blockingCache, error) {
|
|
||||||
return blockingpkg.New(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
func registerAdminBlockingRoutes(r gin.IRouter, s *store, b *blockingCache) {
|
|
||||||
blockingpkg.RegisterRoutes(r, s, b)
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
// 桥接到 internal/bot — 让 main.go / web.go 中使用 botService /
|
|
||||||
// botTextSender / newBotService / newPKIKeyResolver / registerAdminBotRoutes
|
|
||||||
// 这些旧名字的代码继续可用。
|
|
||||||
|
|
||||||
import (
|
|
||||||
mqtt "github.com/mochi-mqtt/server/v2"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
|
|
||||||
botpkg "meshtastic_mqtt_server/internal/bot"
|
|
||||||
)
|
|
||||||
|
|
||||||
type (
|
|
||||||
botService = botpkg.Service
|
|
||||||
botTextSender = botpkg.TextSender
|
|
||||||
botSendTextRequest = botpkg.SendTextRequest
|
|
||||||
)
|
|
||||||
|
|
||||||
func newBotService(s *store, server *mqtt.Server, key []byte) *botService {
|
|
||||||
return botpkg.NewService(s, server, key)
|
|
||||||
}
|
|
||||||
|
|
||||||
func newPKIKeyResolver(s *store) func(toNodeNum, fromNodeNum uint32) ([]byte, []byte, bool) {
|
|
||||||
return botpkg.NewPKIKeyResolver(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
func registerAdminBotRoutes(r gin.IRouter, s *store, sender botTextSender) {
|
|
||||||
botpkg.RegisterRoutes(r, s, sender)
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
cryptotls "crypto/tls"
|
|
||||||
|
|
||||||
cfgpkg "meshtastic_mqtt_server/internal/config"
|
|
||||||
)
|
|
||||||
|
|
||||||
// 桥接到 internal/config — 让根目录其余文件无须修改即可继续使用旧的非导出名字。
|
|
||||||
|
|
||||||
const (
|
|
||||||
configFileName = cfgpkg.FileName
|
|
||||||
databaseDriverSQLite = cfgpkg.DriverSQLite
|
|
||||||
databaseDriverMySQL = cfgpkg.DriverMySQL
|
|
||||||
)
|
|
||||||
|
|
||||||
// 旧的小写类型名通过别名继续可用。
|
|
||||||
type (
|
|
||||||
config = cfgpkg.Config
|
|
||||||
mqttConfig = cfgpkg.MQTTConfig
|
|
||||||
tlsConfig = cfgpkg.TLSConfig
|
|
||||||
meshtasticConfig = cfgpkg.MeshtasticConfig
|
|
||||||
databaseConfig = cfgpkg.DatabaseConfig
|
|
||||||
sqliteConfig = cfgpkg.SQLiteConfig
|
|
||||||
mysqlConfig = cfgpkg.MySQLConfig
|
|
||||||
webConfig = cfgpkg.WebConfig
|
|
||||||
webAdminConfig = cfgpkg.WebAdminConfig
|
|
||||||
aiConfig = cfgpkg.AIConfig
|
|
||||||
)
|
|
||||||
|
|
||||||
func defaultConfig() *config { return cfgpkg.Default() }
|
|
||||||
func defaultConfigDir() string { return cfgpkg.DefaultDir() }
|
|
||||||
func defaultConfigPath() string { return cfgpkg.DefaultPath() }
|
|
||||||
func loadConfig(path string) (*config, error) { return cfgpkg.Load(path) }
|
|
||||||
func writeConfig(path string, cfg *config) error { return cfgpkg.Write(path, cfg) }
|
|
||||||
func validateConfig(cfg *config) error { return cfgpkg.Validate(cfg) }
|
|
||||||
func clearWebSocketPathOnUnsupportedGOOS(cfg *config, goos string) bool {
|
|
||||||
return cfgpkg.ClearWebSocketPathOnUnsupportedGOOS(cfg, goos)
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildTLSConfig(cfg tlsConfig) (*cryptotls.Config, error) {
|
|
||||||
return cfgpkg.BuildTLS(cfg)
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
// 桥接到 internal/help — 让 web.go 中的 registerHelpRoutes /
|
|
||||||
// registerAdminHelpRoutes / renderHelpMarkdown 旧名字仍可用。
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
|
|
||||||
helppkg "meshtastic_mqtt_server/internal/help"
|
|
||||||
)
|
|
||||||
|
|
||||||
func registerHelpRoutes(r gin.IRouter, s *store) { helppkg.RegisterPublicRoutes(r, s) }
|
|
||||||
func registerAdminHelpRoutes(r gin.IRouter, s *store) { helppkg.RegisterAdminRoutes(r, s) }
|
|
||||||
func renderHelpMarkdown(markdown string) (string, error) {
|
|
||||||
return helppkg.RenderMarkdown(markdown)
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
// 桥接到 internal/llmadmin — 让 web.go 中的 registerAdminLLMRoutes 旧名仍可用。
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
|
|
||||||
llmadminpkg "meshtastic_mqtt_server/internal/llmadmin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func registerAdminLLMRoutes(r *gin.RouterGroup, s *store) {
|
|
||||||
llmadminpkg.RegisterRoutes(r, s)
|
|
||||||
}
|
|
||||||
@@ -14,15 +14,23 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"meshtastic_mqtt_server/ai"
|
|
||||||
"meshtastic_mqtt_server/autoreply"
|
|
||||||
"meshtastic_mqtt_server/llm"
|
|
||||||
"meshtastic_mqtt_server/mqtpp"
|
|
||||||
|
|
||||||
mqtt "github.com/mochi-mqtt/server/v2"
|
mqtt "github.com/mochi-mqtt/server/v2"
|
||||||
"github.com/mochi-mqtt/server/v2/hooks/auth"
|
mqttauth "github.com/mochi-mqtt/server/v2/hooks/auth"
|
||||||
"github.com/mochi-mqtt/server/v2/listeners"
|
"github.com/mochi-mqtt/server/v2/listeners"
|
||||||
"github.com/mochi-mqtt/server/v2/packets"
|
"github.com/mochi-mqtt/server/v2/packets"
|
||||||
|
|
||||||
|
"meshtastic_mqtt_server/ai"
|
||||||
|
"meshtastic_mqtt_server/autoreply"
|
||||||
|
"meshtastic_mqtt_server/internal/auth"
|
||||||
|
blockingpkg "meshtastic_mqtt_server/internal/blocking"
|
||||||
|
botpkg "meshtastic_mqtt_server/internal/bot"
|
||||||
|
configpkg "meshtastic_mqtt_server/internal/config"
|
||||||
|
mqttforwardpkg "meshtastic_mqtt_server/internal/mqttforward"
|
||||||
|
rspkg "meshtastic_mqtt_server/internal/runtimesettings"
|
||||||
|
storepkg "meshtastic_mqtt_server/internal/store"
|
||||||
|
webpkg "meshtastic_mqtt_server/internal/web"
|
||||||
|
"meshtastic_mqtt_server/llm"
|
||||||
|
"meshtastic_mqtt_server/mqtpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -39,10 +47,10 @@ const (
|
|||||||
type meshtasticFilterHook struct {
|
type meshtasticFilterHook struct {
|
||||||
mqtt.HookBase
|
mqtt.HookBase
|
||||||
key []byte
|
key []byte
|
||||||
dbQueue *dbWriteQueue
|
dbQueue *storepkg.WriteQueue
|
||||||
stats *meshtasticMessageStats
|
stats *mqttforwardpkg.Stats
|
||||||
blocking *blockingCache
|
blocking *blockingpkg.Cache
|
||||||
settings *runtimeSettingsCache
|
settings *rspkg.Cache
|
||||||
pkiResolver func(toNodeNum, fromNodeNum uint32) ([]byte, []byte, bool)
|
pkiResolver func(toNodeNum, fromNodeNum uint32) ([]byte, []byte, bool)
|
||||||
autoAcker func(record map[string]any)
|
autoAcker func(record map[string]any)
|
||||||
}
|
}
|
||||||
@@ -107,7 +115,7 @@ func (h *meshtasticFilterHook) rejectPublish(cl *mqtt.Client, pk packets.Packet,
|
|||||||
h.dbQueue.EnqueueDiscard(record, pk.Payload, mqttClientInfoFromClient(cl))
|
h.dbQueue.EnqueueDiscard(record, pk.Payload, mqttClientInfoFromClient(cl))
|
||||||
}
|
}
|
||||||
|
|
||||||
func blockingViolationForRecord(blocking *blockingCache, record map[string]any) map[string]any {
|
func blockingViolationForRecord(blocking *blockingpkg.Cache, record map[string]any) map[string]any {
|
||||||
if blocking == nil || record == nil {
|
if blocking == nil || record == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -129,12 +137,12 @@ func blockingViolationForRecord(blocking *blockingCache, record map[string]any)
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func mqttClientInfoFromClient(cl *mqtt.Client) mqttClientInfo {
|
func mqttClientInfoFromClient(cl *mqtt.Client) storepkg.MQTTClientInfo {
|
||||||
if cl == nil {
|
if cl == nil {
|
||||||
return mqttClientInfo{}
|
return storepkg.MQTTClientInfo{}
|
||||||
}
|
}
|
||||||
|
|
||||||
info := mqttClientInfo{
|
info := storepkg.MQTTClientInfo{
|
||||||
ClientID: cl.ID,
|
ClientID: cl.ID,
|
||||||
Username: string(cl.Properties.Username),
|
Username: string(cl.Properties.Username),
|
||||||
Listener: cl.Net.Listener,
|
Listener: cl.Net.Listener,
|
||||||
@@ -166,8 +174,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// parseArgs 加载配置文件、解析命令行覆盖项,并展开 Meshtastic channel PSK。
|
// parseArgs 加载配置文件、解析命令行覆盖项,并展开 Meshtastic channel PSK。
|
||||||
func parseArgs() (*config, error) {
|
func parseArgs() (*configpkg.Config, error) {
|
||||||
cfg, err := loadConfig(defaultConfigPath())
|
cfg, err := configpkg.Load(configpkg.DefaultPath())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -198,9 +206,9 @@ func parseArgs() (*config, error) {
|
|||||||
if value := os.Getenv("MESH_ADMIN_SESSION_SECRET"); value != "" {
|
if value := os.Getenv("MESH_ADMIN_SESSION_SECRET"); value != "" {
|
||||||
cfg.Web.Admin.SessionSecret = value
|
cfg.Web.Admin.SessionSecret = value
|
||||||
}
|
}
|
||||||
clearWebSocketPathOnUnsupportedGOOS(cfg, runtime.GOOS)
|
configpkg.ClearWebSocketPathOnUnsupportedGOOS(cfg, runtime.GOOS)
|
||||||
|
|
||||||
if err := validateConfig(cfg); err != nil {
|
if err := configpkg.Validate(cfg); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
key, err := mqtpp.ExpandPSK(cfg.Meshtastic.PSK)
|
key, err := mqtpp.ExpandPSK(cfg.Meshtastic.PSK)
|
||||||
@@ -212,38 +220,38 @@ func parseArgs() (*config, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// run 创建 MQTT broker 和 Web 服务,并阻塞等待退出信号。
|
// run 创建 MQTT broker 和 Web 服务,并阻塞等待退出信号。
|
||||||
func run(cfg *config) error {
|
func run(cfg *configpkg.Config) error {
|
||||||
store, err := openStore(cfg.Database)
|
store, err := storepkg.OpenStore(cfg.Database)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer store.Close()
|
defer store.Close()
|
||||||
dbQueue := newDBWriteQueue(store)
|
dbQueue := storepkg.NewWriteQueue(store)
|
||||||
defer dbQueue.Close()
|
defer dbQueue.Close()
|
||||||
if err := store.EnsureDefaultAdmin(cfg.Web.Admin.Username, cfg.Web.Admin.Password); err != nil {
|
if err := store.EnsureDefaultAdmin(cfg.Web.Admin.Username, cfg.Web.Admin.Password); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
blocking, err := newBlockingCache(store)
|
blocking, err := blockingpkg.New(store)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
settings, err := newRuntimeSettingsCache(store)
|
settings, err := rspkg.New(store)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
messageStats := &meshtasticMessageStats{}
|
messageStats := &mqttforwardpkg.Stats{}
|
||||||
server, mqttHook, mqttAddr, err := startMQTTServer(cfg, store, dbQueue, messageStats, blocking, settings)
|
server, mqttHook, mqttAddr, err := startMQTTServer(cfg, store, dbQueue, messageStats, blocking, settings)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
botSender := newBotService(store, server, cfg.Key)
|
botSender := botpkg.NewService(store, server, cfg.Key)
|
||||||
mqttHook.autoAcker = botSender.MaybeAutoAck
|
mqttHook.autoAcker = botSender.MaybeAutoAck
|
||||||
botCtx, stopBotBroadcaster := context.WithCancel(context.Background())
|
botCtx, stopBotBroadcaster := context.WithCancel(context.Background())
|
||||||
defer stopBotBroadcaster()
|
defer stopBotBroadcaster()
|
||||||
botSender.StartNodeInfoBroadcaster(botCtx)
|
botSender.StartNodeInfoBroadcaster(botCtx)
|
||||||
forwardManager := newMQTTForwardManager(store)
|
forwardManager := mqttforwardpkg.NewManager(store)
|
||||||
if err := forwardManager.StartFromStore(); err != nil {
|
if err := forwardManager.StartFromStore(); err != nil {
|
||||||
server.Close()
|
server.Close()
|
||||||
return err
|
return err
|
||||||
@@ -262,12 +270,12 @@ func run(cfg *config) error {
|
|||||||
providerConfigs := make([]llm.ProviderConfig, 0, len(llmProviders))
|
providerConfigs := make([]llm.ProviderConfig, 0, len(llmProviders))
|
||||||
for _, p := range llmProviders {
|
for _, p := range llmProviders {
|
||||||
providerConfigs = append(providerConfigs, llm.ProviderConfig{
|
providerConfigs = append(providerConfigs, llm.ProviderConfig{
|
||||||
Name: p.Name,
|
Name: p.Name,
|
||||||
Active: p.Active,
|
Active: p.Active,
|
||||||
APIKey: p.APIKey,
|
APIKey: p.APIKey,
|
||||||
BaseURL: p.BaseURL,
|
BaseURL: p.BaseURL,
|
||||||
Model: p.Model,
|
Model: p.Model,
|
||||||
Timeout: p.Timeout,
|
Timeout: p.Timeout,
|
||||||
ContextWindowTokens: p.ContextWindowTokens,
|
ContextWindowTokens: p.ContextWindowTokens,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -276,7 +284,7 @@ func run(cfg *config) error {
|
|||||||
botSenderAdapter := autoreply.NewBotServiceAdapter(
|
botSenderAdapter := autoreply.NewBotServiceAdapter(
|
||||||
// SendDirectText: 发送私聊消息
|
// SendDirectText: 发送私聊消息
|
||||||
func(ctx context.Context, botID uint64, toNodeNum int64, text string) error {
|
func(ctx context.Context, botID uint64, toNodeNum int64, text string) error {
|
||||||
_, err := botSender.SendText(ctx, botSendTextRequest{
|
_, err := botSender.SendText(ctx, botpkg.SendTextRequest{
|
||||||
BotID: botID,
|
BotID: botID,
|
||||||
MessageType: "direct",
|
MessageType: "direct",
|
||||||
ToNodeNum: &toNodeNum,
|
ToNodeNum: &toNodeNum,
|
||||||
@@ -286,7 +294,7 @@ func run(cfg *config) error {
|
|||||||
},
|
},
|
||||||
// SendChannelText: 发送频道消息
|
// SendChannelText: 发送频道消息
|
||||||
func(ctx context.Context, botID uint64, channelID string, text string) error {
|
func(ctx context.Context, botID uint64, channelID string, text string) error {
|
||||||
_, err := botSender.SendText(ctx, botSendTextRequest{
|
_, err := botSender.SendText(ctx, botpkg.SendTextRequest{
|
||||||
BotID: botID,
|
BotID: botID,
|
||||||
MessageType: "channel",
|
MessageType: "channel",
|
||||||
ChannelID: channelID,
|
ChannelID: channelID,
|
||||||
@@ -297,10 +305,10 @@ func run(cfg *config) error {
|
|||||||
)
|
)
|
||||||
|
|
||||||
aiService, err = ai.NewService(ai.Config{
|
aiService, err = ai.NewService(ai.Config{
|
||||||
LLMProviders: providerConfigs,
|
LLMProviders: providerConfigs,
|
||||||
DataDir: cfg.DataDir,
|
DataDir: cfg.DataDir,
|
||||||
Enabled: cfg.AI.Enabled,
|
Enabled: cfg.AI.Enabled,
|
||||||
ToolConfigStore: store,
|
ToolConfigStore: store,
|
||||||
}, store.DB(), botSenderAdapter)
|
}, store.DB(), botSenderAdapter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "Warning: failed to initialize AI service: %v\n", err)
|
fmt.Fprintf(os.Stderr, "Warning: failed to initialize AI service: %v\n", err)
|
||||||
@@ -319,12 +327,12 @@ func run(cfg *config) error {
|
|||||||
var httpServers []*http.Server
|
var httpServers []*http.Server
|
||||||
errCh := make(chan error, 2)
|
errCh := make(chan error, 2)
|
||||||
if cfg.Web.Enabled {
|
if cfg.Web.Enabled {
|
||||||
sessions, err := newSessionManager(cfg.Web.Admin)
|
sessions, err := auth.NewManager(cfg.Web.Admin)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
mqttStatus := mqttRuntimeStatus{server: server, address: mqttAddr, tls: cfg.MQTT.TLS.Enabled, stats: messageStats, dbQueue: dbQueue}
|
mqttStatus := webpkg.MQTTRuntimeStatus{Server: server, Address: mqttAddr, TLS: cfg.MQTT.TLS.Enabled, Stats: messageStats, DBQueue: dbQueue}
|
||||||
handler := newRouter(cfg.Web, store, sessions, mqttStatus, blocking, forwardManager, settings, botSender)
|
handler := webpkg.NewRouter(cfg.Web, store, sessions, mqttStatus, blocking, forwardManager, settings, botSender)
|
||||||
webAddresses := []string{}
|
webAddresses := []string{}
|
||||||
if cfg.Web.PortEnabled {
|
if cfg.Web.PortEnabled {
|
||||||
httpServer := &http.Server{
|
httpServer := &http.Server{
|
||||||
@@ -344,7 +352,7 @@ func run(cfg *config) error {
|
|||||||
httpServers = append(httpServers, httpServer)
|
httpServers = append(httpServers, httpServer)
|
||||||
webAddresses = append(webAddresses, cfg.Web.SocketPath)
|
webAddresses = append(webAddresses, cfg.Web.SocketPath)
|
||||||
go func() {
|
go func() {
|
||||||
if err := serveHTTPUnixSocket(httpServer, cfg.Web.SocketPath); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
if err := webpkg.ServeUnixSocket(httpServer, cfg.Web.SocketPath); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
||||||
errCh <- err
|
errCh <- err
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
@@ -378,9 +386,9 @@ func run(cfg *config) error {
|
|||||||
return runErr
|
return runErr
|
||||||
}
|
}
|
||||||
|
|
||||||
func startMQTTServer(cfg *config, store *store, dbQueue *dbWriteQueue, stats *meshtasticMessageStats, blocking *blockingCache, settings *runtimeSettingsCache) (*mqtt.Server, *meshtasticFilterHook, string, error) {
|
func startMQTTServer(cfg *configpkg.Config, store *storepkg.Store, dbQueue *storepkg.WriteQueue, stats *mqttforwardpkg.Stats, blocking *blockingpkg.Cache, settings *rspkg.Cache) (*mqtt.Server, *meshtasticFilterHook, string, error) {
|
||||||
server := mqtt.New(&mqtt.Options{InlineClient: true})
|
server := mqtt.New(&mqtt.Options{InlineClient: true})
|
||||||
if err := server.AddHook(new(auth.AllowHook), nil); err != nil {
|
if err := server.AddHook(new(mqttauth.AllowHook), nil); err != nil {
|
||||||
return nil, nil, "", err
|
return nil, nil, "", err
|
||||||
}
|
}
|
||||||
hook := &meshtasticFilterHook{
|
hook := &meshtasticFilterHook{
|
||||||
@@ -389,14 +397,14 @@ func startMQTTServer(cfg *config, store *store, dbQueue *dbWriteQueue, stats *me
|
|||||||
stats: stats,
|
stats: stats,
|
||||||
blocking: blocking,
|
blocking: blocking,
|
||||||
settings: settings,
|
settings: settings,
|
||||||
pkiResolver: newPKIKeyResolver(store),
|
pkiResolver: botpkg.NewPKIKeyResolver(store),
|
||||||
}
|
}
|
||||||
if err := server.AddHook(hook, nil); err != nil {
|
if err := server.AddHook(hook, nil); err != nil {
|
||||||
return nil, nil, "", err
|
return nil, nil, "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
addr := net.JoinHostPort(cfg.MQTT.Host, strconv.Itoa(cfg.MQTT.Port))
|
addr := net.JoinHostPort(cfg.MQTT.Host, strconv.Itoa(cfg.MQTT.Port))
|
||||||
tlsConfig, err := buildTLSConfig(cfg.MQTT.TLS)
|
tlsConfig, err := configpkg.BuildTLS(cfg.MQTT.TLS)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, "", err
|
return nil, nil, "", err
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-13
@@ -4,11 +4,15 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
mqtt "github.com/mochi-mqtt/server/v2"
|
mqtt "github.com/mochi-mqtt/server/v2"
|
||||||
|
|
||||||
|
blockingpkg "meshtastic_mqtt_server/internal/blocking"
|
||||||
|
storepkg "meshtastic_mqtt_server/internal/store"
|
||||||
|
"meshtastic_mqtt_server/internal/store/testutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMQTTClientInfoFromClientNil(t *testing.T) {
|
func TestMQTTClientInfoFromClientNil(t *testing.T) {
|
||||||
info := mqttClientInfoFromClient(nil)
|
info := mqttClientInfoFromClient(nil)
|
||||||
if info != (mqttClientInfo{}) {
|
if info != (storepkg.MQTTClientInfo{}) {
|
||||||
t.Fatalf("info = %#v, want zero value", info)
|
t.Fatalf("info = %#v, want zero value", info)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -42,20 +46,19 @@ func TestMQTTClientInfoFromClientUnsplitRemote(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 注:blockingViolationForRecord 的测试现在跟着 blockingCache 一起搬到了
|
// blockingViolationForRecord 的测试用真实 *Store + blocking.Cache 走完整路径,
|
||||||
// internal/blocking/violations_test.go,使用真实 *Store 构造缓存而不是
|
// 不依赖 cache 的未导出字段。
|
||||||
// 直接捏造未导出字段。这里保留 mqtt client info 这部分测试不动。
|
|
||||||
|
|
||||||
func TestBlockingViolationForRecordNode(t *testing.T) {
|
func TestBlockingViolationForRecordNode(t *testing.T) {
|
||||||
st := openTestStore(t)
|
st := testutil.OpenStore(t)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
nodeNum := int64(305419896)
|
nodeNum := int64(305419896)
|
||||||
if _, err := st.CreateNodeBlocking("!12345678", &nodeNum, "blocked", true); err != nil {
|
if _, err := st.CreateNodeBlocking("!12345678", &nodeNum, "blocked", true); err != nil {
|
||||||
t.Fatalf("CreateNodeBlocking() error = %v", err)
|
t.Fatalf("CreateNodeBlocking() error = %v", err)
|
||||||
}
|
}
|
||||||
cache, err := newBlockingCache(st)
|
cache, err := blockingpkg.New(st)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("newBlockingCache() error = %v", err)
|
t.Fatalf("blocking.New() error = %v", err)
|
||||||
}
|
}
|
||||||
record := map[string]any{"type": "position", "from": "!12345678", "from_num": uint32(305419896)}
|
record := map[string]any{"type": "position", "from": "!12345678", "from_num": uint32(305419896)}
|
||||||
violation := blockingViolationForRecord(cache, record)
|
violation := blockingViolationForRecord(cache, record)
|
||||||
@@ -65,14 +68,14 @@ func TestBlockingViolationForRecordNode(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestBlockingViolationForRecordForbiddenWordFields(t *testing.T) {
|
func TestBlockingViolationForRecordForbiddenWordFields(t *testing.T) {
|
||||||
st := openTestStore(t)
|
st := testutil.OpenStore(t)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
if _, err := st.CreateForbiddenWordBlocking("spam", "contains", false, "blocked", true); err != nil {
|
if _, err := st.CreateForbiddenWordBlocking("spam", "contains", false, "blocked", true); err != nil {
|
||||||
t.Fatalf("CreateForbiddenWordBlocking() error = %v", err)
|
t.Fatalf("CreateForbiddenWordBlocking() error = %v", err)
|
||||||
}
|
}
|
||||||
cache, err := newBlockingCache(st)
|
cache, err := blockingpkg.New(st)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("newBlockingCache() error = %v", err)
|
t.Fatalf("blocking.New() error = %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range []struct {
|
for _, tc := range []struct {
|
||||||
@@ -94,14 +97,14 @@ func TestBlockingViolationForRecordForbiddenWordFields(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestBlockingViolationForRecordAllowed(t *testing.T) {
|
func TestBlockingViolationForRecordAllowed(t *testing.T) {
|
||||||
st := openTestStore(t)
|
st := testutil.OpenStore(t)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
if _, err := st.CreateForbiddenWordBlocking("spam", "contains", false, "blocked", true); err != nil {
|
if _, err := st.CreateForbiddenWordBlocking("spam", "contains", false, "blocked", true); err != nil {
|
||||||
t.Fatalf("CreateForbiddenWordBlocking() error = %v", err)
|
t.Fatalf("CreateForbiddenWordBlocking() error = %v", err)
|
||||||
}
|
}
|
||||||
cache, err := newBlockingCache(st)
|
cache, err := blockingpkg.New(st)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("newBlockingCache() error = %v", err)
|
t.Fatalf("blocking.New() error = %v", err)
|
||||||
}
|
}
|
||||||
record := map[string]any{"type": "text_message", "from": "!1", "text": "hello"}
|
record := map[string]any{"type": "text_message", "from": "!1", "text": "hello"}
|
||||||
if violation := blockingViolationForRecord(cache, record); violation != nil {
|
if violation := blockingViolationForRecord(cache, record); violation != nil {
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
// 桥接到 internal/mapsource — 让 web.go 中的 registerMapSourceRoutes /
|
|
||||||
// registerAdminMapSourceRoutes 旧名字仍可用。
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
|
|
||||||
mspkg "meshtastic_mqtt_server/internal/mapsource"
|
|
||||||
)
|
|
||||||
|
|
||||||
func registerMapSourceRoutes(r gin.IRouter, s *store) { mspkg.RegisterPublicRoutes(r, s) }
|
|
||||||
func registerAdminMapSourceRoutes(r gin.IRouter, s *store) { mspkg.RegisterAdminRoutes(r, s) }
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
// 桥接到 internal/mqttforward — 让 main.go / web.go / mqtt_status.go 中
|
|
||||||
// 使用 mqttForwardManager / meshtasticMessageStats / mqttForwardReloader 等
|
|
||||||
// 旧名字的代码仍可工作。
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
|
|
||||||
mfpkg "meshtastic_mqtt_server/internal/mqttforward"
|
|
||||||
)
|
|
||||||
|
|
||||||
type (
|
|
||||||
mqttForwardManager = mfpkg.Manager
|
|
||||||
mqttForwardReloader = mfpkg.Reloader
|
|
||||||
mqttForwardRuntimeStatus = mfpkg.RuntimeStatus
|
|
||||||
meshtasticMessageStats = mfpkg.Stats
|
|
||||||
)
|
|
||||||
|
|
||||||
func newMQTTForwardManager(s *store) *mqttForwardManager {
|
|
||||||
return mfpkg.NewManager(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
func registerAdminMQTTForwardRoutes(r gin.IRouter, s *store, forwarder mqttForwardReloader) {
|
|
||||||
mfpkg.RegisterRoutes(r, s, forwarder)
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
// 桥接到 internal/runtimesettings — 让根目录代码继续使用旧的小写名字。
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
|
|
||||||
rspkg "meshtastic_mqtt_server/internal/runtimesettings"
|
|
||||||
)
|
|
||||||
|
|
||||||
type runtimeSettingsCache = rspkg.Cache
|
|
||||||
|
|
||||||
func newRuntimeSettingsCache(s *store) (*runtimeSettingsCache, error) {
|
|
||||||
return rspkg.New(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
func registerAdminRuntimeSettingsRoutes(r gin.IRouter, s *store, c *runtimeSettingsCache) {
|
|
||||||
rspkg.RegisterRoutes(r, s, c)
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
// 桥接到 internal/sign — 让 web.go 中 registerAdminSignRoutes / signDTO /
|
|
||||||
// signDayCountDTO 旧名字仍可用。
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
|
|
||||||
signpkg "meshtastic_mqtt_server/internal/sign"
|
|
||||||
)
|
|
||||||
|
|
||||||
func registerAdminSignRoutes(r gin.IRouter, s *store) {
|
|
||||||
signpkg.RegisterAdminRoutes(r, s)
|
|
||||||
}
|
|
||||||
|
|
||||||
func signDTO(row signRecord) gin.H { return signpkg.SignDTO(row) }
|
|
||||||
func signDayCountDTO(row signDayCount) gin.H { return signpkg.SignDayCountDTO(row) }
|
|
||||||
-145
@@ -1,145 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
// 桥接到 internal/store —— 让根目录其余文件无须修改即可继续使用旧的小写类型/函数名。
|
|
||||||
// 当各领域包逐步迁出根目录后,可以删除这些别名。
|
|
||||||
|
|
||||||
import (
|
|
||||||
storepkg "meshtastic_mqtt_server/internal/store"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ---- 类型别名 ----
|
|
||||||
|
|
||||||
type (
|
|
||||||
store = storepkg.Store
|
|
||||||
mqttClientInfo = storepkg.MQTTClientInfo
|
|
||||||
dbWriteQueue = storepkg.WriteQueue
|
|
||||||
listOptions = storepkg.ListOptions
|
|
||||||
mapReportViewportOptions = storepkg.MapReportViewportOptions
|
|
||||||
mapReportViewportResult = storepkg.MapReportViewportResult
|
|
||||||
mapReportClusterRecord = storepkg.MapReportClusterRecord
|
|
||||||
userRecord = storepkg.UserRecord
|
|
||||||
loginLogRecord = storepkg.LoginLogRecord
|
|
||||||
helpContentRecord = storepkg.HelpContentRecord
|
|
||||||
runtimeSettingRecord = storepkg.RuntimeSettingRecord
|
|
||||||
mapTileSourceRecord = storepkg.MapTileSourceRecord
|
|
||||||
mapTileSourceInput = storepkg.MapTileSourceInput
|
|
||||||
discardDetailsRecord = storepkg.DiscardDetailsRecord
|
|
||||||
signRecord = storepkg.SignRecord
|
|
||||||
nodeBlockingRecord = storepkg.NodeBlockingRecord
|
|
||||||
ipBlockingRecord = storepkg.IPBlockingRecord
|
|
||||||
forbiddenWordBlockingRecord = storepkg.ForbiddenWordBlockingRecord
|
|
||||||
mqttForwarderRecord = storepkg.MQTTForwarderRecord
|
|
||||||
mqttForwarderInput = storepkg.MQTTForwarderInput
|
|
||||||
mqttForwardTopicRecord = storepkg.MQTTForwardTopicRecord
|
|
||||||
mqttForwardTopicInput = storepkg.MQTTForwardTopicInput
|
|
||||||
botNodeRecord = storepkg.BotNodeRecord
|
|
||||||
botNodeInput = storepkg.BotNodeInput
|
|
||||||
botMessageRecord = storepkg.BotMessageRecord
|
|
||||||
botDirectMessageRecord = storepkg.BotDirectMessageRecord
|
|
||||||
llmMessageQueueRecord = storepkg.LLMMessageQueueRecord
|
|
||||||
nodeInfoRecord = storepkg.NodeInfoRecord
|
|
||||||
mapReportRecord = storepkg.MapReportRecord
|
|
||||||
textMessageRecord = storepkg.TextMessageRecord
|
|
||||||
llmProviderRecord = storepkg.LLMProviderRecord
|
|
||||||
llmToolRouterRecord = storepkg.LLMToolRouterRecord
|
|
||||||
llmPrimaryConfigRecord = storepkg.LLMPrimaryConfigRecord
|
|
||||||
positionRecord = storepkg.PositionRecord
|
|
||||||
telemetryRecord = storepkg.TelemetryRecord
|
|
||||||
routingRecord = storepkg.RoutingRecord
|
|
||||||
tracerouteRecord = storepkg.TracerouteRecord
|
|
||||||
)
|
|
||||||
|
|
||||||
// AppendPacketFields / MQTTClientRecordFields 已经是导出名,不需要别名。
|
|
||||||
// 直接用包限定名供 root 文件调用:
|
|
||||||
type (
|
|
||||||
AppendPacketFields = storepkg.AppendPacketFields
|
|
||||||
MQTTClientRecordFields = storepkg.MQTTClientRecordFields
|
|
||||||
)
|
|
||||||
|
|
||||||
// 其它额外导出类型的别名(旧的小写形式仍被根目录文件直接使用)。
|
|
||||||
type (
|
|
||||||
runtimeSettingsSnapshot = storepkg.RuntimeSettingsSnapshot
|
|
||||||
mqttForwarderConfig = storepkg.MQTTForwarderConfig
|
|
||||||
botDirectMessageListOptions = storepkg.BotDirectMessageListOptions
|
|
||||||
botMessageListOptions = storepkg.BotMessageListOptions
|
|
||||||
botDirectConversation = storepkg.BotDirectConversation
|
|
||||||
signDayCount = storepkg.SignDayCount
|
|
||||||
)
|
|
||||||
|
|
||||||
var errBlockingAlreadyExists = storepkg.ErrBlockingAlreadyExists
|
|
||||||
var errBotNodeAlreadyExists = storepkg.ErrBotNodeAlreadyExists
|
|
||||||
var (
|
|
||||||
errMapTileSourceAlreadyExists = storepkg.ErrMapTileSourceAlreadyExists
|
|
||||||
errMapTileSourceCannotDeleteDefault = storepkg.ErrMapTileSourceCannotDeleteDefault
|
|
||||||
errMapTileSourceCannotDisableDefault = storepkg.ErrMapTileSourceCannotDisableDefault
|
|
||||||
errMapTileSourceDefaultMustBeEnabled = storepkg.ErrMapTileSourceDefaultMustBeEnabled
|
|
||||||
)
|
|
||||||
|
|
||||||
func mapTileSourceHash(urlTemplate string) string {
|
|
||||||
return storepkg.MapTileSourceHash(urlTemplate)
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
forbiddenWordMatchContains = storepkg.ForbiddenWordMatchContains
|
|
||||||
runtimeSettingAllowEncryptedForwarding = storepkg.RuntimeSettingAllowEncryptedForwarding
|
|
||||||
runtimeSettingLLMQueueEnabled = storepkg.RuntimeSettingLLMQueueEnabled
|
|
||||||
runtimeSettingLLMQueueIncludeChannel = storepkg.RuntimeSettingLLMQueueIncludeChannel
|
|
||||||
|
|
||||||
botDefaultPSK = storepkg.BotDefaultPSK
|
|
||||||
botMessageTypeChannel = storepkg.BotMessageTypeChannel
|
|
||||||
botMessageTypeDirect = storepkg.BotMessageTypeDirect
|
|
||||||
botMessageStatusPending = storepkg.BotMessageStatusPending
|
|
||||||
botMessageStatusPublished = storepkg.BotMessageStatusPublished
|
|
||||||
botMessageStatusFailed = storepkg.BotMessageStatusFailed
|
|
||||||
botDirectMessageDirectionInbound = storepkg.BotDirectMessageDirectionInbound
|
|
||||||
botDirectMessageDirectionOutbound = storepkg.BotDirectMessageDirectionOutbound
|
|
||||||
botDefaultTopicPrefix = storepkg.BotDefaultTopicPrefix
|
|
||||||
|
|
||||||
mqttForwardDirectionSourceToTarget = storepkg.MQTTForwardDirectionSourceToTarget
|
|
||||||
mqttForwardDirectionBidirectional = storepkg.MQTTForwardDirectionBidirectional
|
|
||||||
)
|
|
||||||
|
|
||||||
const botDefaultNodeInfoBroadcastSeconds = storepkg.BotDefaultNodeInfoBroadcastSeconds
|
|
||||||
|
|
||||||
func validateBotNodeNum(n int64) error { return storepkg.ValidateBotNodeNum(n) }
|
|
||||||
|
|
||||||
var errUserAlreadyExists = storepkg.ErrUserAlreadyExists
|
|
||||||
|
|
||||||
var (
|
|
||||||
errMQTTForwarderAlreadyExists = storepkg.ErrMQTTForwarderAlreadyExists
|
|
||||||
errMQTTForwardTopicAlreadyExists = storepkg.ErrMQTTForwardTopicAlreadyExists
|
|
||||||
)
|
|
||||||
|
|
||||||
func nullableString(v any) *string { return storepkg.NullableString(v) }
|
|
||||||
func nullableStringValue(v any) *string { return storepkg.NullableStringValue(v) }
|
|
||||||
func decodeBotPublicKey(row botNodeRecord) ([]byte, error) {
|
|
||||||
return storepkg.DecodeBotPublicKey(row)
|
|
||||||
}
|
|
||||||
|
|
||||||
// LLM 消息队列状态字符串常量。
|
|
||||||
const (
|
|
||||||
llmMessageStatusPending = storepkg.LLMMessageStatusPending
|
|
||||||
llmMessageStatusProcessing = storepkg.LLMMessageStatusProcessing
|
|
||||||
llmMessageStatusProcessed = storepkg.LLMMessageStatusProcessed
|
|
||||||
llmMessageStatusError = storepkg.LLMMessageStatusError
|
|
||||||
)
|
|
||||||
|
|
||||||
const defaultHelpMarkdown = storepkg.DefaultHelpMarkdown
|
|
||||||
|
|
||||||
// 旧名 llmMessageDTO 现在通过 store 提供。
|
|
||||||
func llmMessageDTO(row llmMessageQueueRecord) map[string]any {
|
|
||||||
return storepkg.LLMMessageDTO(row)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- 工厂函数包装 ----
|
|
||||||
|
|
||||||
func openStore(cfg databaseConfig) (*store, error) { return storepkg.OpenStore(cfg) }
|
|
||||||
func normalizeListOptions(o listOptions) listOptions {
|
|
||||||
return storepkg.NormalizeListOptions(o)
|
|
||||||
}
|
|
||||||
func normalizeMapReportViewportOptions(o mapReportViewportOptions) mapReportViewportOptions {
|
|
||||||
return storepkg.NormalizeMapReportViewportOptions(o)
|
|
||||||
}
|
|
||||||
|
|
||||||
// newDBWriteQueue 在新包里更名,提供旧名字避免改 main.go。
|
|
||||||
func newDBWriteQueue(s *store) *dbWriteQueue { return storepkg.NewWriteQueue(s) }
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
storepkg "meshtastic_mqtt_server/internal/store"
|
|
||||||
)
|
|
||||||
|
|
||||||
// openTestStore 在根目录的测试中沿用旧函数名,但底层调用 internal/store 的实现。
|
|
||||||
func openTestStore(t *testing.T) *store {
|
|
||||||
t.Helper()
|
|
||||||
st, err := storepkg.OpenStore(databaseConfig{
|
|
||||||
Driver: databaseDriverSQLite,
|
|
||||||
SQLite: sqliteConfig{Path: filepath.Join(t.TempDir(), "mesh_mqtt_go.db")},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("OpenStore() error = %v", err)
|
|
||||||
}
|
|
||||||
return st
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
// 桥接到 internal/web — 让 main.go 中使用 newSessionManager / newRouter /
|
|
||||||
// mqttRuntimeStatus / serveHTTPUnixSocket 这些旧名字的代码继续编译。
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
mqtt "github.com/mochi-mqtt/server/v2"
|
|
||||||
|
|
||||||
"meshtastic_mqtt_server/internal/auth"
|
|
||||||
mqttforwardpkg "meshtastic_mqtt_server/internal/mqttforward"
|
|
||||||
storepkg "meshtastic_mqtt_server/internal/store"
|
|
||||||
webpkg "meshtastic_mqtt_server/internal/web"
|
|
||||||
)
|
|
||||||
|
|
||||||
// 旧类型/旧函数名 → 新位置的别名。
|
|
||||||
|
|
||||||
type mqttRuntimeStatusInternal = webpkg.MQTTRuntimeStatus
|
|
||||||
|
|
||||||
// mqttRuntimeStatus 旧名字保持小写、字段也是小写——这里用一个适配类型把
|
|
||||||
// main 包的旧字段写法包到 web 包导出的大写字段上。
|
|
||||||
type mqttRuntimeStatus struct {
|
|
||||||
server *mqtt.Server
|
|
||||||
address string
|
|
||||||
tls bool
|
|
||||||
stats *meshtasticMessageStats
|
|
||||||
dbQueue *dbWriteQueue
|
|
||||||
}
|
|
||||||
|
|
||||||
// 让 mqttRuntimeStatus 自动实现 webpkg.MQTTStatusProvider,把请求转给真正的实现。
|
|
||||||
func (m mqttRuntimeStatus) Status() webpkg.AdminMQTTStatus {
|
|
||||||
return webpkg.MQTTRuntimeStatus{
|
|
||||||
Server: m.server,
|
|
||||||
Address: m.address,
|
|
||||||
TLS: m.tls,
|
|
||||||
Stats: m.stats,
|
|
||||||
DBQueue: m.dbQueue,
|
|
||||||
}.Status()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 让旧代码里 `mqttforwardpkg.Stats` 别名留作 main 包内可见。
|
|
||||||
var _ *mqttforwardpkg.Stats = (*meshtasticMessageStats)(nil)
|
|
||||||
|
|
||||||
func newSessionManager(cfg webAdminConfig) (*auth.Manager, error) {
|
|
||||||
return auth.NewManager(cfg)
|
|
||||||
}
|
|
||||||
|
|
||||||
func newRouter(cfg webConfig, store *storepkg.Store, sessions *auth.Manager, mqttStatus webpkg.MQTTStatusProvider, blocking *blockingCache, forwarder mqttForwardReloader, settings *runtimeSettingsCache, botSender botTextSender) *gin.Engine {
|
|
||||||
return webpkg.NewRouter(cfg, store, sessions, mqttStatus, blocking, forwarder, settings, botSender)
|
|
||||||
}
|
|
||||||
|
|
||||||
func serveHTTPUnixSocket(server *http.Server, socketPath string) error {
|
|
||||||
return webpkg.ServeUnixSocket(server, socketPath)
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user