Merge remote-tracking branch 'origin/main' into multi-tenant
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# 项目信息
|
||||
framework:
|
||||
name: "OMC"
|
||||
version: "2.2408.1"
|
||||
version: "2.2409.3"
|
||||
|
||||
# 应用服务配置
|
||||
server:
|
||||
|
||||
96
src/framework/socket/tcp_client.go
Normal file
96
src/framework/socket/tcp_client.go
Normal file
@@ -0,0 +1,96 @@
|
||||
package socket
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ConnTCP 连接TCP客户端
|
||||
type ConnTCP struct {
|
||||
Addr string `json:"addr"` // 主机地址
|
||||
Port int64 `json:"port"` // 端口
|
||||
|
||||
DialTimeOut time.Duration `json:"dialTimeOut"` // 连接超时断开
|
||||
|
||||
Client *net.Conn `json:"client"`
|
||||
LastResult string `json:"lastResult"` // 记最后一次发送消息的结果
|
||||
}
|
||||
|
||||
// New 创建TCP客户端
|
||||
func (c *ConnTCP) New() (*ConnTCP, error) {
|
||||
// IPV6地址协议
|
||||
proto := "tcp"
|
||||
if strings.Contains(c.Addr, ":") {
|
||||
proto = "tcp6"
|
||||
c.Addr = fmt.Sprintf("[%s]", c.Addr)
|
||||
}
|
||||
address := fmt.Sprintf("%s:%d", c.Addr, c.Port)
|
||||
|
||||
// 默认等待5s
|
||||
if c.DialTimeOut == 0 {
|
||||
c.DialTimeOut = 5 * time.Second
|
||||
}
|
||||
|
||||
// 连接到服务端
|
||||
client, err := net.DialTimeout(proto, address, c.DialTimeOut)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c.Client = &client
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// Close 关闭当前TCP客户端
|
||||
func (c *ConnTCP) Close() {
|
||||
if c.Client != nil {
|
||||
(*c.Client).Close()
|
||||
}
|
||||
}
|
||||
|
||||
// Send 发送消息
|
||||
func (c *ConnTCP) Send(msg []byte, timer time.Duration) (string, error) {
|
||||
if c.Client == nil {
|
||||
return "", fmt.Errorf("tcp client not connected")
|
||||
}
|
||||
conn := *c.Client
|
||||
|
||||
// 写入信息
|
||||
if len(msg) > 0 {
|
||||
if _, err := conn.Write(msg); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
defer buf.Reset()
|
||||
|
||||
tmp := make([]byte, 1024)
|
||||
for {
|
||||
select {
|
||||
case <-time.After(timer):
|
||||
c.LastResult = buf.String()
|
||||
return c.LastResult, fmt.Errorf("timeout")
|
||||
default:
|
||||
// 读取命令消息
|
||||
n, err := conn.Read(tmp)
|
||||
if n == 0 || err != nil {
|
||||
tmp = nil
|
||||
break
|
||||
}
|
||||
|
||||
tmpStr := string(tmp[:n])
|
||||
buf.WriteString(tmpStr)
|
||||
|
||||
// 是否有终止符
|
||||
if strings.HasSuffix(tmpStr, ">") || strings.HasSuffix(tmpStr, "> ") || strings.HasSuffix(tmpStr, "# ") {
|
||||
tmp = nil
|
||||
c.LastResult = buf.String()
|
||||
return c.LastResult, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
83
src/framework/socket/tcp_server.go
Normal file
83
src/framework/socket/tcp_server.go
Normal file
@@ -0,0 +1,83 @@
|
||||
package socket
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/logger"
|
||||
)
|
||||
|
||||
// SocketTCP TCP服务端
|
||||
type SocketTCP struct {
|
||||
Addr string `json:"addr"` // 主机地址
|
||||
Port int64 `json:"port"` // 端口
|
||||
Listen *net.Listener `json:"listen"`
|
||||
StopChan chan struct{} `json:"stop"` // 停止信号
|
||||
}
|
||||
|
||||
// New 创建TCP服务端
|
||||
func (s *SocketTCP) New() (*SocketTCP, error) {
|
||||
// IPV6地址协议
|
||||
proto := "tcp"
|
||||
if strings.Contains(s.Addr, ":") {
|
||||
proto = "tcp6"
|
||||
s.Addr = fmt.Sprintf("[%s]", s.Addr)
|
||||
}
|
||||
address := fmt.Sprintf("%s:%d", s.Addr, s.Port)
|
||||
|
||||
ln, err := net.Listen(proto, address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s.Listen = &ln
|
||||
s.StopChan = make(chan struct{}, 1)
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// Close 关闭当前TCP服务端
|
||||
func (s *SocketTCP) Close() {
|
||||
if s.Listen != nil {
|
||||
s.StopChan <- struct{}{}
|
||||
(*s.Listen).Close()
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve 处理消息
|
||||
func (s *SocketTCP) Resolve(bufferSize int, callback func([]byte, int)) error {
|
||||
if s.Listen == nil {
|
||||
return fmt.Errorf("tcp service not created")
|
||||
}
|
||||
|
||||
ln := *s.Listen
|
||||
buffer := make([]byte, bufferSize)
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-s.StopChan:
|
||||
return fmt.Errorf("udp service stop")
|
||||
default:
|
||||
conn, err := ln.Accept()
|
||||
if err != nil {
|
||||
logger.Errorf("Error accepting connection: %v ", err)
|
||||
continue
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
// 读取数据
|
||||
n, err := conn.Read(buffer)
|
||||
if err != nil {
|
||||
fmt.Println("Error reading from TCP connection:", err)
|
||||
continue
|
||||
}
|
||||
|
||||
callback(buffer, n)
|
||||
|
||||
// 发送响应
|
||||
if _, err = conn.Write([]byte("tcp>")); err != nil {
|
||||
fmt.Println("Error sending response:", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
96
src/framework/socket/udp_client.go
Normal file
96
src/framework/socket/udp_client.go
Normal file
@@ -0,0 +1,96 @@
|
||||
package socket
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ConnUDP 连接UDP客户端
|
||||
type ConnUDP struct {
|
||||
Addr string `json:"addr"` // 主机地址
|
||||
Port int64 `json:"port"` // 端口
|
||||
|
||||
DialTimeOut time.Duration `json:"dialTimeOut"` // 连接超时断开
|
||||
|
||||
Client *net.Conn `json:"client"`
|
||||
LastResult string `json:"lastResult"` // 记最后一次发送消息的结果
|
||||
}
|
||||
|
||||
// New 创建UDP客户端
|
||||
func (c *ConnUDP) New() (*ConnUDP, error) {
|
||||
// IPV6地址协议
|
||||
proto := "udp"
|
||||
if strings.Contains(c.Addr, ":") {
|
||||
proto = "udp6"
|
||||
c.Addr = fmt.Sprintf("[%s]", c.Addr)
|
||||
}
|
||||
address := fmt.Sprintf("%s:%d", c.Addr, c.Port)
|
||||
|
||||
// 默认等待5s
|
||||
if c.DialTimeOut == 0 {
|
||||
c.DialTimeOut = 5 * time.Second
|
||||
}
|
||||
|
||||
// 连接到服务端
|
||||
client, err := net.DialTimeout(proto, address, c.DialTimeOut)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c.Client = &client
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// Close 关闭当前UDP客户端
|
||||
func (c *ConnUDP) Close() {
|
||||
if c.Client != nil {
|
||||
(*c.Client).Close()
|
||||
}
|
||||
}
|
||||
|
||||
// Send 发送消息
|
||||
func (c *ConnUDP) Send(msg []byte, ms int) (string, error) {
|
||||
if c.Client == nil {
|
||||
return "", fmt.Errorf("udp client not connected")
|
||||
}
|
||||
conn := *c.Client
|
||||
|
||||
// 写入信息
|
||||
if len(msg) > 0 {
|
||||
if _, err := conn.Write(msg); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
defer buf.Reset()
|
||||
|
||||
tmp := make([]byte, 1024)
|
||||
for {
|
||||
select {
|
||||
case <-time.After(time.Duration(time.Duration(ms).Milliseconds())):
|
||||
c.LastResult = buf.String()
|
||||
return c.LastResult, fmt.Errorf("timeout")
|
||||
default:
|
||||
// 读取命令消息
|
||||
n, err := conn.Read(tmp)
|
||||
if n == 0 || err != nil {
|
||||
tmp = nil
|
||||
break
|
||||
}
|
||||
|
||||
tmpStr := string(tmp[:n])
|
||||
buf.WriteString(tmpStr)
|
||||
|
||||
// 是否有终止符
|
||||
if strings.HasSuffix(tmpStr, ">") || strings.HasSuffix(tmpStr, "> ") || strings.HasSuffix(tmpStr, "# ") {
|
||||
tmp = nil
|
||||
c.LastResult = buf.String()
|
||||
return c.LastResult, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
80
src/framework/socket/udp_server.go
Normal file
80
src/framework/socket/udp_server.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package socket
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// SocketUDP UDP服务端
|
||||
type SocketUDP struct {
|
||||
Addr string `json:"addr"` // 主机地址
|
||||
Port int64 `json:"port"` // 端口
|
||||
Conn *net.UDPConn `json:"conn"`
|
||||
StopChan chan struct{} `json:"stop"` // 停止信号
|
||||
}
|
||||
|
||||
// New 创建UDP服务端
|
||||
func (s *SocketUDP) New() (*SocketUDP, error) {
|
||||
// IPV6地址协议
|
||||
proto := "udp"
|
||||
if strings.Contains(s.Addr, ":") {
|
||||
proto = "udp6"
|
||||
s.Addr = fmt.Sprintf("[%s]", s.Addr)
|
||||
}
|
||||
address := fmt.Sprintf("%s:%d", s.Addr, s.Port)
|
||||
|
||||
// 解析 UDP 地址
|
||||
udpAddr, err := net.ResolveUDPAddr(proto, address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 监听 UDP 地址
|
||||
conn, err := net.ListenUDP("udp", udpAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s.Conn = conn
|
||||
s.StopChan = make(chan struct{}, 1)
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// CloseService 关闭当前UDP服务端
|
||||
func (s *SocketUDP) Close() {
|
||||
if s.Conn != nil {
|
||||
s.StopChan <- struct{}{}
|
||||
(*s.Conn).Close()
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve 处理消息
|
||||
func (s *SocketUDP) Resolve(bufferSize int, callback func([]byte, int)) error {
|
||||
if s.Conn == nil {
|
||||
return fmt.Errorf("udp service not created")
|
||||
}
|
||||
|
||||
buffer := make([]byte, bufferSize)
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-s.StopChan:
|
||||
return fmt.Errorf("udp service stop")
|
||||
default:
|
||||
// 读取数据
|
||||
n, addr, err := s.Conn.ReadFromUDP(buffer)
|
||||
if err != nil {
|
||||
fmt.Println("Error reading from UDP connection:", err)
|
||||
continue
|
||||
}
|
||||
|
||||
callback(buffer, n)
|
||||
|
||||
// 发送响应
|
||||
if _, err = s.Conn.WriteToUDP([]byte("udp>"), addr); err != nil {
|
||||
fmt.Println("Error sending response:", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,11 +50,6 @@ func (c *ConnTelnet) NewClient() (*ConnTelnet, error) {
|
||||
// fmt.Fprintln(client, c.User)
|
||||
// fmt.Fprintln(client, c.Password)
|
||||
|
||||
// 调整窗口大小 (120 列 x 128 行)
|
||||
// 需要确保接收方理解并正确处理发送窗口大小设置命令
|
||||
client.Write([]byte{255, 251, 31})
|
||||
client.Write([]byte{255, 250, 31, byte(120 >> 8), byte(120 & 0xFF), byte(128 >> 8), byte(128 & 0xFF), 255, 240})
|
||||
|
||||
c.Client = &client
|
||||
|
||||
// 排空连接登录的信息
|
||||
@@ -116,6 +111,6 @@ func (c *ConnTelnet) NewClientSession(cols, rows int) (*TelnetClientSession, err
|
||||
s := &TelnetClientSession{
|
||||
Client: *c.Client,
|
||||
}
|
||||
s.WindowChange(cols, rows)
|
||||
// s.WindowChange(cols, rows)
|
||||
return s, nil
|
||||
}
|
||||
@@ -47,11 +47,11 @@ func (s *TelnetClientSession) Read() []byte {
|
||||
buf := make([]byte, 1024)
|
||||
// 设置读取超时时间为100毫秒
|
||||
s.Client.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
|
||||
_, err := s.Client.Read(buf)
|
||||
n, err := s.Client.Read(buf)
|
||||
if err != nil {
|
||||
return []byte{}
|
||||
}
|
||||
return buf
|
||||
return buf[:n]
|
||||
}
|
||||
|
||||
// CombinedOutput 发送命令带结果返回
|
||||
@@ -87,7 +87,7 @@ func Post(url string, data url.Values, headers map[string]string) ([]byte, error
|
||||
// PostJSON 发送 POST 请求,并将请求体序列化为 JSON 格式
|
||||
func PostJSON(url string, data any, headers map[string]string) ([]byte, error) {
|
||||
client := &http.Client{
|
||||
Timeout: 3 * time.Second, // 超时时间
|
||||
Timeout: 10 * time.Second, // 超时时间
|
||||
}
|
||||
|
||||
jsonData, err := json.Marshal(data)
|
||||
@@ -180,7 +180,7 @@ func PostUploadFile(url string, params map[string]string, file *os.File) ([]byte
|
||||
// PutJSON 发送 PUT 请求,并将请求体序列化为 JSON 格式
|
||||
func PutJSON(url string, data any, headers map[string]string) ([]byte, error) {
|
||||
client := &http.Client{
|
||||
Timeout: 3 * time.Second, // 超时时间
|
||||
Timeout: 10 * time.Second, // 超时时间
|
||||
}
|
||||
|
||||
jsonData, err := json.Marshal(data)
|
||||
|
||||
@@ -17,46 +17,53 @@ import (
|
||||
)
|
||||
|
||||
// Number 解析数值型
|
||||
func Number(str any) int64 {
|
||||
switch str := str.(type) {
|
||||
func Number(value any) int64 {
|
||||
switch v := value.(type) {
|
||||
case string:
|
||||
if str == "" {
|
||||
if v == "" {
|
||||
return 0
|
||||
}
|
||||
num, err := strconv.ParseInt(str, 10, 64)
|
||||
num, err := strconv.ParseInt(v, 10, 64)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return num
|
||||
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
|
||||
return reflect.ValueOf(str).Int()
|
||||
case int, int8, int16, int32, int64:
|
||||
return reflect.ValueOf(v).Int()
|
||||
case uint, uint8, uint16, uint32, uint64:
|
||||
return int64(reflect.ValueOf(v).Uint())
|
||||
case float32, float64:
|
||||
return int64(reflect.ValueOf(str).Float())
|
||||
return int64(reflect.ValueOf(v).Float())
|
||||
case bool:
|
||||
if v {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
// Boolean 解析布尔型
|
||||
func Boolean(str any) bool {
|
||||
switch str := str.(type) {
|
||||
func Boolean(value any) bool {
|
||||
switch v := value.(type) {
|
||||
case string:
|
||||
if str == "" || str == "false" || str == "0" {
|
||||
b, err := strconv.ParseBool(v)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
// 尝试将字符串解析为数字
|
||||
if num, err := strconv.ParseFloat(str, 64); err == nil {
|
||||
return num != 0
|
||||
}
|
||||
return true
|
||||
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
|
||||
num := reflect.ValueOf(str).Int()
|
||||
return b
|
||||
case int, int8, int16, int32, int64:
|
||||
num := reflect.ValueOf(v).Int()
|
||||
return num != 0
|
||||
case uint, uint8, uint16, uint32, uint64:
|
||||
num := int64(reflect.ValueOf(v).Uint())
|
||||
return num != 0
|
||||
case float32, float64:
|
||||
num := reflect.ValueOf(str).Float()
|
||||
num := reflect.ValueOf(v).Float()
|
||||
return num != 0
|
||||
case bool:
|
||||
return str
|
||||
return v
|
||||
default:
|
||||
return false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user