Skip to content

Commit 28465a2

Browse files
committed
feat: SignalServer bug
1 parent f8b7c09 commit 28465a2

6 files changed

Lines changed: 126 additions & 41 deletions

File tree

SignalingServer/cmd/signaling/main.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,16 +83,17 @@ func main() {
8383
}
8484

8585
// Initialize handlers
86-
apiHandler := handler.NewAPIHandler(deviceService, authService, presetService, settingsService, cfg)
86+
apiHandler := handler.NewAPIHandler(deviceService, authService, presetService, settingsService, cfg, db)
8787
wsHandler := handler.NewWSHandler(deviceService, authService, db, redisClient)
88-
88+
8989
apiHandler.SetWSHandler(wsHandler)
9090

9191
gin.SetMode(gin.ReleaseMode)
9292
router := gin.New()
9393
router.Use(gin.Recovery())
9494
router.Use(middleware.LoggerMiddleware())
9595
router.Use(middleware.CORSMiddleware(settingsService))
96+
router.Use(apiHandler.APIRequestCounterMiddleware())
9697

9798
apiKeyAuth := middleware.NewAPIKeyAuth(settingsService)
9899

SignalingServer/internal/handler/api_handler.go

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"quickdesk/signaling/internal/models"
1313
"quickdesk/signaling/internal/service"
1414
"runtime"
15+
"sync/atomic"
1516
"time"
1617

1718
"github.com/gin-gonic/gin"
@@ -20,6 +21,7 @@ import (
2021
"github.com/shirou/gopsutil/v3/host"
2122
"github.com/shirou/gopsutil/v3/mem"
2223
psnet "github.com/shirou/gopsutil/v3/net"
24+
"gorm.io/gorm"
2325
)
2426

2527
type APIHandler struct {
@@ -29,23 +31,34 @@ type APIHandler struct {
2931
settingsService *service.SettingsService
3032
config *config.Config
3133
wsHandler *WSHandler
34+
db *gorm.DB
35+
apiRequestCount int64
3236
lastNetIO psnet.IOCountersStat
3337
lastNetIOTime time.Time
3438
uploadSpeed float64
3539
downloadSpeed float64
3640
}
3741

38-
func NewAPIHandler(deviceService *service.DeviceService, authService *service.AuthService, presetService *service.PresetService, settingsService *service.SettingsService, cfg *config.Config) *APIHandler {
42+
func NewAPIHandler(deviceService *service.DeviceService, authService *service.AuthService, presetService *service.PresetService, settingsService *service.SettingsService, cfg *config.Config, db *gorm.DB) *APIHandler {
3943
return &APIHandler{
4044
deviceService: deviceService,
4145
authService: authService,
4246
presetService: presetService,
4347
settingsService: settingsService,
4448
config: cfg,
49+
db: db,
4550
lastNetIOTime: time.Now(),
4651
}
4752
}
4853

54+
// APIRequestCounterMiddleware increments the API request counter for each request
55+
func (h *APIHandler) APIRequestCounterMiddleware() gin.HandlerFunc {
56+
return func(c *gin.Context) {
57+
atomic.AddInt64(&h.apiRequestCount, 1)
58+
c.Next()
59+
}
60+
}
61+
4962
// SetWSHandler sets the WebSocket handler reference (called after WSHandler is created)
5063
func (h *APIHandler) SetWSHandler(ws *WSHandler) {
5164
h.wsHandler = ws
@@ -438,11 +451,39 @@ func (h *APIHandler) GetConnectionStatus(c *gin.Context) {
438451
"currentConnections": wsConnections,
439452
"todayConnections": wsConnections,
440453
"webSocketConnections": wsConnections,
441-
"apiRequests": 0,
454+
"apiRequests": atomic.LoadInt64(&h.apiRequestCount),
442455
})
443456
}
444457

445458
// GetActivity handles GET /admin/activity
446459
func (h *APIHandler) GetActivity(c *gin.Context) {
447-
c.JSON(http.StatusOK, []gin.H{})
460+
var histories []models.ConnectionHistory
461+
h.db.Order("created_at DESC").Limit(50).Find(&histories)
462+
463+
activity := make([]gin.H, 0, len(histories))
464+
for _, hist := range histories {
465+
action := "远程连接"
466+
details := fmt.Sprintf("用户 %d 连接设备 %s", hist.UserID, hist.DeviceID)
467+
if hist.DeviceName != "" {
468+
details = fmt.Sprintf("用户 %d 连接设备 %s (%s)", hist.UserID, hist.DeviceID, hist.DeviceName)
469+
}
470+
if hist.ErrorMsg != "" {
471+
details += " - " + hist.ErrorMsg
472+
}
473+
474+
status := hist.Status
475+
if status == "" {
476+
status = "success"
477+
}
478+
479+
activity = append(activity, gin.H{
480+
"time": hist.CreatedAt.Format("2006-01-02 15:04:05"),
481+
"deviceId": hist.DeviceID,
482+
"action": action,
483+
"details": details,
484+
"status": status,
485+
})
486+
}
487+
488+
c.JSON(http.StatusOK, gin.H{"activity": activity})
448489
}

SignalingServer/internal/handler/ws_handler.go

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,11 @@ const (
2929

3030
// WebSocket message types
3131
type WSMessage struct {
32-
Type string `json:"type"`
33-
Password string `json:"password,omitempty"`
32+
Type string `json:"type"`
33+
Password string `json:"password,omitempty"`
34+
OS string `json:"os,omitempty"`
35+
OSVersion string `json:"os_version,omitempty"`
36+
AppVersion string `json:"app_version,omitempty"`
3437
}
3538

3639
var upgrader = websocket.Upgrader{
@@ -130,25 +133,30 @@ func (h *WSHandler) HandleWebSocket(c *gin.Context) {
130133

131134
// Host connection: Auto-register if not exists, create temp password
132135
if !isClient {
136+
// Read device info from query params
137+
osInfo := c.DefaultQuery("os", "Unknown")
138+
osVersion := c.DefaultQuery("os_version", "Unknown")
139+
appVersion := c.DefaultQuery("app_version", "Unknown")
140+
133141
// Check if device exists
134142
_, err := h.deviceService.GetByDeviceID(c.Request.Context(), deviceID)
135143
if err != nil {
136144
// Device doesn't exist, register it
137145
log.Printf("Device %s not registered, auto-registering...", deviceID)
138146
req := &service.RegisterDeviceRequest{
139-
OS: "Unknown",
140-
OSVersion: "Unknown",
141-
AppVersion: "1.0.0",
147+
OS: osInfo,
148+
OSVersion: osVersion,
149+
AppVersion: appVersion,
142150
}
143-
151+
144152
// Use provided device_id
145153
device, err := h.deviceService.RegisterDeviceWithID(c.Request.Context(), deviceID, req)
146154
if err != nil {
147155
log.Printf("Failed to register device: %v", err)
148156
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to register device"})
149157
return
150158
}
151-
159+
152160
// Generate and set temporary password
153161
tempPassword := h.authService.GenerateTemporaryPassword()
154162
if accessCode == "" {
@@ -158,10 +166,13 @@ func (h *WSHandler) HandleWebSocket(c *gin.Context) {
158166
if err != nil {
159167
log.Printf("Failed to set temporary password: %v", err)
160168
}
161-
169+
162170
log.Printf("Device registered: device_id=%s, temp_password=%s", device.DeviceID, accessCode)
163171
} else {
164-
// Device exists, update temporary password if provided
172+
// Device exists, update device info and temporary password
173+
if osInfo != "Unknown" || osVersion != "Unknown" || appVersion != "Unknown" {
174+
h.deviceService.UpdateDeviceInfo(c.Request.Context(), deviceID, osInfo, osVersion, appVersion)
175+
}
165176
if accessCode != "" {
166177
err = h.authService.SetTemporaryPassword(c.Request.Context(), deviceID, accessCode)
167178
if err != nil {
@@ -297,6 +308,18 @@ func (h *WSHandler) HandleWebSocket(c *gin.Context) {
297308
}
298309
continue // Don't forward this message to clients
299310
}
311+
if !isClient && wsMsg.Type == "set_device_info" {
312+
// Host is reporting its device info (OS, version, etc.)
313+
if wsMsg.OS != "" || wsMsg.OSVersion != "" || wsMsg.AppVersion != "" {
314+
h.deviceService.UpdateDeviceInfo(context.Background(), deviceID, wsMsg.OS, wsMsg.OSVersion, wsMsg.AppVersion)
315+
log.Printf("Device info updated for %s: os=%s, os_version=%s, app_version=%s",
316+
deviceID, wsMsg.OS, wsMsg.OSVersion, wsMsg.AppVersion)
317+
h.sendToConnection(conn, map[string]interface{}{
318+
"type": "device_info_set",
319+
})
320+
}
321+
continue
322+
}
300323
}
301324

302325
// Forward message

SignalingServer/internal/repository/device_repo.go

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,13 @@ func (r *DeviceRepository) Update(ctx context.Context, device *models.Device) er
4242

4343
// SetOnline updates the online status of a device
4444
func (r *DeviceRepository) SetOnline(ctx context.Context, deviceID string, online bool) error {
45+
updates := map[string]interface{}{"online": online}
46+
if online {
47+
updates["last_seen"] = time.Now()
48+
}
4549
return r.db.WithContext(ctx).Model(&models.Device{}).
4650
Where("device_id = ?", deviceID).
47-
Update("online", online).Error
51+
Updates(updates).Error
4852
}
4953

5054
// UpdateLastSeen updates the last_seen timestamp of a device
@@ -54,6 +58,26 @@ func (r *DeviceRepository) UpdateLastSeen(ctx context.Context, deviceID string)
5458
Update("last_seen", time.Now()).Error
5559
}
5660

61+
// UpdateDeviceInfo updates OS, OSVersion, and AppVersion for a device
62+
func (r *DeviceRepository) UpdateDeviceInfo(ctx context.Context, deviceID, os, osVersion, appVersion string) error {
63+
updates := map[string]interface{}{}
64+
if os != "" {
65+
updates["os"] = os
66+
}
67+
if osVersion != "" {
68+
updates["os_version"] = osVersion
69+
}
70+
if appVersion != "" {
71+
updates["app_version"] = appVersion
72+
}
73+
if len(updates) == 0 {
74+
return nil
75+
}
76+
return r.db.WithContext(ctx).Model(&models.Device{}).
77+
Where("device_id = ?", deviceID).
78+
Updates(updates).Error
79+
}
80+
5781
// List retrieves devices with pagination
5882
func (r *DeviceRepository) List(ctx context.Context, offset, limit int) ([]models.Device, error) {
5983
var devices []models.Device

SignalingServer/internal/service/device_service.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,16 @@ func (s *DeviceService) RegisterDevice(ctx context.Context, req *RegisterDeviceR
8585
if req.DeviceID != "" {
8686
existingDevice, err := s.repo.GetByDeviceID(ctx, req.DeviceID)
8787
if err == nil {
88-
// Device exists, update last_seen and return
88+
// Device exists, update last_seen and device info
8989
log.Printf("Device already exists: device_id=%s", req.DeviceID)
9090
s.repo.UpdateLastSeen(ctx, req.DeviceID)
91+
// Update device info if provided (handles app upgrades)
92+
if req.OS != "" || req.OSVersion != "" || req.AppVersion != "" {
93+
s.repo.UpdateDeviceInfo(ctx, req.DeviceID, req.OS, req.OSVersion, req.AppVersion)
94+
existingDevice.OS = req.OS
95+
existingDevice.OSVersion = req.OSVersion
96+
existingDevice.AppVersion = req.AppVersion
97+
}
9198
return existingDevice, false, nil
9299
}
93100
if err != gorm.ErrRecordNotFound {
@@ -181,4 +188,11 @@ func (s *DeviceService) IsDeviceOnline(ctx context.Context, deviceID string) (bo
181188
// GetAllDevices returns all devices
182189
func (s *DeviceService) GetAllDevices(ctx context.Context) ([]models.Device, error) {
183190
return s.repo.GetAll(ctx)
191+
}
192+
193+
// UpdateDeviceInfo updates OS, OSVersion, and AppVersion for a device
194+
func (s *DeviceService) UpdateDeviceInfo(ctx context.Context, deviceID, os, osVersion, appVersion string) {
195+
if err := s.repo.UpdateDeviceInfo(ctx, deviceID, os, osVersion, appVersion); err != nil {
196+
log.Printf("Failed to update device info for %s: %v", deviceID, err)
197+
}
184198
}

SignalingServer/web/src/views/HomePage.vue

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -142,29 +142,7 @@ const connectionStatus = ref({
142142
apiRequests: 0
143143
})
144144
145-
const activityList = ref([
146-
{
147-
time: '2026-03-06 14:45:35',
148-
deviceId: '642407192',
149-
action: '设备登录',
150-
details: '设备 642407192 成功登录',
151-
status: 'success'
152-
},
153-
{
154-
time: '2026-03-06 14:40:12',
155-
deviceId: '123456789',
156-
action: '设备注册',
157-
details: '新设备 123456789 注册成功',
158-
status: 'success'
159-
},
160-
{
161-
time: '2026-03-06 14:35:45',
162-
deviceId: '987654321',
163-
action: '密码验证',
164-
details: '设备 987654321 密码验证失败',
165-
status: 'failed'
166-
}
167-
])
145+
const activityList = ref([])
168146
169147
function rowClassName({ row }) {
170148
return row.status === 'success' ? 'success-row' : 'failed-row'
@@ -214,8 +192,12 @@ let systemStatusTimer = null
214192
215193
async function refreshSystemStatus() {
216194
try {
217-
const systemData = await getSystemStatus()
195+
const [systemData, connectionData] = await Promise.all([
196+
getSystemStatus(),
197+
getConnectionStatus()
198+
])
218199
systemStatus.value = systemData
200+
connectionStatus.value = connectionData
219201
updateOverview(systemData)
220202
} catch (e) {
221203
console.error('Failed to refresh system status:', e.message)
@@ -224,7 +206,7 @@ async function refreshSystemStatus() {
224206
225207
function startSystemStatusAutoRefresh() {
226208
if (systemStatusTimer) clearInterval(systemStatusTimer)
227-
systemStatusTimer = setInterval(refreshSystemStatus, 1000)
209+
systemStatusTimer = setInterval(refreshSystemStatus, 5000)
228210
}
229211
230212
function stopSystemStatusAutoRefresh() {

0 commit comments

Comments
 (0)