Parcourir la source

优化文件传输

Cheng Jian il y a 2 ans
Parent
commit
dfd0fcd942
2 fichiers modifiés avec 47 ajouts et 24 suppressions
  1. 2 6
      rpcx-gateway/converter.go
  2. 45 18
      rpcx-gateway/gateway.go

+ 2 - 6
rpcx-gateway/converter.go

@@ -109,7 +109,7 @@ func HttpRequest2RpcxRequest(r *http.Request) (*protocol.Message, error) {
 	return req, nil
 }
 
-func MultipartRequest2RpcxRequest(r *http.Request) (map[string]string, *multipart.FileHeader, error) {
+func MultipartRequest2RpcxRequest(r *http.Request) (map[string]string, map[string][]*multipart.FileHeader, error) {
 	r.ParseMultipartForm(10 << 20) //10mb
 	form := r.MultipartForm
 	formValues := make(map[string]string)
@@ -133,10 +133,6 @@ func MultipartRequest2RpcxRequest(r *http.Request) (map[string]string, *multipar
 		formValues[k] = v[0]
 	}
 
-	file := form.File["file"][0]
-	formValues["fileName"] = file.Filename
-	formValues["fileSize"] = strconv.FormatInt(file.Size, 10)
-
 	sp := h.Get(XServicePath)
 	if sp != "" {
 		formValues["reqService"] = sp
@@ -152,7 +148,7 @@ func MultipartRequest2RpcxRequest(r *http.Request) (map[string]string, *multipar
 	}
 	formValues["authExclude"] = "false"
 
-	return formValues, form.File["file"][0], nil
+	return formValues, form.File, nil
 }
 
 func getRpcxHeader(r *http.Request, key string) string {

+ 45 - 18
rpcx-gateway/gateway.go

@@ -11,6 +11,7 @@ import (
 	"mime/multipart"
 	"net"
 	"net/http"
+	"strconv"
 	"strings"
 	"sync"
 	"sync/atomic"
@@ -178,25 +179,51 @@ func getRequestToken(r *http.Request) string {
 }
 
 // sendFile
-func sendFile(conn net.Conn, file *multipart.FileHeader) error {
-	// 只读打开文件
-	f, err := file.Open()
-	if err != nil {
-		return err
-	}
-	// 从本文件中,读数据,写给网络接收端。
-	buf := make([]byte, 1024)
-	for {
-		n, err := f.Read(buf)
-		if n == 0 {
-			log.Debug("发送文件完成")
-			return nil
+func sendFile(conn net.Conn, files map[string][]*multipart.FileHeader) error {
+	index := 0
+	for key, header := range files {
+		index++
+		file, _ := header[0].Open()
+		fileName := header[0].Filename
+		fileSize := header[0].Size
+		fileHeader := fmt.Sprintf("%s %s %v", key, fileName, fileSize)
+
+		// 发送文件名长度
+		length := strconv.Itoa(len(fileHeader))
+		conn.Write([]byte(PadLeft(length, 3, "0")))
+		// 发送文件名和文件长度给 接收端
+		conn.Write([]byte(fileHeader))
+
+		// 从本文件中,读数据,写给网络接收端。
+		buf := make([]byte, 1024)
+		for {
+			n, err := file.Read(buf)
+			if n == 0 {
+				log.Debug("发送文件完成")
+				break
+			}
+			// 写到网络socket中
+			_, err = conn.Write(buf[:n])
+			if err != nil {
+				log.Debug("conn.Write err:", err)
+				break
+			}
 		}
-		// 写到网络socket中
-		_, err = conn.Write(buf[:n])
-		if err != nil {
-			log.Debug("conn.Write err:", err)
-			return nil
+
+		if index == len(files) {
+			conn.Write([]byte("2"))
+		} else {
+			conn.Write([]byte("1"))
 		}
 	}
+	return nil
+}
+
+func PadLeft(s string, length int, padding string) string {
+	sLen := len(s)
+	if sLen >= length {
+		return s
+	}
+	padCount := length - sLen
+	return strings.Repeat(padding, padCount) + s
 }