Browse Source

优化修改代码

niujiuru 2 tuần trước cách đây
mục cha
commit
d83cd69c93
3 tập tin đã thay đổi với 152 bổ sung53 xóa
  1. 8 2
      baseapp/app.go
  2. 1 0
      main.go
  3. 143 51
      utils/jsonrpc2/rpc.go

+ 8 - 2
baseapp/app.go

@@ -45,11 +45,11 @@ func SingleInstanceRun() { // 非阻塞单实例运行
 	}
 
 	ch := make(chan os.Signal, 1)
-	signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
+	signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM, syscall.SIGUSR1)
 	go func() {
 		for s := range ch {
 			switch s {
-			case syscall.SIGINT, syscall.SIGTERM:
+			case syscall.SIGINT, syscall.SIGTERM, syscall.SIGUSR1:
 				Logger.Infof("Received signal: %v", s)
 				mux.Close()
 				os.RemoveAll(lockFile)
@@ -70,3 +70,9 @@ func IsExit1() bool {
 func IsExit2() <-chan struct{} {
 	return exitCh
 }
+
+func SafeExit() { // 安全退出
+	pid := os.Getpid()
+	syscall.Kill(pid, syscall.SIGUSR1)
+	<-exitCh
+}

+ 1 - 0
main.go

@@ -57,6 +57,7 @@ end_p:
 
 	baseapp.Logger.Info("程序退出")
 	baseapp.ExitLogger() // 安全的关闭日志模块
+	baseapp.SafeExit()   // 安全的关闭退出程序
 }
 
 func help() {

+ 143 - 51
utils/jsonrpc2/rpc.go

@@ -5,99 +5,191 @@ package jsonrpc2
 
 import (
 	"encoding/json"
+	"errors"
 	"fmt"
 )
 
-type ErrorCode int
+type ErrCode int
 
 const (
-	ErrParse          ErrorCode = -32700 // 解析错误: "Parse error"
-	ErrInvalidRequest ErrorCode = -32600 // 无效请求: "Invalid request"
-	ErrMethodNotFound ErrorCode = -32601 // 无效方法: "Method not found"
-	ErrInvalidParams  ErrorCode = -32602 // 无效参数: "Invalid params"
-	ErrInternal       ErrorCode = -32603 // 内部错误: "Internal error"
+	ErrParse          ErrCode = -32700 // 解析错误: "Parse error"
+	ErrInvalidRequest ErrCode = -32600 // 无效请求: "Invalid request"
+	ErrMethodNotFound ErrCode = -32601 // 无效方法: "Method not found"
+	ErrInvalidParams  ErrCode = -32602 // 无效参数: "Invalid params"
+	ErrInternal       ErrCode = -32603 // 内部错误: "Internal error"
 )
 
-type Request struct {
-	JSONRPC string          `json:"jsonrpc"`          // 版本号, 固定: "2.0"
-	Method  string          `json:"method"`           // 调用方法, 执行函数名
-	Params  json.RawMessage `json:"params,omitempty"` // 请求参数, 可选可为空
-	ID      int             `json:"id"`               // 请求ID, 用于标识请求
-}
-
 type Error struct {
-	Code    ErrorCode `json:"code"`    // 错误码
-	Message string    `json:"message"` // 错误信息
+	Code    ErrCode `json:"code"`    //// 错误码
+	Message string  `json:"message"` //// 错误信息
 }
 
 func (e Error) Error() string {
 	return e.Message
 }
 
+type Request struct {
+	JSONRPC string          `json:"jsonrpc"`          // 版本号, 固定: "2.0"
+	Method  string          `json:"method"`           // 调用方法, 执行函数名
+	Params  json.RawMessage `json:"params,omitempty"` // 请求参数, 可选可为空
+	ID      *int            `json:"id,omitempty"`     // 请求ID, 用于标识请求
+}
+
 type Response struct {
 	JSONRPC string          `json:"jsonrpc"`          // 版本号, 固定: "2.0"
 	Result  json.RawMessage `json:"result,omitempty"` // 响应结果, 可选可为空
 	Error   *Error          `json:"error,omitempty"`  // 错误信息, 可选可为空
-	ID      int             `json:"id"`               // 应答ID, 响应匹配请求
+	ID      *int            `json:"id"`               // 应答ID, 响应匹配请求
 }
 
 // 解析请求数据
-func ParseRequest(jsonStr string) (*Request, error) {
+func ParseRequest(input any) (*Request, error) {
+	var raw []byte
+
+	switch v := input.(type) {
+	case nil:
+		return nil, errors.New("input is nil")
+	case string:
+		raw = []byte(v)
+	case []byte:
+		raw = v
+	default:
+		return nil, errors.New("unsupported input type: must be string or []byte")
+	}
+
 	var req Request
-	if err := json.Unmarshal([]byte(jsonStr), &req); err != nil {
-		return nil, err
+	if err := json.Unmarshal(raw, &req); err != nil {
+		return nil, fmt.Errorf("unmarshal request: %w", err)
 	}
+
 	return &req, nil
 }
 
-// 构建响应数据
-func BuildResult(id int, result any) (*Response, error) {
-	b, err := json.Marshal(result)
+// 编码JSON数据
+func marshalJSON(input any) (json.RawMessage, error) {
+	switch v := input.(type) {
+	case nil:
+		return nil, nil
+	case []byte:
+		return nil, errors.New("[]byte is not allowed: use json.RawMessage for raw JSON")
+	case json.RawMessage:
+		return v, nil
+	default:
+		b, err := json.Marshal(v)
+		if err != nil {
+			return nil, fmt.Errorf("marshal json: %w", err)
+		}
+		return json.RawMessage(b), nil
+	}
+}
+
+// 构建一个请求
+func BuildRequest(method string, params any, id int) (*Request, error) {
+	if method == "" {
+		return nil, errors.New("method must be non-empty")
+	}
+
+	raw, err := marshalJSON(params)
 	if err != nil {
 		return nil, err
 	}
-	return &Response{
+
+	req := &Request{
 		JSONRPC: "2.0",
-		Result:  b,
-		ID:      id,
-	}, nil
+		Method:  method,
+		ID:      &id,
+	}
+
+	if raw != nil { // 非空参数
+		req.Params = raw
+	}
+
+	return req, nil
 }
 
-// 构建错误响应
-func BuildError(id int, code ErrorCode, message string) *Response {
-	return &Response{
+// 构建一个通知
+func BuildNotification(method string, params any) (*Request, error) {
+	if method == "" {
+		return nil, errors.New("method must be non-empty")
+	}
+
+	raw, err := marshalJSON(params)
+	if err != nil {
+		return nil, err
+	}
+
+	req := &Request{
 		JSONRPC: "2.0",
-		Error: &Error{
-			Code:    code,
-			Message: message,
-		},
-		ID: id,
+		Method:  method,
 	}
-}
 
-// 构建解析错误
-func BuildParseError(id int) *Response {
-	return BuildError(id, ErrParse, "Parse error")
-}
+	if raw != nil { // 非空参数
+		req.Params = raw
+	}
 
-// 构建无效请求
-func BuildInvalidRequest(id int) *Response {
-	return BuildError(id, ErrInvalidRequest, "Invalid request")
+	return req, nil
 }
 
-// 构建无效方法
-func BuildMethodNotFound(id int) *Response {
-	return BuildError(id, ErrMethodNotFound, "Method not found")
+// 构建成功应答
+func BuildResult(req *Request, result any) (*Response, error) {
+	if req.ID == nil { // 通知类型, 不用应答
+		return nil, nil
+	}
+
+	raw, err := marshalJSON(result)
+	if err != nil {
+		return nil, err
+	}
+
+	if raw == nil {
+		raw = json.RawMessage("null")
+	}
+
+	return &Response{
+		JSONRPC: "2.0",
+		Result:  raw,
+		ID:      req.ID,
+	}, nil
 }
 
-// 构建无效参数
-func BuildInvalidParams(id int) *Response {
-	return BuildError(id, ErrInvalidParams, "Invalid params")
+// 构建错误应答
+func BuildError(req *Request, code ErrCode, message string) *Response {
+	if req.ID == nil { // 通知类型, 不用应答
+		return nil
+	}
+
+	wmsg := message
+
+	switch code {
+	case ErrParse:
+		wmsg = "解析错误"
+	case ErrInvalidRequest:
+		wmsg = "无效请求"
+	case ErrMethodNotFound:
+		wmsg = "无效调用"
+	case ErrInvalidParams:
+		wmsg = "无效参数"
+	case ErrInternal:
+		wmsg = "内部错误"
+	}
+
+	return &Response{
+		JSONRPC: "2.0",
+		Error: &Error{
+			Code:    code,
+			Message: wmsg,
+		},
+		ID: req.ID,
+	}
 }
 
-// 构建内部错误
-func BuildInternalError(id int) *Response {
-	return BuildError(id, ErrInternal, "Internal error")
+// 请求转字符串
+func (req *Request) String() (string, error) {
+	b, err := json.Marshal(req)
+	if err != nil {
+		return "", fmt.Errorf("marshal request: %w", err)
+	}
+	return string(b), nil
 }
 
 // 应答转字符串