pc_mqtt/client.go

133 lines
2.8 KiB
Go
Raw Permalink Normal View History

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