2009-06-05 80 views
6

Tôi có mã Java tạo kết nối socket dài hạn với thiết bị tự động hóa tại nhà để giám sát nó cho hoạt động/sự kiện. Vấn đề là nếu thiết bị được khởi động lại hoặc được cấp nguồn, mã Java sẽ tự động kết nối lại càng sớm càng tốt. Bất kỳ ý tưởng nào về cách phát hiện một kết nối bị ngắt ở phía Java, tốt nhất là không định kỳ bỏ phiếu thiết bị?Kết nối lại kết nối ổ cắm Java khi ngắt kết nối

Trả lời

3

Nếu thiết bị khởi động lại mà không đóng đúng ổ cắm, tôi không biết bất cứ điều gì sẽ cho phép bạn phát hiện nó. Máy chủ của bạn sẽ không thể phát hiện rằng ổ cắm đã biến mất, trong trường hợp này, trừ khi thiết bị trở lại hoặc cho đến khi ngăn xếp TCP/IP trên máy chủ của bạn từ bỏ và tuyên bố kết nối đã chết. Tại một số điểm bạn sẽ nhận được một IOException. Bạn cần phải nắm bắt ngoại lệ đó và sau đó kết nối lại khi nó xảy ra.

Bạn thực sự cảm thấy tiếc về hành vi của TCP/IP tại đây. Khi một đầu của một kết nối đơn giản biến mất (không có gói FIN), đầu kia có thể đợi một khoảng thời gian tùy ý (tùy thuộc vào nhiều yếu tố) trước khi quyết định kết nối đã chết.

Nếu bạn muốn nắm bắt vấn đề này sớm hơn - và bạn có thể đảm bảo rằng thiết bị sẽ phản hồi trong một khoảng thời gian nhất định, sau đó đặt thời gian chờ trên ổ cắm. Nếu bạn làm điều này, bạn sẽ nhận được SocketTimeoutException nếu thiết bị không phản hồi và sau đó bạn có thể đóng ổ cắm và thử mở lại ổ cắm. Tôi đã sử dụng điều này với thành công.

2

Nếu phần mềm của bạn chỉ đang chờ dữ liệu từ thiết bị tự động hóa nhà là cách duy nhất để phát hiện thiết bị đã biến mất, hãy bật tùy chọn SO_KEEPALIVE trong ổ cắm để giao tiếp với thiết bị.

Để thực hiện việc này, chỉ cần gọi phương thức setKeepAlive (true) trên socket và điều đó sẽ làm cho việc triển khai socket bên dưới bật tùy chọn SO_KEEP_ALIVE.

Điều này sẽ làm cho việc triển khai cơ bản trao đổi định kỳ một số dữ liệu với điểm cuối từ xa và nếu thiết bị chết trong khi bạn đang chờ dữ liệu, ngoại lệ sẽ được ném.

Vấn đề duy nhất là việc giữ thời gian chờ này phụ thuộc vào hệ điều hành và đôi khi không thể thay đổi.

Nếu bạn cần thời gian chờ ngắn hơn, không có cách nào khác ngoài việc triển khai thiết bị thăm dò định kỳ trên thiết bị.

1

Tôi đã giải quyết vấn đề tương tự chính xác này.

Nếu bạn muốn nắm bắt vấn đề này sớm hơn - và bạn có thể đảm bảo rằng thiết bị sẽ phản hồi trong một khoảng thời gian nhất định, sau đó đặt thời gian chờ trên ổ cắm. Nếu bạn làm điều này, bạn sẽ nhận được một SocketTimeoutException nếu thiết bị không đáp ứng, và sau đó bạn có thể đóng socket và thử mở lại socket. Tôi đã sử dụng điều này với thành công.

Trích dẫn từ trên:

tôi nhận được nó để đóng socket sau đó cố gắng mở lại nó, mà nó chạy rằng mã tốt. Vấn đề duy nhất là một khi tôi đóng một ổ cắm tôi không thể mở lại nó, tôi nhận được ngoại lệ là các ổ cắm được đóng lại. Điều này xảy ra mỗi lần. Làm thế nào để tôi đóng một ổ cắm sau đó mở lại bằng cách ra ngoài nhận ngoại lệ này?

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