Files
lmvpn_server/internal/vpn/tunnel.go
T
kevin 91c9e12c3c 添加 WebSocket VPN 接口及用户认证
- 移动 config 包到 internal/config,新增 DatabaseConfig
- 使用 GORM + SQLite 管理用户数据,预留 MySQL 支持
- 新增 internal/model/user.go GORM 用户模型
- 新增 internal/db/db.go 数据库初始化及默认管理员
- 新增 internal/vpn/ WebSocket 鉴权与隧道骨架
- /ws 路径支持用户名+密码鉴权 (bcrypt)
- 心跳保活 + echo 隧道模式
2026-07-02 20:30:11 +08:00

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
}
}
}