2012-04-21 33 views

Trả lời

18

Một kỹ thuật là triển khai phương pháp "keepalive" mà mỗi khách hàng thường xuyên gọi. Điều này giả định bạn đã có một số user_id được giữ trong số Session của từng khách hàng.

// server code: heartbeat method 
Meteor.methods({ 
    keepalive: function (user_id) { 
    if (!Connections.findOne(user_id)) 
     Connections.insert({user_id: user_id}); 

    Connections.update(user_id, {$set: {last_seen: (new Date()).getTime()}}); 
    } 
}); 

// server code: clean up dead clients after 60 seconds 
Meteor.setInterval(function() { 
    var now = (new Date()).getTime(); 
    Connections.find({last_seen: {$lt: (now - 60 * 1000)}}).forEach(function (user) { 
    // do something here for each idle user 
    }); 
}); 

// client code: ping heartbeat every 5 seconds 
Meteor.setInterval(function() { 
    Meteor.call('keepalive', Session.get('user_id')); 
}, 5000); 
+0

Sau nhiều tìm kiếm tôi nghĩ đây là giải pháp tốt nhất hiện nay. Cảm ơn!! – greggreg

+6

Đây gần như mã giả, vì nó không hoạt động như: setInterval đầu tiên không có khoảng thời gian nào được chỉ định. Ngoài ra lệnh Connections.update không chỉ định để cập nhật {'user_id': user_id}. Có thể có các lỗi khác. Đó là một khởi đầu tốt đẹp mặc dù. –

+3

@debergalis Đây có phải là cách được khuyến nghị để xem khách hàng có bị chết không? – user2602152

1

nếu bạn đang sử dụng Auth bạn có quyền truy cập vào ID của người dùng trong phương pháp và Xuất bản chức năng, bạn có thể thực hiện theo dõi của bạn có .. ví dụ bạn có thể đặt "lần xem cuối cùng" khi người dùng chuyển đổi phòng:

Meteor.publish("messages", function(roomId) { 
    // assuming ActiveConnections is where you're tracking user connection activity 
    ActiveConnections.update({ userId: this.userId() }, { 
     $set:{ lastSeen: new Date().getTime() } 
    }); 
    return Messages.find({ roomId: roomId}); 
}); 
13

Tôi nghĩ cách tốt hơn là bắt sự kiện đóng socket trong chức năng xuất bản.

Meteor.publish("your_collection", function() { 
    this.session.socket.on("close", function() { /*do your thing*/}); 
} 

UPDATE:

Mới hơn phiên bản của thiên thạch sử dụng _SESSION như thế này:

this._session.socket.on("close", function() { /*do your thing*/}); 
+0

Điều đó thật tuyệt. Nhưng sau đó tôi dường như chạy vào vấn đề này: http://stackoverflow.com/questions/10192938/meteor-code-must-always-run-within-a-fiber-when-calling-collection-insert-on-s – huyz

+0

Cảm ơn . Đây là câu trả lời cho câu hỏi của tôi: [Meteor quan sát chạy mãi mãi] (http://stackoverflow.com/q/12902392/599991) – zVictor

+3

Tôi sử dụng meteor 0.6.1 và cho dòng này 'this.session.socket.on (" đóng ", function() {/ * làm điều của bạn * /});' my server trả về _TypeError: Không thể đọc thuộc tính 'socket' của undefined_ Nhưng khi tôi sửa nó thành 'this._session.socket.on (" close ", function() {/ * làm việc của bạn * /}); 'nó hoạt động tốt, nhờ – fantom

2

Tôi đã thực hiện một gói thông minh Meteor theo dõi tất cả các phiên kết nối từ phiên khác nhau và phát hiện cả hai phiên logout và ngắt kết nối các sự kiện, mà không phải tốn kém.

https://github.com/mizzao/meteor-user-status

Để phát hiện các sự kiện ngắt kết nối/logout, bạn chỉ có thể làm như sau:

UserStatus.on "connectionLogout", (info) -> 
    console.log(info.userId + " with session " + info.connectionId + " logged out") 

Bạn cũng có thể sử dụng nó chủ động. Kiểm tra nó ra!

CHỈNH SỬA:v0.3.0 trạng thái người dùng giờ đây cũng theo dõi người dùng không sử dụng!

+0

Điều này có thể được thực hiện trên cơ sở mỗi trang và không thông qua toàn bộ ứng dụng không? – Scalahansolo

+0

Có, mặc dù chưa được triển khai. Mở yêu cầu tính năng! –

-1

Tôi đang sử dụng Iron Router và gọi mã dọn dẹp của tôi trên sự kiện unload của bộ điều khiển chính của tôi. Chắc chắn điều này sẽ không bắt sự kiện đóng tab, nhưng vẫn cảm thấy đủ tốt cho nhiều trường hợp sử dụng

ApplicationController = RouteController.extend({ 
    layoutTemplate: 'root', 
    data: {}, 
    fastRender: true, 
    onBeforeAction: function() { 
     this.next(); 
    }, 
    unload: function() { 
     if(Meteor.userId()) 
      Meteor.call('CleanUpTheUsersTrash'); 
    }, 
    action: function() { 
     console.log('this should be overridden by our actual controllers!'); 
    } 
}); 
Các vấn đề liên quan