添加了日志文件,优化了程序入口

This commit is contained in:
Sheyiyuan 2024-11-29 11:43:39 +08:00
parent 02b7f596c0
commit dc5d0141e6
7 changed files with 369 additions and 182 deletions

1
.idea/vcs.xml generated
View File

@ -2,6 +2,5 @@
<project version="4"> <project version="4">
<component name="VcsDirectoryMappings"> <component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" /> <mapping directory="$PROJECT_DIR$" vcs="Git" />
<mapping directory="$PROJECT_DIR$/main" vcs="Git" />
</component> </component>
</project> </project>

21
doc.go Normal file
View File

@ -0,0 +1,21 @@
package main
const (
helpDoc string = `
欢迎使用ProjectWIND!
使用方法:
ProjectWIND [options]
Options:
-h, --help 显示帮助文档
-v, --version 显示版本信息
-r, --run 运行wind
-s, 创建Linux service
-i, --init 初始化配置文件
Website:
github.com/Sheyiyuan/ProjectWIND
For Developers:
-w,
`
version string = `WIND v0.1.0`
)

197
main.go
View File

@ -1,175 +1,46 @@
package main package main
import ( import (
"ProjectWIND/protocol"
"ProjectWIND/typed"
"encoding/json"
"errors"
"fmt" "fmt"
"io"
"log"
"os" "os"
) )
func init() {
// 初始化日志记录器
log.SetFlags(log.Ldate | log.Ltime)
log.SetPrefix("[WIND] ")
// 检查并创建必要的目录和文件
if _, err := os.Stat("./data/"); os.IsNotExist(err) {
// 如果不存在,则创建该文件夹
err := os.Mkdir("./data/", 0755)
if err != nil {
log.Fatal(err)
}
}
// 检查./data/文件夹中是否存在config.json文件
if _, err := os.Stat("./data/config.json"); os.IsNotExist(err) {
// 如果不存在,则创建该文件
file, err := os.Create("./data/config.json")
if err != nil {
log.Fatal(err)
}
defer func(file *os.File) {
err := file.Close()
if err != nil {
log.Fatal(err)
}
}(file)
}
// 检查并更新配置文件
err := checkAndUpdateConfig("./data/config.json")
if err != nil {
log.Fatal(err)
}
// 检查./data/文件夹中是否存在app/文件夹
if _, err := os.Stat("./data/app/"); os.IsNotExist(err) {
// 如果不存在,则创建该文件夹
err := os.Mkdir("./data/app/", 0755)
if err != nil {
log.Fatal(err)
}
}
// 检查./data/文件夹中是否存在database/文件夹
if _, err := os.Stat("./data/database/"); os.IsNotExist(err) {
// 如果不存在,则创建该文件夹
err := os.Mkdir("./data/database/", 0755)
if err != nil {
log.Fatal(err)
}
}
// 检查./data/文件夹中是否存在log/文件夹
if _, err := os.Stat("./data/log/"); os.IsNotExist(err) {
// 如果不存在,则创建该文件夹
err := os.Mkdir("./data/log/", 0755)
if err != nil {
log.Fatal(err)
}
}
}
func main() { func main() {
//读取参数 //如果没有参数则启动WebUI
if len(os.Args) == 1 || os.Args[0] == "help" || os.Args[0] == "-h" || os.Args[0] == "--help" { if len(os.Args) <= 1 {
fmt.Println(`Usage: input command "start"or"-s" to start the server.`) startWebUI()
return return
} }
command := os.Args[1] cmdArgs := os.Args[1:]
switch command { if cmdArgs[0] == "-h" || cmdArgs[0] == "--help" {
case "start": fmt.Printf("%v\n", helpDoc)
case "-s": return
{
log.Println("Starting ProjectWIND...")
// 启动 WebSocket 处理程序
log.Println("Starting WebSocket handler...")
_, err := protocol.WebSocketHandler()
if err != nil {
// 如果发生错误,记录错误并退出程序
log.Fatal(err)
}
return
}
default:
{
fmt.Println("Invalid command.")
return
}
} }
} if cmdArgs[0] == "-r" || cmdArgs[0] == "--run" {
func checkAndUpdateConfig(configPath string) error { // 启动服务
var config typed.ConfigInfo startWebUI()
// 定义默认配置 return
var defaultConfig typed.ConfigInfo }
defaultConfig.CoreName = "windCore" if cmdArgs[0] == "-i" || cmdArgs[0] == "--init" {
defaultConfig.WebUIPort = 3211 // 初始化项目
defaultConfig.ProtocolAddr = make(map[string]string) initCore()
defaultConfig.ServiceName = "wind" return
// 读取配置文件 }
file, err := os.Open(configPath) if cmdArgs[0] == "-v" || cmdArgs[0] == "--version" {
if err != nil { // 显示版本信息
return err fmt.Printf(`%v\n`, version)
} return
defer func(file *os.File) { }
err := file.Close() if cmdArgs[0] == "-s" || cmdArgs[0] == "--service" {
if err != nil { // 注册Linux服务并启动
log.Printf("Failed to close config file: %v", err) registerService()
} return
}(file) }
if cmdArgs[0] == "-p" || cmdArgs[0] == "--protocol" {
// 解码JSON配置 // 连接到协议端
decoder := json.NewDecoder(file) startProtocol()
err = decoder.Decode(&config) return
if err != nil { }
if !errors.Is(err, io.EOF) { fmt.Println("Invalid command.")
return err return
}
}
// 检查并更新配置
if config.ProtocolAddr == nil {
config.ProtocolAddr = defaultConfig.ProtocolAddr
}
if config.WebUIPort == 0 {
config.WebUIPort = defaultConfig.WebUIPort
}
if config.CoreName == "" {
config.CoreName = defaultConfig.CoreName
}
if config.ServiceName == "" {
config.ServiceName = defaultConfig.ServiceName
}
if config.PasswordHash == "" {
config.PasswordHash = ""
}
formattedJSON, err := json.MarshalIndent(config, "", " ")
if err != nil {
fmt.Println("Error formatting JSON:", err)
return err
}
// 将格式化后的JSON字符串写入文件
file, err = os.Create("./data/config.json")
if err != nil {
fmt.Println("Error creating file:", err)
return err
}
defer func(file *os.File) {
err := file.Close()
if err != nil {
log.Printf("Failed to close config file: %v", err)
}
}(file)
_, err = file.Write(formattedJSON)
if err != nil {
fmt.Println("Error writing to file:", err)
return err
}
return nil
} }

View File

@ -31,7 +31,7 @@ func SendMessage(messageType string, message string, targetId int64, autoEscape
return false, err return false, err
} }
// 发送消息 // 发送消息
_, err = wsSendMessage(messageJson) err = wsSendMessage(messageJson)
if err != nil { if err != nil {
return false, err return false, err
} }

View File

@ -9,14 +9,16 @@ import (
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
) )
const ( var gProtocolAddr string
severURL = "your_server_url"
)
func WebSocketHandler() (*websocket.Conn, error) { // WebSocketHandler 接收WebSocket连接处的消息并处理
u, err := url.Parse(severURL) func WebSocketHandler(protocolAddr string) (*websocket.Conn, error) {
// 保存全局变量
gProtocolAddr = protocolAddr
// 解析连接URL
u, err := url.Parse(protocolAddr)
if err != nil { if err != nil {
log.Println("Parse URL error:", err) log.Println("[ERROR] Parse URL error:", err)
return nil, err return nil, err
} }
@ -47,6 +49,7 @@ func WebSocketHandler() (*websocket.Conn, error) {
return conn, nil return conn, nil
} }
// processMessage 处理接收到的消息
func processMessage(messageType int, message []byte) { func processMessage(messageType int, message []byte) {
if messageType != websocket.TextMessage { if messageType != websocket.TextMessage {
log.Println("[INFO] Invalid message type:", messageType) log.Println("[INFO] Invalid message type:", messageType)
@ -95,17 +98,17 @@ func processMessage(messageType int, message []byte) {
} }
// wsSendMessage 向WebSocket服务器发送消息并返回发送状态 // wsSendMessage 向WebSocket服务器发送消息并返回发送状态
func wsSendMessage(message []byte) (bool, error) { func wsSendMessage(message []byte) error {
// 解析连接URL // 解析连接URL
u, err := url.Parse(fmt.Sprintf("%v/api", severURL)) u, err := url.Parse(fmt.Sprintf("%v/api", gProtocolAddr))
if err != nil { if err != nil {
return false, fmt.Errorf("无效的URL: %v", err) return fmt.Errorf("无效的URL: %v", err)
} }
// 建立连接 // 建立连接
conn, _, err := websocket.DefaultDialer.Dial(u.String(), nil) conn, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
if err != nil { if err != nil {
return false, fmt.Errorf("连接失败: %v", err) return fmt.Errorf("连接失败: %v", err)
} }
defer func(conn *websocket.Conn) { defer func(conn *websocket.Conn) {
err := conn.Close() err := conn.Close()
@ -117,8 +120,8 @@ func wsSendMessage(message []byte) (bool, error) {
// 发送消息 // 发送消息
err = conn.WriteMessage(websocket.TextMessage, message) err = conn.WriteMessage(websocket.TextMessage, message)
if err != nil { if err != nil {
return false, fmt.Errorf("发送消息失败: %v", err) return fmt.Errorf("发送消息失败: %v", err)
} }
return true, nil return nil
} }

View File

@ -1,11 +1,11 @@
package typed package typed
type ConfigInfo struct { type ConfigInfo struct {
CoreName string `json:"core_name"` CoreName string `json:"core_name"`
ProtocolAddr map[string]string `json:"protocol_addr"` ProtocolAddr string `json:"protocol_addr"`
WebUIPort uint16 `json:"webui_port"` WebUIPort uint16 `json:"webui_port"`
PasswordHash string `json:"password_hash"` PasswordHash string `json:"password_hash"`
ServiceName string `json:"service_name"` ServiceName string `json:"service_name"`
} }
type MessageEventInfo struct { type MessageEventInfo struct {

293
utils.go Normal file
View File

@ -0,0 +1,293 @@
package main
import (
"ProjectWIND/protocol"
"ProjectWIND/typed"
"encoding/json"
"errors"
"fmt"
"io"
"log"
"os"
"time"
)
func initCore() string {
// 初始化日志记录器
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
log.SetPrefix("[WIND] ")
log.Println("[INFO] 正在初始化WIND配置文件...")
err := checkAndUpdateConfig("./data/config.json")
if err != nil {
log.Fatal(err)
}
// 创建日志文件
logFile := fmt.Sprintf("./data/log/WIND_CORE_%s.log", time.Now().Format("20060102150405"))
_, err = os.Stat(logFile)
if os.IsNotExist(err) {
file, err := os.Create(logFile)
if err != nil {
log.Fatalf("[ERROR] Failed to create log file: %v", err)
}
defer func(file *os.File) {
err := file.Close()
if err != nil {
log.Printf("[ERROR] Failed to close log file: %v", err)
}
}(file)
}
file, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if err != nil {
log.Fatalf("[ERROR] Failed to create log file: %v", err)
}
defer func(file *os.File) {
err := file.Close()
if err != nil {
log.Printf("[ERROR] Failed to close log file: %v", err)
}
}(file)
// 设置日志输出到文件
log.SetOutput(io.MultiWriter(os.Stdout, file))
log.Println("[INFO] WIND配置文件初始化完成")
return logFile
}
func checkAndUpdateConfig(configPath string) error {
// 检查并创建必要的目录和文件
if _, err := os.Stat("./data/"); os.IsNotExist(err) {
// 如果不存在,则创建该文件夹
err := os.Mkdir("./data/", 0755)
if err != nil {
log.Fatal(err)
}
}
// 检查./data/文件夹中是否存在config.json文件
if _, err := os.Stat("./data/config.json"); os.IsNotExist(err) {
// 如果不存在,则创建该文件
file, err := os.Create("./data/config.json")
if err != nil {
log.Fatal(err)
}
defer func(file *os.File) {
err := file.Close()
if err != nil {
log.Fatal(err)
}
}(file)
}
// 检查并更新配置文件
var config typed.ConfigInfo
// 定义默认配置
var defaultConfig typed.ConfigInfo
defaultConfig.CoreName = "windCore"
defaultConfig.WebUIPort = 3211
defaultConfig.ProtocolAddr = ""
defaultConfig.ServiceName = "wind"
// 读取配置文件
file, err := os.Open(configPath)
if err != nil {
return err
}
defer func(file *os.File) {
err := file.Close()
if err != nil {
log.Printf("[ERROR] Failed to close config file: %v", err)
}
}(file)
// 解码JSON配置
decoder := json.NewDecoder(file)
err = decoder.Decode(&config)
if err != nil {
if !errors.Is(err, io.EOF) {
return err
}
}
// 检查并更新配置
if config.ProtocolAddr == "" {
config.ProtocolAddr = defaultConfig.ProtocolAddr
}
if config.WebUIPort == 0 {
config.WebUIPort = defaultConfig.WebUIPort
}
if config.CoreName == "" {
config.CoreName = defaultConfig.CoreName
}
if config.ServiceName == "" {
config.ServiceName = defaultConfig.ServiceName
}
if config.PasswordHash == "" {
config.PasswordHash = ""
}
formattedJSON, err := json.MarshalIndent(config, "", " ")
if err != nil {
return err
}
// 将格式化后的JSON字符串写入文件
file, err = os.Create("./data/config.json")
if err != nil {
log.Println("Error creating file:", err)
return err
}
defer func(file *os.File) {
err := file.Close()
if err != nil {
log.Printf("Failed to close config file: %v", err)
}
}(file)
_, err = file.Write(formattedJSON)
if err != nil {
log.Println("[ERROR] Error writing to file:", err)
return err
}
// 检查./data/文件夹中是否存在app/文件夹
if _, err := os.Stat("./data/app/"); os.IsNotExist(err) {
// 如果不存在,则创建该文件夹
err := os.Mkdir("./data/app/", 0755)
if err != nil {
return err
}
}
// 检查./data/文件夹中是否存在images/文件夹
if _, err := os.Stat("./data/images/"); os.IsNotExist(err) {
// 如果不存在,则创建该文件夹
err := os.Mkdir("./data/images/", 0755)
if err != nil {
return err
}
}
// 检查./data/文件夹中是否存在database/文件夹
if _, err := os.Stat("./data/database/"); os.IsNotExist(err) {
// 如果不存在,则创建该文件夹
err := os.Mkdir("./data/database/", 0755)
if err != nil {
return err
}
}
// 检查./data/文件夹中是否存在log/文件夹
if _, err := os.Stat("./data/log/"); os.IsNotExist(err) {
// 如果不存在,则创建该文件夹
err := os.Mkdir("./data/log/", 0755)
if err != nil {
return err
}
}
return nil
}
func startWebUI() {
{
//初始化
logFile := initCore()
// 设置日志输出到文件
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
log.SetPrefix("[WIND] ")
// 打开日志文件
file, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if err != nil {
log.Fatalf("[ERROR] Failed to create log file: %v", err)
}
defer func(file *os.File) {
err := file.Close()
if err != nil {
log.Printf("[ERROR] Failed to close log file: %v", err)
}
}(file)
// 设置日志输出到文件
log.SetOutput(io.MultiWriter(os.Stdout, file))
log.Println("[INFO] 正在启动WIND核心服务...")
// 启动 WebSocket 处理程序
//TODO: 这里要添加webUI的启动代码
}
}
func registerService() {
//初始化
logFile := initCore()
// 设置日志输出到文件
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
log.SetPrefix("[WIND] ")
// 打开日志文件
file, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if err != nil {
log.Fatalf("[ERROR] Failed to create log file: %v", err)
}
defer func(file *os.File) {
err := file.Close()
if err != nil {
log.Printf("[ERROR] Failed to close log file: %v", err)
}
}(file)
// 设置日志输出到文件
log.SetOutput(io.MultiWriter(os.Stdout, file))
//TODO: 这里要添加注册服务的代码
}
func startProtocol() {
//初始化
logFile := initCore()
// 设置日志输出到文件
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
log.SetPrefix("[WIND] ")
// 打开日志文件
file, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if err != nil {
log.Fatalf("[ERROR] Failed to create log file: %v", err)
}
defer func(file *os.File) {
err := file.Close()
if err != nil {
log.Printf("[ERROR] Failed to close log file: %v", err)
}
}(file)
// 设置日志输出到文件
log.SetOutput(io.MultiWriter(os.Stdout, file))
//从配置文件中读取配置信息
log.Println("[INFO] 正在启动WIND协议服务...")
var config typed.ConfigInfo
file, err = os.Open("./data/config.json")
if err != nil {
log.Printf("[ERROR] Failed to open config file when linking to protocol: %v", err)
}
defer func(file *os.File) {
err := file.Close()
if err != nil {
log.Printf("[ERROR] Failed to close config file: %v", err)
}
}(file)
decoder := json.NewDecoder(file)
err = decoder.Decode(&config)
if err != nil {
log.Printf("[ERROR] Failed to decode config file when linking to protocol: %v", err)
}
//获取协议地址
protocolAddr := config.ProtocolAddr
//链接协议
// 启动 WebSocket 处理程序
log.Println("[INFO] 正在启动WebSocket链接程序...")
_, err = protocol.WebSocketHandler(protocolAddr)
if err != nil {
// 如果发生错误,记录错误并退出程序
log.Fatal(err)
}
return
}