Cách gửi % tiến độ từ server lên client khi làm progress bar

87 lượt xem

profile picture

Ẩn danh

Ngày 2 Tháng 06

Dự án em đang dùng react cho frontend, java cho backend. Em định làm progress bar khi upload file excel, vậy phải gửi % tiến độ từ server lên client thế nào vậy ạ? Việc upload file thì được thực hiện ở backend, vậy có cách nào để trên frontend bắt được % tiến độ không ạ? Em cũng không chắc phải gg thế nào, mọi người giúp em với.

Đánh giá câu hỏi ngay!

Hãy ấn Up Vote với những câu hỏi cụ thể và chi tiết

Hãy ấn Down Vote với những câu hỏi chưa rõ ràng Careerly sẽ nhắc người hỏi chỉnh sửa lại.

2 câu trả lời

BEST

Ảnh đại diện của Kien Dinh

Chào bạn, mình hiểu là bạn đang muốn ra lệnh từ front end cho upload file từ Backend tới 1 service bên thứ ba khác, sau đó client sẽ phải bắt được progress đúng không? Mô hình: Client <==> Backend ==upload==>> Storage Trong trường hợp đó, bạn có thể code Java phía backend để đếm từng bytes được gửi đi tới server. Xem code demo bên dưới. ⚠️ Lưu ý, bạn nên batching số byte được gửi đi theo một tỷ lệ nào đó (ví dụ 2-5% mới update 1 lần), nhằm tránh việc gửi response về cho client quá nhiều, làm giảm hiệu năng. 📺 Vậy dùng cơ chế gì để trả response về cho client một cách liên tục? Bạn có thể tham khảo các cơ chế sau: - Long polling hoặc short polling. - Socket để giữ kết nối real time (tốn tài nguyên và phức tạp hơn). - Grpc server streaming (cần nhúng grpc web vào client, gây nặng client). Kinh nghiệm cá nhân: Thông thường đa số các progress bar đều không theo dõi realtime trừ phi cực kì cần thiết. Thay vào đó có một cách implement mình thấy thường được dùng, chính là bạn ước lượng số thời gian cần được dùng để upload file, sau đó cho progress bar chạy hết 90%, và 10% còn lại sẽ được hoàn thành khi file được upload xong. Tham khảo: https://stackoverflow.com/questions/254719/file-upload-with-java-with-progress-bar

1import java.io.FilterOutputStream;
2import java.io.IOException;
3import java.io.OutputStream;
4import org.apache.commons.httpclient.methods.RequestEntity;
5
6public class CountingMultipartRequestEntity implements RequestEntity {
7    private final RequestEntity delegate;
8
9    private final ProgressListener listener;
10
11    public CountingMultipartRequestEntity(final RequestEntity entity,
12            final ProgressListener listener) {
13        super();
14        this.delegate = entity;
15        this.listener = listener;
16    }
17
18    public long getContentLength() {
19        return this.delegate.getContentLength();
20    }
21
22    public String getContentType() {
23        return this.delegate.getContentType();
24    }
25
26    public boolean isRepeatable() {
27        return this.delegate.isRepeatable();
28    }
29
30    public void writeRequest(final OutputStream out) throws IOException {
31        this.delegate.writeRequest(new CountingOutputStream(out, this.listener));
32    }
33
34    public static interface ProgressListener {
35        void transferred(long num);
36    }
37
38    public static class CountingOutputStream extends FilterOutputStream {
39
40        private final ProgressListener listener;
41
42        private long transferred;
43
44        public CountingOutputStream(final OutputStream out,
45                final ProgressListener listener) {
46            super(out);
47            this.listener = listener;
48            this.transferred = 0;
49        }
50
51        public void write(byte[] b, int off, int len) throws IOException {
52            out.write(b, off, len);
53            this.transferred += len;
54            this.listener.transferred(this.transferred);
55        }
56
57        public void write(int b) throws IOException {
58            out.write(b);
59            this.transferred++;
60            this.listener.transferred(this.transferred);
61        }
62    }
63}

BEST

Ảnh đại diện của Tuan Nguyen Van

Hi bạn! Cá nhân mình trong thực tế cũng đã từng làm feature kiểu này rồi. Chính xác là làm import file excel chứa các thông tin products rồi phía BE xử lý đọc file và tạo sản phẩm. Mình đoán bạn cũng đang làm task tương tự như thế. Ở feature này mình làm cả FE, BE nên mình đưa ra suggest cho bạn cách mình giải quyết nhé ( Hiện tại, feature vẫn chạy ngon ở product nhé :D ) Ở phía FE: - Với file excel thì nên giới hạn 10mb / per file. Hoặc 1 số nào đấy vừa đủ. Vì đây không phải là video hay file nên sẽ không nặng và file này trên BE bạn sẽ xử lý => mình nghĩ bạn không cần chia nhỏ file đâu. - Upload bằng form data như bình thường. - Mỗi lần F5 lại trang hoặc bạn muốn near real time thì 10s call API BE để lấy thông tin process file. Ở phía BE: - Nhận được file => đọc file => push job vào queue xử lý ( trước làm task mình dùng rabbitmq ). - Xử lý từng product. Mình có 1 biến đếm mỗi lần xử lý xong mình increase nó thêm 1 => lưu thông tin process vào redis. - Làm 1 api đọc thông tin process và gửi cho FE hiển thị. Ở đây mình đang đoán bạn làm task tương tự như vậy. Còn nếu của bạn chỉ đơn giản là theo dõi tiến độ upload file thì FE bạn nên chia nhỏ file ra thành từng phần nhỏ 10mb / 1 phần chẳng hạn. Ví dụ file 100mb => bạn chia 10 phần gọi async 10 lần API lên BE => Mỗi lần gọi bạn tăng tiến độ xử lý 10%. Tương tự dựa vào size file và batch size file bạn chia => Tính ra được số % mỗi lần xử lý batch file. Trước cũng có 1 câu hỏi FE nén video gửi lên server. Mình có suggest idea và code example. Bạn tham khảo ở link dưới nhé. Hi vọng, câu trả lời của mình sẽ giúp bạn có giải pháp cho feature đang làm. https://careerly.vn/comments/6411?utm_campaign=self-share

Đăng ký ngay bây giờ để đọc toàn bộ câu trả lời!

Cộng đồng lập trình viên sẽ giải đáp tường tận cho bạn.

Xem thêm

Đồng ý với Điều khoản dịch vụ Chính sách bảo mật của Careerly

Bạn đã có tài khoản rồi?

Đăng ký ngay bây giờ để đọc toàn bộ câu trả lời!

Cộng đồng lập trình viên sẽ giải đáp tường tận cho bạn.