2012-05-31 35 views
10

Tôi gặp một hành vi khá lạ khi sử dụng smack để xây dựng một Client/Bot XMPP nhỏ. Tôi thiết lập kết nối cũng như một ConnectionListener và một ChatManagerListener. Điều này hoạt động khá tốt và sau đó tôi có thể trò chuyện với ứng dụng của tôi đang chạy trên thiết bị di động.Smack Client - Người dùng vẫn đang 'online' mặc dù kết nối bị hủy bỏ

Để kiểm tra hành vi trên kết nối bị mất, tôi đã cắm cáp ethernet của thiết bị di động. Tôi hy vọng khách hàng XMPP sẽ mất kết nối và người dùng sẽ được đặt 'ngoại tuyến' trong danh sách bạn bè của người dùng. Điều gì xảy ra là, người dùng này vẫn được hiển thị dưới dạng 'trực tuyến' và ConnectionListener của khách hàng của tôi không kích hoạt gì, cho dù connectionClosed cũng không kết nối lại hay không.

Khi tôi sau đó cắm cáp ethernet trở lại, đôi khi nó giống như kết nối đã được duy trì mọi lúc. Các tin nhắn ngoại tuyến được xử lý và tôi có thể trò chuyện lại như trước đây. Các lần khác khách hàng của tôi hoàn toàn không thể tiếp cận và ra khỏi trật tự, có vẻ như tất cả các thính giả đã biến mất ... Nhưng không có sự bất bình nào được ném ra.

Đó là một hành vi khá lạ và không kiểm soát được sẽ làm cho toàn bộ khách hàng không thể sử dụng được cho tôi, vì tôi không thể chắc chắn rằng khách hàng sẽ xuất hiện trở lại sau khi kết nối đã bị cấm.

Có ai khác gặp phải vấn đề như vậy hoặc có bất kỳ gợi ý nào (không) xảy ra?

Nếu cần tôi có thể cung cấp mã của tôi, nhưng thực sự chỉ cần sao chép & dán từ tài liệu Smack.

Trả lời

8

Bạn đang thực sự mô tả hai các hiệu ứng khác nhau tại đây. Hãy bắt đầu với tên được đặt tên trong tiêu đề câu hỏi của bạn: Người dùng được giả định trực tuyến bởi máy chủ ngay cả khi kết nối đột ngột và do đó bị xóa, bị hủy. Lý do đơn giản là máy chủ đã không nhận thấy sự ngắt kết nối của máy khách, vì không có sự kết thúc rõ ràng của luồng XMPP. Hầu hết máy chủ XMPP kiểm tra các máy khách với một ping mỗi X phút. Nếu một máy khách không trả lời, nó giả định bị ngắt kết nối và hiển thị ngoại tuyến (nếu nó là tài nguyên được kết nối cuối cùng cho JID đó). Điều đó đã không xảy ra ở đây và không phải là không phổ biến. Bởi vì đôi khi bạn muốn có thời gian chờ lâu (nửa giờ hoặc lâu hơn).

Điều tương tự cũng áp dụng cho phía bên kia. Smack cũng gửi XMPP ping mỗi X phút nếu PingManager hoặc PingManagerWithAlarmManager (dành cho Android) được sử dụng. Nếu có bất kỳ vấn đề với socket được sử dụng, một ngoại lệ được ném.

Tôi hy vọng rằng tôi có thể hướng bạn đi đúng hướng. Bạn phải gỡ lỗi cho chính mình tại sao kết nối không bị chấm dứt với một ngoại lệ trong trường hợp của bạn.

Điều cuối cùng: Kết nối TCP có thể dễ dàng tồn tại trong một khoảng thời gian chờ ngay cả khi cáp Ethernet được cắm ra và sau đó quay lại. Có nhiều thời gian chờ trên các lớp khác nhau của mô hình OSI liên quan: NAT, TCP, XMPP, v.v.

+0

Cảm ơn đã giải thích, họ có thể giúp tôi. Có lẽ tôi sẽ kiên nhẫn hơn và chờ đợi hơn 1-2 phút trước khi cắm lại cáp. Nhưng dù sao thì vấn đề của người nghe đôi khi vẫn được điều chỉnh và đôi khi không phải là một bí ẩn. Nhưng tôi nghĩ tôi sẽ mở một câu hỏi khác cho điều đó. – signpainter

+2

Tôi muốn thêm rằng hành vi này của TCP không phải là một lỗi, nhưng một tính năng tuyệt vời mà ít người dường như đánh giá cao.Không cần phải kết nối lại và thực hiện cài đặt luồng XMPP khá tốn kém giúp bạn tiết kiệm rất nhiều chuyến khứ hồi. Những gì bạn có thể muốn là cho hệ điều hành để cho bạn biết về mất mát, và nối lại, kết nối để bạn có thể kiểm tra xem kết nối có còn sống hay không. Nếu nó đã làm, chạy dọc theo như thể không có gì xảy ra, nếu không kết nối lại. Kết nối lại XEP-0198 cũng rất tuyệt vời. – Zash

0

bạn đã sử dụng quá rõ ràng phương pháp disconnect() chấm dứt kết nối của bạn, nếu không thì máy chủ sẽ phải định kỳ ping bạn và nhận ra rằng mình đã đi ẩn

Các vấn đề liên quan