版本更新
This commit is contained in:
parent
eadb5d5471
commit
1ea4bd7559
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
*.exe
|
||||
release/*.tar
|
||||
release/*.tar
|
||||
.vscode/
|
||||
44
common/feishu.go
Normal file
44
common/feishu.go
Normal file
@ -0,0 +1,44 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func SendFeishuMsg(msg string) error {
|
||||
// 创建请求体
|
||||
payload := map[string]interface{}{
|
||||
"msg_type": "text",
|
||||
"content": map[string]string{
|
||||
"text": msg,
|
||||
},
|
||||
}
|
||||
payloadBytes, err := json.Marshal(payload)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 创建HTTP请求
|
||||
req, err := http.NewRequest("POST", GetFeishuUrl(), bytes.NewBuffer(payloadBytes))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
// 发送请求
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// 检查响应状态码
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return fmt.Errorf("failed to send message, status code: %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
package model
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@ -25,9 +25,15 @@ type MysqlConfig struct {
|
||||
Database string `yaml:"database"`
|
||||
}
|
||||
|
||||
type SystemConfig struct {
|
||||
NMap bool `yaml:"nmap"` // 是否开启端口扫描
|
||||
FeishUrl string `yaml:"feishu_url"` // 飞书机器人url
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Servers []SshConfig `yaml:"servers"`
|
||||
Mysqls []MysqlConfig `yaml:"mysqls"`
|
||||
System SystemConfig `yaml:"system"`
|
||||
}
|
||||
|
||||
var config *Config
|
||||
@ -73,3 +79,11 @@ func GetMysqlConfig(name string) (*MysqlConfig, error) {
|
||||
func GetWsConfig(name string) (*SshConfig, error) {
|
||||
return GetServerConfig("ws")
|
||||
}
|
||||
|
||||
func GetFeishuUrl() string {
|
||||
return config.System.FeishUrl
|
||||
}
|
||||
|
||||
func GetNMap() bool {
|
||||
return config.System.NMap
|
||||
}
|
||||
@ -1,10 +1,13 @@
|
||||
system:
|
||||
nmap: false
|
||||
feishu_url: 'https://open.feishu.cn/open-apis/bot/v2/hook/70e24a79-b019-434a-b4d1-4592bbf7c311'
|
||||
mysqls:
|
||||
- host: '127.0.0.1'
|
||||
name: 'merge_pet_test'
|
||||
port: 3306
|
||||
user: 'root'
|
||||
password: 'Z4rf7eZZe500dxa'
|
||||
database: 'pet_home_1'
|
||||
database: 'pet_home_%d'
|
||||
idleTimeout: Infinity
|
||||
- host: '127.0.0.1'
|
||||
name: 'merge_pet_sdk'
|
||||
@ -13,12 +16,19 @@ mysqls:
|
||||
password: 'Z4rf7eZZe500dxa'
|
||||
database: 'Merge_Pet_sdk'
|
||||
idleTimeout: Infinity
|
||||
- host: '127.0.0.1'
|
||||
name: 'merge_pet_london'
|
||||
port: 3306
|
||||
user: 'root'
|
||||
password: 'Z4rf7eZZe500dxa'
|
||||
database: 'merge_pet_london_%d'
|
||||
idleTimeout: Infinity
|
||||
- host: '127.0.0.1'
|
||||
name: 'merge_pet_online'
|
||||
port: 3306
|
||||
user: 'root'
|
||||
password: 'Xijing1!'
|
||||
database: 'merge_pet_1'
|
||||
database: 'merge_pet_%d'
|
||||
idleTimeout: Infinity
|
||||
- host: 'rm-f8zd2030feam53n43.mysql.rds.aliyuncs.com'
|
||||
name: 'log'
|
||||
@ -39,6 +49,11 @@ servers:
|
||||
port: 22
|
||||
username: 'root'
|
||||
password: 'ByWayStudios01!'
|
||||
- name: 'london'
|
||||
host: '8.208.47.208'
|
||||
port: 22
|
||||
username: 'root'
|
||||
password: '3/Qr-g]ljJ&9@bM&'
|
||||
- name: 'log'
|
||||
host: '8.155.14.94'
|
||||
port: 22
|
||||
|
||||
29
controller/mail.go
Normal file
29
controller/mail.go
Normal file
@ -0,0 +1,29 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"backend/model"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func SendMail(c *gin.Context) {
|
||||
Mail := model.Mail{}
|
||||
c.BindJSON(&Mail)
|
||||
err := Mail.SendMail()
|
||||
if err != nil {
|
||||
failed(c, err.Error())
|
||||
return
|
||||
}
|
||||
success(c, nil)
|
||||
}
|
||||
|
||||
func MailList(c *gin.Context) {
|
||||
Mail := model.Mail{}
|
||||
c.BindJSON(&Mail)
|
||||
MailList, err := Mail.MailList()
|
||||
if err != nil {
|
||||
failed(c, err.Error())
|
||||
return
|
||||
}
|
||||
success(c, MailList)
|
||||
}
|
||||
115
controller/server.go
Normal file
115
controller/server.go
Normal file
@ -0,0 +1,115 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"backend/common"
|
||||
"backend/model"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func AppList(c *gin.Context) {
|
||||
Server := model.Server{}
|
||||
AppList, err := Server.AppList()
|
||||
if err != nil {
|
||||
failed(c, err.Error())
|
||||
return
|
||||
}
|
||||
success(c, AppList)
|
||||
}
|
||||
|
||||
func ServerList(c *gin.Context) {
|
||||
Server := model.Server{}
|
||||
c.BindJSON(&Server)
|
||||
ServerList, err := Server.ServerList()
|
||||
if err != nil {
|
||||
failed(c, err.Error())
|
||||
return
|
||||
}
|
||||
success(c, ServerList)
|
||||
}
|
||||
|
||||
func AddServer(c *gin.Context) {
|
||||
Server := model.Server{}
|
||||
c.BindJSON(&Server)
|
||||
err := Server.AddServer()
|
||||
if err != nil {
|
||||
failed(c, err.Error())
|
||||
return
|
||||
}
|
||||
success(c, nil)
|
||||
}
|
||||
|
||||
func UpdateApp(c *gin.Context) {
|
||||
Server := model.Server{}
|
||||
c.BindJSON(&Server)
|
||||
msg, err := Server.UpdateApp()
|
||||
if err != nil {
|
||||
failed(c, err.Error())
|
||||
return
|
||||
}
|
||||
success(c, map[string]string{"msg": msg})
|
||||
}
|
||||
|
||||
func UpdateAppFeishu(c *gin.Context) {
|
||||
Server := model.Server{}
|
||||
c.BindJSON(&Server)
|
||||
go Server.UpdateAppFeishu()
|
||||
success(c, map[string]string{"msg": "have send feishu"})
|
||||
}
|
||||
|
||||
func RestartServer(c *gin.Context) {
|
||||
Server := model.Server{}
|
||||
c.BindJSON(&Server)
|
||||
msg, err := Server.RestartServer()
|
||||
if err != nil {
|
||||
failed(c, err.Error())
|
||||
return
|
||||
}
|
||||
success(c, map[string]string{"msg": msg})
|
||||
}
|
||||
|
||||
func ReloadServer(c *gin.Context) {
|
||||
Server := model.Server{}
|
||||
c.BindJSON(&Server)
|
||||
msg, err := Server.ReloadServer()
|
||||
if err != nil {
|
||||
failed(c, err.Error())
|
||||
return
|
||||
}
|
||||
success(c, map[string]string{"msg": msg})
|
||||
}
|
||||
|
||||
func AppPortNmap() {
|
||||
NMapEnable := common.GetNMap()
|
||||
if !NMapEnable {
|
||||
return
|
||||
}
|
||||
for {
|
||||
Server := model.Server{}
|
||||
AppList, err := Server.AppList()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, app := range AppList {
|
||||
Server.AppId = app.AppId
|
||||
ServerList, err := Server.ServerList()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
App, err := model.GetAppConfig(app.AppId)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
for _, server := range ServerList {
|
||||
err := model.PortMap(App.WsHost, fmt.Sprintf("%d", server.ServerId+App.WsPort))
|
||||
if err != nil {
|
||||
common.SendFeishuMsg(fmt.Sprintf("App: %s, Server: %s, 端口扫描异常 failed: %v", App.AppName, server.ServerName, err))
|
||||
}
|
||||
}
|
||||
}
|
||||
time.Sleep(5 * time.Minute)
|
||||
}
|
||||
|
||||
}
|
||||
22
controller/statistics.go
Normal file
22
controller/statistics.go
Normal file
@ -0,0 +1,22 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"backend/model"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func StatisticsLevel(c *gin.Context) {
|
||||
statistics := model.Statistics{}
|
||||
err := c.BindJSON(&statistics)
|
||||
if err != nil {
|
||||
failed(c, err.Error())
|
||||
return
|
||||
}
|
||||
res, err := statistics.StatisticsLevel()
|
||||
if err != nil {
|
||||
failed(c, err.Error())
|
||||
return
|
||||
}
|
||||
success(c, res)
|
||||
}
|
||||
@ -23,6 +23,7 @@ func UserInfo(c *gin.Context) {
|
||||
func UserList(c *gin.Context) {
|
||||
var request struct {
|
||||
Id int `json:"Id"`
|
||||
ServerId int `json:"ServerId"`
|
||||
PageSize int `json:"pageSize"`
|
||||
CurrentPage int `json:"currentPage"`
|
||||
}
|
||||
@ -32,7 +33,7 @@ func UserList(c *gin.Context) {
|
||||
failed(c, err.Error())
|
||||
return
|
||||
}
|
||||
user, total, err := model.GetUserList(request.Id, request.PageSize, request.CurrentPage)
|
||||
user, total, err := model.GetUserList(request.Id, request.ServerId, request.PageSize, request.CurrentPage)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
failed(c, err.Error())
|
||||
|
||||
1
go.mod
1
go.mod
@ -14,6 +14,7 @@ require (
|
||||
|
||||
require (
|
||||
filippo.io/edwards25519 v1.1.0 // indirect
|
||||
github.com/Ullaakut/nmap v2.0.2+incompatible // indirect
|
||||
github.com/bytedance/sonic v1.11.6 // indirect
|
||||
github.com/bytedance/sonic/loader v0.1.1 // indirect
|
||||
github.com/cloudwego/base64x v0.1.4 // indirect
|
||||
|
||||
2
go.sum
2
go.sum
@ -1,5 +1,7 @@
|
||||
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||
github.com/Ullaakut/nmap v2.0.2+incompatible h1:edw45QpSQBQ2B/Hqfg86Bt5rrK79tp/fAcqIHyNSdQs=
|
||||
github.com/Ullaakut/nmap v2.0.2+incompatible/go.mod h1:fkC066hwfcoKwlI7DS2ARTggSVtBTZYCjVH1TzuTMaQ=
|
||||
github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0=
|
||||
github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=
|
||||
github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=
|
||||
|
||||
26
main.go
26
main.go
@ -13,15 +13,33 @@ func main() {
|
||||
|
||||
api := r.Group("/api")
|
||||
{
|
||||
api.GET("/user/info", controller.UserInfo)
|
||||
api.POST("/auth/login", controller.Login)
|
||||
api.POST("/user/list", controller.UserList)
|
||||
api.GET("/auth/codes", controller.Codes)
|
||||
|
||||
api.POST("/log/user", controller.UserDetail)
|
||||
api.POST("/log/asset", controller.Asset)
|
||||
api.POST("/log/event", controller.Event)
|
||||
api.POST("/log/order", controller.Order)
|
||||
api.GET("/auth/codes", controller.Codes)
|
||||
}
|
||||
|
||||
api.POST("/user/list", controller.UserList)
|
||||
api.GET("/user/info", controller.UserInfo)
|
||||
|
||||
api.POST("/server/list", controller.AppList)
|
||||
api.POST("/server/serverList", controller.ServerList)
|
||||
api.POST("/server/addServer", controller.AddServer)
|
||||
|
||||
api.POST("/server/updateApp", controller.UpdateApp)
|
||||
api.POST("/server/updateAppFeishu", controller.UpdateAppFeishu)
|
||||
api.POST("/server/restart", controller.RestartServer)
|
||||
api.POST("/server/reload", controller.ReloadServer)
|
||||
|
||||
api.POST("/statistics/level", controller.StatisticsLevel)
|
||||
|
||||
// 邮件
|
||||
api.POST("/mail/send", controller.SendMail)
|
||||
api.POST("/mail/list", controller.MailList)
|
||||
}
|
||||
go controller.AppPortNmap()
|
||||
r.Run(":5320") // 在 0.0.0.0:5320 上监听并服务
|
||||
|
||||
}
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"backend/common"
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
"github.com/go-sql-driver/mysql"
|
||||
"github.com/jmoiron/sqlx"
|
||||
@ -17,12 +19,12 @@ func init() {
|
||||
MysqlList = make(map[string]*sqlx.DB)
|
||||
}
|
||||
|
||||
func connectToMySQLViaSSH(ServerName, MysqlName string) (*sqlx.DB, error) {
|
||||
SshConfig, err := GetServerConfig(ServerName)
|
||||
func connectToMySQLViaSSH(ServerName, MysqlName string, ServerId int) (*sqlx.DB, error) {
|
||||
SshConfig, err := common.GetServerConfig(ServerName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get SSH config: %v", err)
|
||||
}
|
||||
MysqlConfig, err := GetMysqlConfig(MysqlName)
|
||||
MysqlConfig, err := common.GetMysqlConfig(MysqlName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get MySQL config: %v", err)
|
||||
}
|
||||
@ -52,9 +54,14 @@ func connectToMySQLViaSSH(ServerName, MysqlName string) (*sqlx.DB, error) {
|
||||
mysql.RegisterDialContext("mysql+tcp", func(ctx context.Context, addr string) (net.Conn, error) {
|
||||
return mysqlConn, nil
|
||||
})
|
||||
|
||||
var Database string
|
||||
if strings.Contains(MysqlConfig.Database, "%") {
|
||||
Database = fmt.Sprintf(MysqlConfig.Database, ServerId)
|
||||
} else {
|
||||
Database = MysqlConfig.Database
|
||||
}
|
||||
// 连接到 MySQL 数据库
|
||||
dsn := fmt.Sprintf("%s:%s@mysql+tcp(%s:%d)/%s", MysqlConfig.Username, MysqlConfig.Password, MysqlConfig.Host, MysqlConfig.Port, MysqlConfig.Database)
|
||||
dsn := fmt.Sprintf("%s:%s@mysql+tcp(%s:%d)/%s", MysqlConfig.Username, MysqlConfig.Password, MysqlConfig.Host, MysqlConfig.Port, Database)
|
||||
db, err := sqlx.Open("mysql", dsn)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to open MySQL: %v", err)
|
||||
@ -64,11 +71,11 @@ func connectToMySQLViaSSH(ServerName, MysqlName string) (*sqlx.DB, error) {
|
||||
}
|
||||
|
||||
func connectToTopicMySQLViaSSH(ServerName, MysqlName, Topic string) (*sqlx.DB, error) {
|
||||
SshConfig, err := GetServerConfig(ServerName)
|
||||
SshConfig, err := common.GetServerConfig(ServerName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get SSH config: %v", err)
|
||||
}
|
||||
MysqlConfig, err := GetMysqlConfig(MysqlName)
|
||||
MysqlConfig, err := common.GetMysqlConfig(MysqlName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get MySQL config: %v", err)
|
||||
}
|
||||
@ -109,12 +116,30 @@ func connectToTopicMySQLViaSSH(ServerName, MysqlName, Topic string) (*sqlx.DB, e
|
||||
return db, nil
|
||||
}
|
||||
|
||||
func GetMysqlDB(Server, Mysql string) *sqlx.DB {
|
||||
key := fmt.Sprintf("%s_%s", Server, Mysql)
|
||||
func GetMysqlDB(Server, Mysql string, ServerId int) *sqlx.DB {
|
||||
key := fmt.Sprintf("%s_%s_%d", Server, Mysql, ServerId)
|
||||
if db, ok := MysqlList[key]; ok {
|
||||
return db
|
||||
if err := db.Ping(); err == nil {
|
||||
return db
|
||||
}
|
||||
}
|
||||
Db, err := connectToMySQLViaSSH(Server, Mysql)
|
||||
Db, err := connectToMySQLViaSSH(Server, Mysql, ServerId)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
MysqlList[key] = Db
|
||||
return Db
|
||||
}
|
||||
|
||||
func GetGameDB() *sqlx.DB {
|
||||
Server, Mysql := "log", "log"
|
||||
key := fmt.Sprintf("%s_%s_game", Server, Mysql)
|
||||
if db, ok := MysqlList[key]; ok {
|
||||
if err := db.Ping(); err == nil {
|
||||
return db
|
||||
}
|
||||
}
|
||||
Db, err := connectToTopicMySQLViaSSH(Server, Mysql, "game")
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
@ -124,9 +149,11 @@ func GetMysqlDB(Server, Mysql string) *sqlx.DB {
|
||||
|
||||
func GetTopicDB(Topic string) *sqlx.DB {
|
||||
Server, Mysql := "log", "log"
|
||||
key := fmt.Sprintf("%s_%s_topic", Server, Mysql)
|
||||
key := fmt.Sprintf("%s_%s_%s", Server, Mysql, Topic)
|
||||
if db, ok := MysqlList[key]; ok {
|
||||
return db
|
||||
if err := db.Ping(); err == nil {
|
||||
return db
|
||||
}
|
||||
}
|
||||
Db, err := connectToTopicMySQLViaSSH(Server, Mysql, Topic)
|
||||
if err != nil {
|
||||
@ -137,7 +164,7 @@ func GetTopicDB(Topic string) *sqlx.DB {
|
||||
}
|
||||
|
||||
func GetAppConfig(AppId int) (*AppStruct, error) {
|
||||
Db := GetMysqlDB("log", "log")
|
||||
Db := GetMysqlDB("log", "log", 0)
|
||||
var app AppStruct
|
||||
err := Db.Get(&app, "SELECT * FROM app WHERE `AppId` = ?", AppId)
|
||||
if err != nil {
|
||||
|
||||
53
model/Statistics.go
Normal file
53
model/Statistics.go
Normal file
@ -0,0 +1,53 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
)
|
||||
|
||||
type Statistics struct {
|
||||
AppId int `json:"AppId"`
|
||||
ServerList []int `json:"ServerList"`
|
||||
}
|
||||
|
||||
func (s *Statistics) StatisticsLevel() (interface{}, error) {
|
||||
AppConfig, err := GetAppConfig(s.AppId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res := make([]map[string]interface{}, 0)
|
||||
res1 := make(map[int]int)
|
||||
type dbres struct {
|
||||
Sum int `db:"sum"`
|
||||
Level int `db:"level"`
|
||||
}
|
||||
for _, v := range s.ServerList {
|
||||
Db := GetMysqlDB(AppConfig.ServerName, AppConfig.MysqlName, v)
|
||||
if Db == nil {
|
||||
return nil, fmt.Errorf("failed to get mysql database")
|
||||
}
|
||||
var result []dbres
|
||||
err = Db.Select(&result, "select count(*) as sum , `level` from t_player_baseinfo group by `level`")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get level count: %v", err)
|
||||
}
|
||||
for r := range result {
|
||||
res1[result[r].Level] += result[r].Sum
|
||||
}
|
||||
}
|
||||
keys := make([]int, 0, len(res1))
|
||||
for k := range res1 {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Ints(keys)
|
||||
for _, k := range keys {
|
||||
res = append(res, map[string]interface{}{
|
||||
"Level": k,
|
||||
"Sum": res1[k],
|
||||
})
|
||||
}
|
||||
return map[string]interface{}{
|
||||
"data": res,
|
||||
"total": len(res),
|
||||
}, nil
|
||||
}
|
||||
@ -10,6 +10,7 @@ type AppStruct struct {
|
||||
Topic string `db:"Topic"`
|
||||
Update int `db:"Update"`
|
||||
AppId int `db:"AppId"`
|
||||
Path string `db:"Path"`
|
||||
}
|
||||
|
||||
type User struct {
|
||||
|
||||
@ -3,20 +3,15 @@ package model
|
||||
import (
|
||||
"backend/msg"
|
||||
util "backend/uitl"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/websocket"
|
||||
)
|
||||
|
||||
func GetUserList(AppId, PageSize, CurrentPage int) ([]*User, int, error) {
|
||||
func GetUserList(AppId, ServerId, PageSize, CurrentPage int) ([]*User, int, error) {
|
||||
App, err := GetAppConfig(AppId)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
db := GetMysqlDB(App.ServerName, App.MysqlName)
|
||||
db := GetMysqlDB(App.ServerName, App.MysqlName, ServerId)
|
||||
if db == nil {
|
||||
return nil, 0, fmt.Errorf("failed to get MySQL database")
|
||||
}
|
||||
@ -31,7 +26,7 @@ func GetUserList(AppId, PageSize, CurrentPage int) ([]*User, int, error) {
|
||||
return nil, 0, fmt.Errorf("failed to get user count: %v", err)
|
||||
}
|
||||
for _, user := range users {
|
||||
if user.LogoutTime == 0 {
|
||||
if user.LoginTime > user.LogoutTime {
|
||||
user.Online = "在线"
|
||||
} else {
|
||||
user.Online = "离线"
|
||||
@ -46,45 +41,15 @@ func UserDetail(Uid int) (map[string]interface{}, error) {
|
||||
}
|
||||
AppId := Uid / 100000000
|
||||
ServerId := Uid % 100000000 / 100000
|
||||
App, err := GetAppConfig(AppId)
|
||||
ws, err := getWebsocket(AppId, ServerId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
Server, err := GetServerConfig(App.ServerName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
origin := "http://localhost/"
|
||||
url := fmt.Sprintf("ws://%s:%d/", Server.Host, App.WsPort+ServerId)
|
||||
config, err := websocket.NewConfig(url, origin)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create websocket config: %v", err)
|
||||
}
|
||||
config.Dialer = &net.Dialer{
|
||||
Timeout: 5 * time.Second,
|
||||
}
|
||||
|
||||
ws, err := websocket.DialConfig(config)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to connect to websocket: %v", err)
|
||||
return nil, fmt.Errorf("failed to get websocket: %v", err)
|
||||
}
|
||||
defer ws.Close()
|
||||
|
||||
reqBuf := util.PackMsg(req)
|
||||
_, err = ws.Write(reqBuf)
|
||||
r, err := util.SendAdminMsg(ws, req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to write to websocket: %v", err)
|
||||
return nil, fmt.Errorf("failed to send admin message: %v", err)
|
||||
}
|
||||
|
||||
readbuf := make([]byte, 512)
|
||||
n, err := ws.Read(readbuf)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read from websocket: %v", err)
|
||||
}
|
||||
resBuf, _ := util.UnpackMsg(readbuf, n)
|
||||
fmt.Println(string(resBuf))
|
||||
r := make(map[string]interface{})
|
||||
json.Unmarshal(resBuf, &r)
|
||||
return r, nil
|
||||
}
|
||||
|
||||
32
model/log.go
32
model/log.go
@ -7,9 +7,11 @@ import (
|
||||
)
|
||||
|
||||
type Log struct {
|
||||
Uid int `json:"Id"`
|
||||
PageSize int `json:"PageSize"`
|
||||
CurrentPage int `json:"CurrentPage"`
|
||||
Uid int `json:"Id"`
|
||||
PageSize int `json:"PageSize"`
|
||||
CurrentPage int `json:"CurrentPage"`
|
||||
AppId int `json:"AppId"`
|
||||
EventParam string `json:"Event"`
|
||||
}
|
||||
|
||||
type ResAsset struct {
|
||||
@ -30,6 +32,8 @@ type ResOrder struct {
|
||||
type Order struct {
|
||||
Id int `db:"id"`
|
||||
Uid int `db:"Uid"`
|
||||
AppId int `db:"AppId"`
|
||||
ServerId int `db:"ServerId"`
|
||||
OrderId string `db:"OrderId"`
|
||||
Price float64 `db:"Price"`
|
||||
PayChannelOrderId string `db:"PayChannelOrderId"`
|
||||
@ -53,6 +57,8 @@ type ResAssetDetail struct {
|
||||
type Event struct {
|
||||
Id int `db:"id"`
|
||||
Uid int `db:"Uid"`
|
||||
AppId int `db:"AppId"`
|
||||
ServerId int `db:"ServerId"`
|
||||
Event string `db:"Event"`
|
||||
Label string
|
||||
Param string `db:"Param"`
|
||||
@ -112,14 +118,18 @@ func (m *Log) Event() (*ResEvent, error) {
|
||||
return nil, fmt.Errorf("failed to get mysql database")
|
||||
}
|
||||
assets := []*Event{}
|
||||
err = Db.Select(&assets, "SELECT * FROM log_event WHERE Uid = ? and `Event` != 'asset_change' ORDER BY Timestamp DESC LIMIT ?, ?", m.Uid, (m.CurrentPage-1)*m.PageSize, m.PageSize)
|
||||
if m.EventParam != "" {
|
||||
err = Db.Select(&assets, "SELECT * FROM log_event WHERE Uid = ? and `Event` = ? ORDER BY Timestamp DESC LIMIT ?, ?", m.Uid, m.EventParam, (m.CurrentPage-1)*m.PageSize, m.PageSize)
|
||||
} else {
|
||||
err = Db.Select(&assets, "SELECT * FROM log_event WHERE Uid = ? and `Event` != 'asset_change' ORDER BY Timestamp DESC LIMIT ?, ?", m.Uid, (m.CurrentPage-1)*m.PageSize, m.PageSize)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get asset list: %v", err)
|
||||
return nil, fmt.Errorf("failed to get event list: %v", err)
|
||||
}
|
||||
var total int
|
||||
err = Db.QueryRow("SELECT COUNT(*) FROM log_event WHERE Uid = ? and `Event` != 'asset_change'", m.Uid).Scan(&total)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get asset count: %v", err)
|
||||
return nil, fmt.Errorf("failed to get event count: %v", err)
|
||||
}
|
||||
for _, asset := range assets {
|
||||
asset.Label = asset.Event
|
||||
@ -131,8 +141,7 @@ func (m *Log) Event() (*ResEvent, error) {
|
||||
}
|
||||
|
||||
func (m *Log) Order() (*ResOrder, error) {
|
||||
AppId, _ := util.ParseUid(m.Uid)
|
||||
AppConfig, err := GetAppConfig(AppId)
|
||||
AppConfig, err := GetAppConfig(m.AppId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -141,7 +150,12 @@ func (m *Log) Order() (*ResOrder, error) {
|
||||
return nil, fmt.Errorf("failed to get mysql database")
|
||||
}
|
||||
assets := []*Order{}
|
||||
err = Db.Select(&assets, "SELECT * FROM log_order WHERE Uid = ? ORDER BY Timestamp DESC LIMIT ?, ?", m.Uid, (m.CurrentPage-1)*m.PageSize, m.PageSize)
|
||||
if m.Uid == 0 {
|
||||
err = Db.Select(&assets, "SELECT * FROM log_order ORDER BY Timestamp DESC LIMIT ?, ?", (m.CurrentPage-1)*m.PageSize, m.PageSize)
|
||||
} else {
|
||||
err = Db.Select(&assets, "SELECT * FROM log_order WHERE Uid = ? ORDER BY Timestamp DESC LIMIT ?, ?", m.Uid, (m.CurrentPage-1)*m.PageSize, m.PageSize)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get asset list: %v", err)
|
||||
}
|
||||
|
||||
76
model/mail.go
Normal file
76
model/mail.go
Normal file
@ -0,0 +1,76 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"backend/msg"
|
||||
util "backend/uitl"
|
||||
"fmt"
|
||||
"log"
|
||||
)
|
||||
|
||||
type Mail struct {
|
||||
AppId int `json:"AppId"`
|
||||
ServerId int `json:"ServerId"`
|
||||
PageSize int `json:"PageSize"`
|
||||
CurrentPage int `json:"CurrentPage"`
|
||||
|
||||
MailId int `json:"mail_id" db:"mail_id"`
|
||||
Title string `json:"title" db:"title"`
|
||||
Content string `json:"content" db:"content"`
|
||||
StartTime int64 `json:"start_time" db:"start_time"`
|
||||
EndTime int64 `json:"end_time" db:"end_time"`
|
||||
Items string `json:"items" db:"items"`
|
||||
RegisterTime int64 `json:"register_time" db:"register_time"`
|
||||
MailType int `json:"mail_type" db:"mail_type"`
|
||||
ToUids string `json:"to_uids" db:"to_uids"`
|
||||
CreateTime int64 `json:"create_time" db:"create_time"`
|
||||
}
|
||||
|
||||
type Result struct {
|
||||
Data interface{} `json:"data"`
|
||||
Result int `json:"result"`
|
||||
}
|
||||
|
||||
func (m *Mail) MailList() (*Result, error) {
|
||||
// do something
|
||||
AppCfg, err := GetAppConfig(m.AppId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
Db := GetMysqlDB(AppCfg.ServerName, AppCfg.MysqlName, m.ServerId)
|
||||
var mail []*Mail
|
||||
err = Db.Select(&mail, "SELECT `mail_id`, `title`, `content`, `start_time`, `end_time`, `items`, `register_time`, `mail_type`, `to_uids`, `create_time` FROM system_mail_info")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to scan rows: %v", err)
|
||||
}
|
||||
return &Result{
|
||||
Data: mail,
|
||||
Result: 0,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m *Mail) SendMail() error {
|
||||
AppCfg, err := GetAppConfig(m.AppId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
Db := GetMysqlDB(AppCfg.ServerName, AppCfg.MysqlName, m.ServerId)
|
||||
_, err = Db.Exec("INSERT INTO system_mail_info (`title`, `content`, `start_time`, `end_time`, `items`, `register_time`, `mail_type`, `to_uids`, `create_time`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", m.Title, m.Content, m.StartTime, m.EndTime, m.Items, m.RegisterTime, m.MailType, m.ToUids, m.CreateTime)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to insert mail: %v", err)
|
||||
}
|
||||
go func() {
|
||||
ws, err := getWebsocket(m.AppId, m.ServerId)
|
||||
if err != nil {
|
||||
log.Printf("failed to get websocket: %v", err)
|
||||
}
|
||||
defer ws.Close()
|
||||
|
||||
req := &msg.ReqReloadServerMail{}
|
||||
_, err = util.SendAdminMsg(ws, req)
|
||||
if err != nil {
|
||||
log.Printf("failed to send admin message: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
return nil
|
||||
}
|
||||
238
model/server.go
Normal file
238
model/server.go
Normal file
@ -0,0 +1,238 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"backend/common"
|
||||
"backend/msg"
|
||||
util "backend/uitl"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/Ullaakut/nmap"
|
||||
)
|
||||
|
||||
const (
|
||||
DEVOPS_SERVER = "log"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
AppId int `json:"AppId"`
|
||||
ServerId int `json:"ServerId"`
|
||||
ServerName string `json:"ServerName"`
|
||||
Status int `json:"Status"`
|
||||
OpenServerTime int `json:"OpenServerTime"`
|
||||
Type int `json:"Type"`
|
||||
}
|
||||
|
||||
type App struct {
|
||||
AppId int `json:"AppId" db:"AppId"`
|
||||
AppName string `json:"AppName" db:"AppName"`
|
||||
Update int `json:"Update" db:"Update"`
|
||||
}
|
||||
|
||||
type ServerInfo struct {
|
||||
AppId int `json:"AppId" db:"AppId"`
|
||||
ServerId int `json:"ServerId" db:"ServerId"`
|
||||
ServerName string `json:"ServerName" db:"ServerName"`
|
||||
Status int `json:"Status" db:"Status"`
|
||||
CreateTime int `json:"CreateTime" db:"CreateTime"`
|
||||
OpenServerTime int `json:"OpenServerTime" db:"OpenServerTime"`
|
||||
StartTime int64 `json:"StartTime"`
|
||||
PlayerNum int `json:"PlayerNum"`
|
||||
}
|
||||
|
||||
func (s *Server) AppList() ([]*App, error) {
|
||||
Db := GetGameDB()
|
||||
var app []*App
|
||||
err := Db.Select(&app, "SELECT `AppId`, `AppName`, `Update` FROM app")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to scan rows: %v", err)
|
||||
}
|
||||
return app, nil
|
||||
}
|
||||
|
||||
func (s *Server) ServerList() ([]*ServerInfo, error) {
|
||||
Db := GetGameDB()
|
||||
var server []*ServerInfo
|
||||
err := Db.Select(&server, "SELECT `AppId`, `ServerId`, `ServerName`, `Status`, `CreateTime`, `OpenServerTime` FROM server where AppId = ?", s.AppId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to scan rows: %v", err)
|
||||
}
|
||||
if s.Type == 1 {
|
||||
return server, nil
|
||||
}
|
||||
for _, v := range server {
|
||||
ws, err := getWebsocket(v.AppId, v.ServerId)
|
||||
if err != nil {
|
||||
v.Status = 0
|
||||
continue
|
||||
}
|
||||
req := &msg.ReqServerInfo{}
|
||||
reqBuf := util.PackMsg(req)
|
||||
_, err = ws.Write(reqBuf)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
readbuf := make([]byte, 4096)
|
||||
n, err := ws.Read(readbuf)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
resBuf, _ := util.UnpackMsg(readbuf, n)
|
||||
// fmt.Println(string(resBuf))
|
||||
r := make(map[string]interface{})
|
||||
json.Unmarshal(resBuf, &r)
|
||||
if r["StartTime"] != nil {
|
||||
v.StartTime = int64(r["StartTime"].(float64))
|
||||
}
|
||||
if r["PlayerNum"] != nil {
|
||||
v.PlayerNum = int(r["PlayerNum"].(float64))
|
||||
}
|
||||
v.Status = 1
|
||||
ws.Close()
|
||||
}
|
||||
|
||||
return server, nil
|
||||
}
|
||||
|
||||
func (s *Server) AddServer() error {
|
||||
Db := GetGameDB()
|
||||
_, err := Db.Exec("INSERT INTO server (`AppId`, `ServerId`, `ServerName`, `Status`, `CreateTime`, `OpenServerTime`) VALUES (?, ?, ?, ?, ?, ?)",
|
||||
s.AppId, s.ServerId, s.ServerName, s.Status, util.Now(), s.OpenServerTime)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to insert: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Server) UpdateApp() (string, error) {
|
||||
AppConfig, err := GetAppConfig(s.AppId)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
ServerConfig, err := common.GetServerConfig(DEVOPS_SERVER)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
SshClient, err := NewSshClient(ServerConfig)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
_, err = SshClient.RunCommand("cd /data/devops && git pull")
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to git pull: %v", err)
|
||||
}
|
||||
cmd := fmt.Sprintf("ansible-playbook /data/devops/playbook/%s.yml -i /data/devops/playbook/hosts", AppConfig.AppName)
|
||||
output, err := SshClient.RunCommand(cmd)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
DB := GetGameDB()
|
||||
DB.Exec("UPDATE app SET `Update` = ? WHERE `AppId` = ?", util.Now(), s.AppId)
|
||||
common.SendFeishuMsg(fmt.Sprintf("AppName: %s, 执行文件更新完成", AppConfig.AppName))
|
||||
return output, nil
|
||||
}
|
||||
|
||||
func (s *Server) UpdateAppFeishu() (string, error) {
|
||||
AppConfig, err := GetAppConfig(s.AppId)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
ServerConfig, err := common.GetServerConfig(DEVOPS_SERVER)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
SshClient, err := NewSshClient(ServerConfig)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
_, err = SshClient.RunCommand("cd /data/devops && git pull")
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to git pull: %v", err)
|
||||
}
|
||||
cmd := fmt.Sprintf("ansible-playbook /data/devops/playbook/%s.yml -i /data/devops/playbook/hosts", AppConfig.AppName)
|
||||
output, err := SshClient.RunCommand(cmd)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
DB := GetGameDB()
|
||||
DB.Exec("UPDATE app SET `Update` = ? WHERE `AppId` = ?", util.Now(), s.AppId)
|
||||
common.SendFeishuMsg(fmt.Sprintf("AppName: %s, 执行文件更新完成", AppConfig.AppName))
|
||||
return output, nil
|
||||
}
|
||||
|
||||
func (s *Server) RestartServer() (string, error) {
|
||||
AppConfig, err := GetAppConfig(s.AppId)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
ServerConfig, err := common.GetServerConfig(AppConfig.ServerName)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
SshClient, err := NewSshClient(ServerConfig)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
cmd := fmt.Sprintf("%s/tool/tool restart node %d", AppConfig.Path, s.ServerId)
|
||||
output, err := SshClient.RunCommand(cmd)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
common.SendFeishuMsg(fmt.Sprintf("AppName: %s, ServerName: %s, 重启完成", AppConfig.AppName, s.ServerName))
|
||||
return output, nil
|
||||
}
|
||||
|
||||
func (s *Server) ReloadServer() (string, error) {
|
||||
AppConfig, err := GetAppConfig(s.AppId)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
ws, err := getWebsocket(s.AppId, s.ServerId)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to get websocket: %v", err)
|
||||
}
|
||||
defer ws.Close()
|
||||
req := &msg.ReqReload{}
|
||||
_, err = util.SendAdminMsg(ws, req)
|
||||
if err != nil {
|
||||
log.Printf("failed to send admin message: %v", err)
|
||||
}
|
||||
common.SendFeishuMsg(fmt.Sprintf("AppName: %s, ServerName: %s, 配置重载完成", AppConfig.AppName, s.ServerName))
|
||||
return "success", nil
|
||||
}
|
||||
|
||||
// 端口扫描
|
||||
func PortMap(Ip string, Port string) error {
|
||||
// 创建一个新的Nmap扫描器
|
||||
scanner, err := nmap.NewScanner(
|
||||
nmap.WithTargets(Ip), // 替换为你要扫描的目标IP地址
|
||||
nmap.WithPorts(Port), // 替换为你要扫描的端口
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 执行扫描
|
||||
result, warnings, err := scanner.Run()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 打印扫描结果
|
||||
for _, warning := range warnings {
|
||||
log.Printf("警告: %v", warning)
|
||||
}
|
||||
|
||||
for _, host := range result.Hosts {
|
||||
if len(host.Ports) == 0 || host.Status.State != "up" {
|
||||
return fmt.Errorf("主机不可达")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
45
model/ssh.go
Normal file
45
model/ssh.go
Normal file
@ -0,0 +1,45 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"backend/common"
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/crypto/ssh"
|
||||
)
|
||||
|
||||
type SshClient struct {
|
||||
client *ssh.Client
|
||||
}
|
||||
|
||||
func NewSshClient(config *common.SshConfig) (*SshClient, error) {
|
||||
sshconfig := &ssh.ClientConfig{
|
||||
User: config.Username,
|
||||
Auth: []ssh.AuthMethod{
|
||||
ssh.Password(config.Password),
|
||||
},
|
||||
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
|
||||
}
|
||||
|
||||
addr := fmt.Sprintf("%s:%d", config.Host, config.Port)
|
||||
client, err := ssh.Dial("tcp", addr, sshconfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &SshClient{client: client}, nil
|
||||
}
|
||||
|
||||
func (s *SshClient) RunCommand(cmd string) (string, error) {
|
||||
session, err := s.client.NewSession()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer session.Close()
|
||||
|
||||
output, err := session.CombinedOutput(cmd)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(output), nil
|
||||
}
|
||||
35
model/websocket.go
Normal file
35
model/websocket.go
Normal file
@ -0,0 +1,35 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"backend/common"
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/net/websocket"
|
||||
)
|
||||
|
||||
func getWebsocket(AppId, ServerId int) (*websocket.Conn, error) {
|
||||
App, err := GetAppConfig(AppId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
Server, err := common.GetServerConfig(App.ServerName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
origin := "http://localhost/"
|
||||
url := fmt.Sprintf("ws://%s:%d/", Server.Host, App.WsPort+ServerId)
|
||||
config, err := websocket.NewConfig(url, origin)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create websocket config: %v", err)
|
||||
}
|
||||
// config.Dialer = &net.Dialer{
|
||||
// Timeout: 5 * time.Second,
|
||||
// }
|
||||
|
||||
ws, err := websocket.DialConfig(config)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to connect to websocket: %v", err)
|
||||
}
|
||||
return ws, nil
|
||||
}
|
||||
7367
msg/Gameapi.pb.go
7367
msg/Gameapi.pb.go
File diff suppressed because it is too large
Load Diff
BIN
release/backend
BIN
release/backend
Binary file not shown.
@ -1,3 +1,6 @@
|
||||
system:
|
||||
nmap: true
|
||||
feishu_url: 'https://open.feishu.cn/open-apis/bot/v2/hook/70e24a79-b019-434a-b4d1-4592bbf7c311'
|
||||
mysqls:
|
||||
- host: '127.0.0.1'
|
||||
name: 'merge_pet_test'
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
cd /data/backend
|
||||
GOOS=linux GOARCH=amd64 go build -o /data/backend/release/backend main.go
|
||||
cd /data/admin_backend
|
||||
GOOS=linux GOARCH=amd64 go build -o /data/admin_backend/release/backend main.go
|
||||
|
||||
26
uitl/util.go
26
uitl/util.go
@ -2,9 +2,13 @@ package util
|
||||
|
||||
import (
|
||||
"backend/msg"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/websocket"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
@ -68,3 +72,25 @@ func Int(a interface{}) int {
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func Now() int64 {
|
||||
return time.Now().Unix()
|
||||
}
|
||||
|
||||
func SendAdminMsg(ws *websocket.Conn, req proto.Message) (map[string]interface{}, error) {
|
||||
reqBuf := PackMsg(req)
|
||||
_, err := ws.Write(reqBuf)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to write to websocket: %v", err)
|
||||
}
|
||||
|
||||
readbuf := make([]byte, 4096)
|
||||
n, err := ws.Read(readbuf)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read from websocket: %v", err)
|
||||
}
|
||||
resBuf, _ := UnpackMsg(readbuf, n)
|
||||
r := make(map[string]interface{})
|
||||
json.Unmarshal(resBuf, &r)
|
||||
return r, nil
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user