blob: 0901b8f15142b95001c04795340b4db4b58c2c42 [file] [log] [blame]
Shuyi Chend7955ce2013-05-22 14:51:55 -07001/**
2 * Copyright 2012-2013 Florian Schmaus
3 *
4 * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.jivesoftware.smackx.ping;
18
19import java.lang.ref.WeakReference;
20import java.util.Set;
21
22import org.jivesoftware.smack.Connection;
23
24class ServerPingTask implements Runnable {
25
26 // This has to be a weak reference because IIRC all threads are roots
27 // for objects and we have a new thread here that should hold a strong
28 // reference to connection so that it can be GCed.
29 private WeakReference<Connection> weakConnection;
30
31 private int delta = 1000; // 1 seconds
32 private int tries = 3; // 3 tries
33
34 protected ServerPingTask(Connection connection) {
35 this.weakConnection = new WeakReference<Connection>(connection);
36 }
37
38 public void run() {
39 Connection connection = weakConnection.get();
40 if (connection == null) {
41 // connection has been collected by GC
42 // which means we can stop the thread by breaking the loop
43 return;
44 }
45 if (connection.isAuthenticated()) {
46 PingManager pingManager = PingManager.getInstanceFor(connection);
47 boolean res = false;
48
49 for (int i = 0; i < tries; i++) {
50 if (i != 0) {
51 try {
52 Thread.sleep(delta);
53 } catch (InterruptedException e) {
54 // We received an interrupt
55 // This only happens if we should stop pinging
56 return;
57 }
58 }
59 res = pingManager.pingMyServer();
60 // stop when we receive a pong back
61 if (res) {
62 pingManager.lastSuccessfulPingByTask = System.currentTimeMillis();
63 break;
64 }
65 }
66 if (!res) {
67 Set<PingFailedListener> pingFailedListeners = pingManager.getPingFailedListeners();
68 for (PingFailedListener l : pingFailedListeners) {
69 l.pingFailed();
70 }
71 } else {
72 // Ping was successful, wind-up the periodic task again
73 pingManager.maybeSchedulePingServerTask();
74 }
75 }
76 }
77}