l_szy_go/main.go

129 lines
2.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 main
import (
"bytes"
"fmt"
"github.com/caarlos0/env/v6"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/websocket/v2"
"l_szr_go/pkg"
"os/signal"
"syscall"
"time"
"l_szr_go/entity"
"log"
"os"
"sync"
)
var (
config entity.Config
activeConnections sync.WaitGroup
)
func Server() *fiber.App {
app := fiber.New()
// 健康检查
app.Get("/health", func(c *fiber.Ctx) error {
return c.SendStatus(fiber.StatusOK)
})
// WebSocket 路由
app.Use("/ws", func(c *fiber.Ctx) error {
if websocket.IsWebSocketUpgrade(c) {
c.Locals("allowed", true)
return c.Next()
}
return fiber.ErrUpgradeRequired
})
app.Get("/ws", websocket.New(HandleWebSocket))
return app
}
func HandleWebSocket(c *websocket.Conn) {
activeConnections.Add(1)
defer activeConnections.Done()
var audioBuffer bytes.Buffer
fileName := fmt.Sprintf("output_%s.wav",
time.Now().Format("20060102_150405.000"))
log.Printf("客户端连接: %s", c.RemoteAddr())
defer func() {
if audioBuffer.Len() == 0 {
log.Println("未接收到音频数据,跳过保存")
return
}
if err := pkg.SaveAsWav(&audioBuffer, fileName, config); err != nil {
log.Printf("保存文件失败: %v", err)
} else {
log.Printf("音频已保存为 %s (%d字节)", fileName, audioBuffer.Len())
}
}()
for {
_, message, err := c.ReadMessage()
if err != nil {
if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) {
log.Printf("客户端异常断开: %v", err)
} else {
log.Println("客户端主动断开")
}
break
}
// 检查缓冲区大小
if audioBuffer.Len()+len(message) > config.MaxBufferSize {
log.Println("达到最大缓冲区大小,断开连接")
break
}
// 验证PCM数据 (基本验证)
if config.BitDepth == 16 && len(message)%2 != 0 {
log.Println("接收到无效的16位PCM数据长度不是2的倍数")
continue
}
if _, err := audioBuffer.Write(message); err != nil {
log.Printf("写入缓冲区失败: %v", err)
break
}
log.Printf("接收到 %d 字节音频数据 (总大小: %d字节)",
len(message), audioBuffer.Len())
}
}
func main() {
if err := env.Parse(&config); err != nil {
log.Fatalf("加载配置失败: %v", err)
}
fmt.Print(config.SampleRate)
app := Server()
// 启动服务器
go func() {
log.Printf("服务器启动,监听端口 %s", config.Port)
log.Printf("音频配置: %dHz, %d通道, %d位深",
config.SampleRate, config.Channels, config.BitDepth)
if err := app.Listen(":" + config.Port); err != nil {
log.Fatalf("服务器启动失败: %v", err)
}
}()
// 优雅关闭
quit := make(chan os.Signal, 1)
signal.Notify(quit, os.Interrupt, syscall.SIGTERM)
<-quit
log.Println("正在关闭服务器...")
// 等待所有连接完成
activeConnections.Wait()
log.Println("所有连接已关闭")
os.Exit(0)
}