133 lines
2.8 KiB
Go
133 lines
2.8 KiB
Go
|
package main
|
|||
|
|
|||
|
import (
|
|||
|
"encoding/json"
|
|||
|
"fmt"
|
|||
|
"os"
|
|||
|
"os/exec"
|
|||
|
"runtime"
|
|||
|
"time"
|
|||
|
|
|||
|
mqtt "github.com/eclipse/paho.mqtt.golang"
|
|||
|
"github.com/joho/godotenv"
|
|||
|
"github.com/shirou/gopsutil/cpu"
|
|||
|
"github.com/shirou/gopsutil/mem"
|
|||
|
)
|
|||
|
|
|||
|
// PCInfo 定义 PC 使用信息的结构。
|
|||
|
type PCInfo struct {
|
|||
|
CPUUsage float64 `json:"cpu_usage"` // CPU
|
|||
|
MemUsage float64 `json:"mem_usage"` // Memory
|
|||
|
}
|
|||
|
|
|||
|
// Command 定义接收命令的结构。
|
|||
|
type Command struct {
|
|||
|
Action string `json:"action"` // Action 待执行
|
|||
|
}
|
|||
|
|
|||
|
// loadEnv 加载 .env 文件以读取环境变量。
|
|||
|
func loadEnv() {
|
|||
|
err := godotenv.Load(".env")
|
|||
|
if err != nil {
|
|||
|
fmt.Println("Error loading .env file")
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// getPCInfo 检索当前 PC 使用信息。
|
|||
|
func getPCInfo() (PCInfo, error) {
|
|||
|
cpuPercentages, err := cpu.Percent(0, false)
|
|||
|
if err != nil {
|
|||
|
return PCInfo{}, err
|
|||
|
}
|
|||
|
|
|||
|
memInfo, err := mem.VirtualMemory()
|
|||
|
if err != nil {
|
|||
|
return PCInfo{}, err
|
|||
|
}
|
|||
|
|
|||
|
// 保留2位小数
|
|||
|
return PCInfo{
|
|||
|
CPUUsage: float64(int(cpuPercentages[0]*100)) / 100,
|
|||
|
MemUsage: float64(int(memInfo.UsedPercent*100)) / 100,
|
|||
|
}, nil
|
|||
|
}
|
|||
|
|
|||
|
// onMessageReceived 处理从 MQTT 接收的消息。
|
|||
|
func onMessageReceived(client mqtt.Client, msg mqtt.Message) {
|
|||
|
var cmd Command
|
|||
|
err := json.Unmarshal(msg.Payload(), &cmd)
|
|||
|
if err != nil {
|
|||
|
fmt.Println("Error decoding JSON command:", err)
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
if cmd.Action == "shutdown" {
|
|||
|
fmt.Println("Shutdown command received. Shutting down...")
|
|||
|
executeShutdown()
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// executeShutdown 根据操作系统执行关机命令。
|
|||
|
func executeShutdown() {
|
|||
|
var cmd *exec.Cmd
|
|||
|
switch runtime.GOOS {
|
|||
|
case "windows":
|
|||
|
cmd = exec.Command("shutdown", "/s", "/t", "0")
|
|||
|
case "linux", "darwin":
|
|||
|
cmd = exec.Command("shutdown", "-h", "now")
|
|||
|
default:
|
|||
|
fmt.Println("Shutdown not supported on this OS")
|
|||
|
return
|
|||
|
}
|
|||
|
err := cmd.Run()
|
|||
|
if err != nil {
|
|||
|
fmt.Println("Failed to execute shutdown:", err)
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
func main() {
|
|||
|
loadEnv()
|
|||
|
|
|||
|
broker := os.Getenv("MQTT_BROKER")
|
|||
|
clientID := os.Getenv("MQTT_CLIENT_ID")
|
|||
|
topic := os.Getenv("MQTT_TOPIC")
|
|||
|
|
|||
|
opts := mqtt.NewClientOptions()
|
|||
|
opts.AddBroker(broker)
|
|||
|
opts.SetClientID(clientID)
|
|||
|
opts.SetDefaultPublishHandler(onMessageReceived)
|
|||
|
|
|||
|
client := mqtt.NewClient(opts)
|
|||
|
if token := client.Connect(); token.Wait() && token.Error() != nil {
|
|||
|
fmt.Println(token.Error())
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
// 订阅主题以接收命令
|
|||
|
client.Subscribe(topic, 0, nil)
|
|||
|
|
|||
|
for {
|
|||
|
pcInfo, err := getPCInfo()
|
|||
|
if err != nil {
|
|||
|
fmt.Println("Error getting PC info:", err)
|
|||
|
continue
|
|||
|
}
|
|||
|
|
|||
|
pcInfoJSON, err := json.Marshal(pcInfo)
|
|||
|
if err != nil {
|
|||
|
fmt.Println("Error encoding PC info to JSON:", err)
|
|||
|
continue
|
|||
|
}
|
|||
|
|
|||
|
token := client.Publish(topic, 0, false, pcInfoJSON)
|
|||
|
token.Wait()
|
|||
|
|
|||
|
fmt.Println("Message published:", string(pcInfoJSON))
|
|||
|
|
|||
|
time.Sleep(10 * time.Second) // 控制发送频率,例如每10秒发送一次
|
|||
|
}
|
|||
|
|
|||
|
// 完成后断开 MQTT 客户端连接
|
|||
|
// client.Disconnect(250)
|
|||
|
}
|