Truyền nhận dữ liệu trong socket.io



  • Mình đang tìm hiểu socket.io này với một app nhỏ là tìm kiếm các row trong CSDL. Vấn đề là khi mình truy cập và connect đến server, lần đầu tìm kiếm thì server tìm đúng kết quả và truyền lên client, cho client hiển thị ra cũng đúng luôn. Nhưng tiếp tục tìm kiếm lần nữa thì vấn đề xảy ra. Phía server thì kết quả tìm kiếm ra kết quả vẫn đúng, nhưng khi truyền lên client thì phía client nhận được kết quả và bao gồm vào đó là thêm tất cả các kết quả của lần tìm kiếm trước nữa chứ không phải là chỉ có kết quả của lần vừa rồi.
    Và cho mình hỏi thêm một vấn đề nữa là mình có thể dừng nghe một sự kiện, và cho lắng nghe lại sự kiện đó sau này không?
    Mong các pro, cao nhân chỉ giáo với ạ.

    File app.js

    ... // Phần khai báo trước
    
    // Phần xử lý kết nối và truy xuất dữ liệu
    io.on('connection', function (socket) {
        socket.emit('connected');
        console.log('Client connected!');
        socket.on('find', function(data) {
            console.log(data)
            if (Object.keys(data).length > 0) {
                test.findAll({where: data, logging: function (sql) {
                    console.log(sql);
                }}).then(function(rows) {
                    console.log(rows.length)
                    socket.emit('findfinish');
                    socket.on('load', function(index) {
                        if (index < rows.length ) {
                            socket.emit('add', rows[index].dataValues, index);
                        } else {
                            socket.emit('finishtransfer');
                        }
                    });
                });
            } else {
                console.log('data null');
            }
        });
    });
    

    File index.html

    
    // Phần xử lý script ở client
    <script>
        var current = undefined;
        var socket = io('http://localhost', {transports: ['websocket'], upgrade: false});
        socket.on('connected', function() {
            console.log('connected');
        })
        var titles = [];
        var th = $('th');
        th.each((key, element) => {
            titles.push($(element).text());
            $('<input type="text" name="' + titles[key] + '" id="' + key + '" placeholder="' + titles[key] + '">').appendTo('#search-form').promise().done(function() {
                $(this).bind('keyup', function() {
                    if (current != $(this).val()) {
                        current = $(this).val()
                        $('#result tbody').html('');
                        var obj = {};
                        $('#search-form input').each( (k,v) => {
                            if ( $(v).val() != '' ) {
                                obj[titles[k]] = { $like : '%' + $(v).val() + '%' }  ;
                            }
                        });
                        socket.emit('find', obj);
                    }
    
                });
            });
        });
        socket.on('findfinish', function() {
            socket.emit('load', 0);
        })
        socket.on('add', addData);  
        socket.on('finishtransfer', function() {
            console.log('Finished');
        });
        function addData(data, index) {
            if (data) {
                var html = '<tr>';
                html += '<td nowrap>' + data["Row ID"] + '</td>';
                html += '<td nowrap>' + data["Order ID"] + '</td>';
                html += '<td nowrap>' + data["Order Date"] + '</td>';
                html += '<td nowrap>' + data["Ship Date"] + '</td>';
                html += '<td nowrap>' + data["Ship Mode"] + '</td>';
                html += '<td nowrap>' + data["Customer ID"] + '</td>';
                html += '<td nowrap>' + data["Customer Name"] + '</td>';
                html += '<td nowrap>' + data["Segment"] + '</td>';
                html += '<td nowrap>' + data["Country"] + '</td>';
                html += '<td nowrap>' + data["City"] + '</td>';
                html += '<td nowrap>' + data["State"] + '</td>';
                html += '<td nowrap>' + data["Postal Code"] + '</td>';
                html += '<td nowrap>' + data["Region"] + '</td>';
                html += '<td nowrap>' + data["Product ID"] + '</td>';
                html += '<td nowrap>' + data["Category"] + '</td>';
                html += '<td nowrap>' + data["Sub-Category"] + '</td>';
                html += '<td nowrap>' + data["Product Name"] + '</td>';
                html += '<td nowrap>' + data["Sales"] + '</td>';
                html += '<td nowrap>' + data["Quantity"] + '</td>';
                html += '<td nowrap>' + data["Discount"] + '</td>';
                html += '<td nowrap>' + data["Profit"] + '</td>';   
                html += '</tr>';
                $('#result tbody').append(html);
                socket.emit('load', index + 1);
            }
        }
    </script>
    

    Sau khi console.log ở client thì mình nhận thấy là sự kiện 'finishtransfer' đã được phát đi rất nhiều lần bắt đầu từ lần tìm kiếm thứ 2



  •         $('#result tbody').append(html);
    

    Bạn thử .empty() trước khi .append()



  • ngay lúc nhập dữ liệu vào ô search là mình đã có lệnh empty cho tbody rồi ạ. chỉ có cái là cái data truyền lên nó bị lặp dữ liệu thôi bác



  • mỗi lần find, bạn đều đăng ký thêm 1 sự kiện on('load')
    nên khi client emit thì tất cả được trigger thôi.
    ps: đừng đăng kí sự kiện lắng nghe lồng nhau



  • Vâng, mình hiểu rồi. Thank bạn nhé. Vậy tiện bác biết làm cách nào để mình có thể dừng nghe một sự kiện, và cho lắng nghe lại sự kiện đó sau này không?



  • Bạn có thể removeListener đó đi. Hoặc dùng cờ để kiểm tra.


Log in to reply