- 移动 config 包到 internal/config,新增 DatabaseConfig - 使用 GORM + SQLite 管理用户数据,预留 MySQL 支持 - 新增 internal/model/user.go GORM 用户模型 - 新增 internal/db/db.go 数据库初始化及默认管理员 - 新增 internal/vpn/ WebSocket 鉴权与隧道骨架 - /ws 路径支持用户名+密码鉴权 (bcrypt) - 心跳保活 + echo 隧道模式
54 lines
1.1 KiB
Go
54 lines
1.1 KiB
Go
package vpn
|
|
|
|
import (
|
|
"log"
|
|
"time"
|
|
|
|
"lmvpn/internal/model"
|
|
|
|
"github.com/gorilla/websocket"
|
|
)
|
|
|
|
const (
|
|
readTimeout = 60 * time.Second
|
|
writeTimeout = 10 * time.Second
|
|
pingPeriod = 30 * time.Second
|
|
)
|
|
|
|
func runTunnel(conn *websocket.Conn, user *model.User) {
|
|
defer conn.Close()
|
|
|
|
log.Printf("用户 %s 已连接", user.Username)
|
|
|
|
go func() {
|
|
ticker := time.NewTicker(pingPeriod)
|
|
defer ticker.Stop()
|
|
for range ticker.C {
|
|
conn.SetWriteDeadline(time.Now().Add(writeTimeout))
|
|
if err := conn.WriteMessage(websocket.PingMessage, nil); err != nil {
|
|
return
|
|
}
|
|
}
|
|
}()
|
|
|
|
conn.SetPongHandler(func(string) error {
|
|
conn.SetReadDeadline(time.Now().Add(readTimeout))
|
|
return nil
|
|
})
|
|
|
|
for {
|
|
conn.SetReadDeadline(time.Now().Add(readTimeout))
|
|
messageType, data, err := conn.ReadMessage()
|
|
if err != nil {
|
|
log.Printf("用户 %s 断开连接: %v", user.Username, err)
|
|
return
|
|
}
|
|
|
|
conn.SetWriteDeadline(time.Now().Add(writeTimeout))
|
|
if err := conn.WriteMessage(messageType, data); err != nil {
|
|
log.Printf("用户 %s 发送失败: %v", user.Username, err)
|
|
return
|
|
}
|
|
}
|
|
}
|