Pubnub hereNow: проблемы с переменной областью и потоками
Вот мой код
Я пытаюсь проверить, подписан ли подписчик с определенным идентификатором на мой канал.
public class HubActions {
private boolean reply;
public boolean isConnected(String id, String chan) {
String subKey = "sub-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
String pubKey = "pub-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
Pubnub pubnub = new Pubnub(pubKey, subKey);
Callback callback = new Callback() {
public void successCallback(String channel, Object response) {
System.out.println(response.toString());
try {
JSONObject json = new JSONObject(response.toString());
JSONArray uuids = new JSONArray();
uuids = json.getJSONArray("uuids");
for(int i=0;i<json.getInt("occupancy");i++) {
if(uuids.get(i).equals(id)) {
System.out.println("Yup!");
reply = true;
break;
}
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void errorCallback(String channel, PubnubError error) {
System.out.println(error.toString());
}
};
pubnub.hereNow(chan, callback);
return reply;
}
public static void main(String[] args) {
boolean b = new HubActions().isConnected("2", "2_sub");
System.out.println(b);
}
}
Вот мой вывод
ложный
{"Размещение":2,"сервис":"Присутствие","сообщение":"OK","Статус":200,"UUID,":["2","3bbe065c-d84a-4529-a641-26d05439e71d"]}
Ага!
Я не понимаю, почему возвращается false, хотя функция явно присваивает значение true ответу логической переменной
Я понимаю, что при создании экземпляра pubnub 2 потоки инициализируются. Я думаю, что это может быть, что потоки все еще обрабатывают, в то время как функция возвращает значение переменной по умолчанию ответа
Но как мне решить это?
1 ответ
Это асинхронная проблема. Ты звонишь hereNow
, и он сразу возвращается, а затем вы выводите значение reply
в то время как successCallback вызывается асинхронно и запускает цикл.
Вот почему вы видите значение reply
отображается перед отображением Yup. Сделайте это вместо этого:
public class HubActions {
private boolean reply;
public boolean isConnected(String id, String chan) {
String subKey = "sub-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
String pubKey = "pub-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
Pubnub pubnub = new Pubnub(pubKey, subKey);
Callback callback = new Callback() {
public void successCallback(String channel, Object response) {
System.out.println(response.toString());
try {
JSONObject json = new JSONObject(response.toString());
JSONArray uuids = new JSONArray();
uuids = json.getJSONArray("uuids");
for(int i=0;i<json.getInt("occupancy");i++) {
if(uuids.get(i).equals(id)) {
System.out.println("Yup!");
reply = true;
break;
}
}
// output value of reply here
// or implement your own listener for the
// caller to receive the update
System.out.println(reply);
}
catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void errorCallback(String channel, PubnubError error) {
System.out.println(error.toString());
}
};
pubnub.hereNow(chan, callback);
return reply;
}
public static void main(String[] args) {
boolean b = new HubActions().isConnected("2", "2_sub");
// b will always be false due to async nature of code
// must implement a listener to get the result from this scope
// System.out.println(b);
}
}
В приведенном выше коде, я размышляю над реальным решением, которое заключается в реализации шаблона слушателя successCallback
код и позвоните, чтобы уведомить об этом main
,
Все, что я сделал, это закомментировал вашу System.out.println(b)
как это всегда будет false
и делать System.out.println(reply)
в successCallback
после завершения цикла for.