128 lines
2.8 KiB
Go
128 lines
2.8 KiB
Go
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)
|
||
}
|
||
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)
|
||
}
|