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