使用 PubNub 获取用户状态

Get user status using PubNub

我创建了一个使用 Sinch 实现应用到应用调用的应用程序。只有当呼叫者知道接收者的名字时它才有效。

为了克服这个问题,Sinch 建议使用 PubNub 来获取用户状态。他们也有一个 tutorial here. 问题是教程很旧,PubNub 已经更新了他们的 API。我尝试使用他们的文档自己使用他们的新 API 来实现该功能,但它不起作用或更准确地说我不知道​​该怎么做。

我当前的代码是:

public class LoggedUsers extends Activity {
    private PubNub pubNub;
    String name;
    private ArrayList users;
    private JSONArray loggedUserList;
    ListView UserList;
    TextView allUsers;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.user_list);
        allUsers = (TextView) findViewById(R.id.JSONFromPubNub);
        SharedPreferences sp = getSharedPreferences("User_Details", MODE_APPEND);
        try {
            name = sp.getString("UserName", "");
        } catch (NullPointerException e) {

        }
        final PNConfiguration pnc = new PNConfiguration();
        pnc.setPublishKey("publish key");
        pnc.setSubscribeKey("subscribe key");
        pnc.setUuid(name);

        pubNub = new PubNub(pnc);
        users = new ArrayList<String>();
        UserList = (ListView) findViewById(R.id.listView);
        String user = getUserStatus();
        allUsers.setText(user);
        final ArrayAdapter adapter = new ArrayAdapter(getApplicationContext(), R.layout.single_item_list, users);
        UserList.setAdapter(adapter);

        pubNub.addListener(new SubscribeCallback() {
            @Override
            public void status(PubNub pubnub, PNStatus status) {
                if (status.getCategory() == PNStatusCategory.PNUnexpectedDisconnectCategory) {
                    // This event happens when radio / connectivity is lost
                    HashMap <String,String> map = new HashMap();
                    map.put("State","Offline");
                    pubNub.setPresenceState().channels(Arrays.asList("CallingChannel1")).state(map).uuid(pnc.getUuid());
                } else if (status.getCategory() == PNStatusCategory.PNConnectedCategory) {

                    // Connect event. You can do stuff like publish, and know you'll get it.
                    // Or just use the connected event to confirm you are subscribed for
                    // UI / internal notifications, etc
                    HashMap <String,String> map = new HashMap();
                    map.put("State","Online");
                    pubNub.setPresenceState().channels(Arrays.asList("CallingChannel1")).state(map).uuid(pnc.getUuid());
                  /*  if (status.getCategory() == PNStatusCategory.PNConnectedCategory) {
                        pubnub.publish().channel("awesomeChannel").message("hello!!").async(new PNCallback<PNPublishResult>() {
                            @Override
                            public void onResponse(PNPublishResult result, PNStatus status) {
                                // Check whether request successfully completed or not.
                                if (!status.isError()) {

                                    // Message successfully published to specified channel.
                                }
                                // Request processing failed.
                                else {

                                    // Handle message publish error. Check 'category' property to find out possible issue
                                    // because of which request did fail.
                                    //
                                    // Request can be resent using: [status retry];
                                }
                            }
                        });
                    }*/
                } else if (status.getCategory() == PNStatusCategory.PNReconnectedCategory) {
                    HashMap <String,String> map = new HashMap();
                    map.put("State","Online");
                    pubNub.setPresenceState().channels(Arrays.asList("CallingChannel1")).state(map).uuid(pnc.getUuid());

                    // Happens as part of our regular operation. This event happens when
                    // radio / connectivity is lost, then regained.
                } else if (status.getCategory() == PNStatusCategory.PNDecryptionErrorCategory) {

                    // Handle messsage decryption error. Probably client configured to
                    // encrypt messages and on live data feed it received plain text.
                }
            }

            @Override
            public void message(PubNub pubnub, PNMessageResult message) {

            }

            @Override
            public void presence(PubNub pubnub, PNPresenceEventResult presence) {

            }
        });
    }
    public String getUserStatus(){
        final StringBuilder allUsers = new StringBuilder();
        pubNub.subscribe().channels(Arrays.asList("CallingChannel1")).withPresence().execute();
        pubNub.hereNow()
                // tailor the next two lines to example
                .channels(Arrays.asList("CallingChannel1"))
                .includeState(true)
                .includeUUIDs(true)
                .async(new PNCallback<PNHereNowResult>() {
                    @Override
                    public void onResponse(PNHereNowResult result, PNStatus status) {
                        if (status.isError()) {
                            // handle error
                            return;
                        }

                        for (PNHereNowChannelData channelData : result.getChannels().values()) {
                            allUsers.append("---");
                            allUsers.append("channel:" + channelData.getChannelName());
                            allUsers.append("occoupancy: " + channelData.getOccupancy());
                            allUsers.append("occupants:");
                            for (PNHereNowOccupantData occupant : channelData.getOccupants()) {
                                allUsers.append("uuid: " + occupant.getUuid() + " state: " + occupant.getState());
                            }
                        }
                    }
                });
               return allUsers.toString();
    }



    @Override
    protected void onResume() {
        super.onResume();
    }
}

这是我的问题:

  1. 我正在尝试在文本视图中显示我收到的所有数据(稍后它将在列表视图或回收器视图中排列)但是我得到一个空白屏幕所以我从服务器。

  2. 用户状态应该不断更新以了解用户是否更改状态(在线 -> 离线)但是代码中似乎没有进行 async 调用所以我认为将只执行一次,然后数据集不会被更改。

我该如何解决我的问题?

PubNub 状态

您可以使用 PubNub Presence. When you subscribe, subscribe with presence enabled and you will get state-change, join, leave & timeout events in the presence callback 监控在线和状态变化。

Callback callback = new Callback() {
    @Override
    public void successCallback(String channel, Object message) {
        System.out.println(channel + " : "
                + message.getClass() + " : " + message.toString());

       // take action on the presence events here
    }
 
    @Override
    public void connectCallback(String channel, Object message) {
       System.out.println("CONNECT on channel:" + channel
                + " : " + message.getClass() + " : "
                + message.toString());
    }
 
    @Override
    public void disconnectCallback(String channel, Object message) {
        System.out.println("DISCONNECT on channel:" + channel
                + " : " + message.getClass() + " : "
                + message.toString());
    }
 
    @Override
    public void reconnectCallback(String channel, Object message) {
        System.out.println("RECONNECT on channel:" + channel
                + " : " + message.getClass() + " : "
                + message.toString());
    }
 
    @Override
    public void errorCallback(String channel, PubnubError error) {
        System.out.println("ERROR on channel " + channel
                + " : " + error.toString());
    }
};
 
try {
    pubnub.presence("my_channel", callback);
} 
catch (PubnubException e) {
    System.out.println(e.toString());
}

Sinch 似乎使用的是相当旧版本的 PubNub Android SDK。我认为您仍然可以使用 PubNub Android SDK v4 在 Sinch SDK 之外执行您需要执行的操作,除非 Sinch 明确要求使用相同版本的 SDK。