【问题标题】:How to create XMPP chat client for facebook?如何为 facebook 创建 XMPP 聊天客户端?
【发布时间】:2012-06-18 04:52:17
【问题描述】:

我正在为 FACEBOOK 创建 XMPP 客户端。我为 gmail 做了这个,现在我必须为 FaceBook 创建相同的内容。我为此搜索了很多代码,但我仍然收到此类错误Not connected to serverservice-unavailable(503)

我在这里分享我所做的代码。

public class ClientJabberActivity extends Activity {

ArrayList<String> m_discussionThread;
ArrayAdapter<String> m_discussionThreadAdapter;
XMPPConnection m_connection;
private Handler m_handler;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    m_handler = new Handler();

    try {
        initConnection();
    } catch (XMPPException e) {
        e.printStackTrace();
    }

    final EditText recipient = (EditText) this.findViewById(R.id.recipient);
    final EditText message = (EditText) this.findViewById(R.id.message);
    ListView list = (ListView) this.findViewById(R.id.thread);

    m_discussionThread = new ArrayList<String>();
    m_discussionThreadAdapter = new ArrayAdapter<String>(this,
            R.layout.multi_line_list_item, m_discussionThread);
    list.setAdapter(m_discussionThreadAdapter);

    Button send = (Button) this.findViewById(R.id.send);
    send.setOnClickListener(new View.OnClickListener() {
        public void onClick(View view) {

            String to = recipient.getText().toString();
            String text = message.getText().toString();

            Message msg = new Message(to, Message.Type.chat);
            msg.setBody(text);
            m_connection.sendPacket(msg);
            m_discussionThread.add(" Me  : ");
            m_discussionThread.add(text);
            m_discussionThreadAdapter.notifyDataSetChanged();
        }
    });
}

private void initConnection() throws XMPPException {

    ConnectionConfiguration config = new ConnectionConfiguration(
            "chat.facebook.com", 5222, "chat.facebook.com");
    config.setSASLAuthenticationEnabled(true);
    m_connection = new XMPPConnection(config);
    try {
        SASLAuthentication.registerSASLMechanism("X-FACEBOOK-PLATFORM",
                SASLXFacebookPlatformMechanism.class);
        SASLAuthentication.supportSASLMechanism("X-FACEBOOK-PLATFORM", 0);
        m_connection.connect();          
        m_connection.login(apiKey + "|" + sessionKey, sessionSecret, "Application");
    } catch (XMPPException e) {
        m_connection.disconnect();
        e.printStackTrace();
    }

    Presence presence = new Presence(Presence.Type.available);
    m_connection.sendPacket(presence);

    PacketFilter filter = new MessageTypeFilter(Message.Type.chat);

    m_connection.addPacketListener(new PacketListener() {
        public void processPacket(Packet packet) {
            Message message = (Message) packet;
            if (message.getBody() != null) {
                String fromName = StringUtils.parseBareAddress(message
                        .getFrom());
                m_discussionThread.add(fromName + ":");
                m_discussionThread.add(message.getBody());

                m_handler.post(new Runnable() {
                    public void run() {
                        m_discussionThreadAdapter.notifyDataSetChanged();
                    }
                });
            }
        }
    }, filter);

    ChatManager chatmanager = m_connection.getChatManager();
    chatmanager.addChatListener(new ChatManagerListener() {
        public void chatCreated(final Chat chat,
                final boolean createdLocally) {
            chat.addMessageListener(new MessageListener() {
                public void processMessage(Chat chat, Message message) {
                    System.out.println("Received message: "
                            + (message != null ? message.getBody() : "NULL"));
                    Log.i("CHAT USER",
                            "Received message is: " + message.getBody());
                }
            });
        }
    });
}
 }

还有这个班级SASLXFacebookPlatformMechanism

我怎样才能像这样登录xmpp.login(apiKey + "|" + sessionKey, sessionSecret, "Application"); 我知道如何获取 facebook 的 accessToken,应用程序密钥。我不知道 sessionKey、sessionSecret 如何获取这些值以及如何解决这个问题。

如果我使用 xmpp.login(apiKey, accessToken, "Application"); 我会收到此错误 --IllegalArgumentException: API key or session key is not present

编辑: 最后我从 Amal 解决方案中得到了解决方案:xmpp.login(apiKey, accessToken, "Application");

【问题讨论】:

  • 在一些答案中访问令牌看起来像这样“something|sessionKey|somethingElse”,但我的访问令牌看起来像这样--AAABeS1oNtyABANFNGJRZBLn5G1SKzj3jKlSi36F2iagYi0lhwvnt0ZAHtSxbWWZB8Ehq3CY3x5JxNz5wKSAlj5xagXAm4qxPJkOh3K为什么两者不同..
  • 是 facebook sdk 更改访问令牌格式..
  • 能否给我一个下载jar的链接,以便在我的android项目中导入XMPP、Sasl和ConnectionConfiguration来实现FB聊天。
  • @Arun 在这里查看这个可用的 asmack 库列表,code.google.com/p/asmack/downloads/list 在这个我使用 asmack-2010.05.07。它将对 Gmail 和 Facebook 有用。
  • 我们能从这里导入 Sasl 吗?

标签: android facebook xmpp


【解决方案1】:

对于 android 2.2 更高版本,必须在 AsyncTask 中建立连接...

private class AsyncCallWS extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
    Log.i(TAG, "doInBackground");
    calculate();
    return null;
}

@Override
protected void onPostExecute(Void result) {
    Log.i(TAG, "onPostExecute");
}

@Override
protected void onPreExecute() {
    Log.i(TAG, "onPreExecute");
}

@Override
protected void onProgressUpdate(Void... values) {
    Log.i(TAG, "onProgressUpdate");
}

public void calculate() 
{
    Session s = Session.getActiveSession();
    ConnectionConfiguration config = new ConnectionConfiguration("chat.facebook.com", 5222);
    config.setSASLAuthenticationEnabled(true);
    XMPPConnection mFbConnection = new XMPPConnection(config);


        SASLAuthentication.registerSASLMechanism("X-FACEBOOK-PLATFORM", SASLXFacebookPlatformMechanism.class);
        SASLAuthentication.supportSASLMechanism("X-FACEBOOK-PLATFORM", 0);

        try {
            mFbConnection.connect();    

            Log.i("XMPPClient",
                    "Connected to " + mFbConnection.getHost());

            mFbConnection.login("7028228197XXXXXX",s.getAccessToken(),"Application");
            Roster roster = mFbConnection.getRoster();
            Collection<RosterEntry> entries = roster.getEntries();

            Log.i("XMPPClient","\n\n"+ entries.size() + " buddy(ies):");

            // shows first time onliners---->
            String temp[] = new String[50];
            int i = 0;
            for (RosterEntry entry : entries) {    
                 String user = entry.getName();
                 Log.i("TAG", user);
                }


        } catch (Exception e) {

            e.printStackTrace();
        } 
}
}

别忘了添加权限。

private static final List<String> PERMISSIONS = Arrays.asList("xmpp_login");
if(checkPermissions()) 
    {
        AsyncCallWS task = new AsyncCallWS();
        task.execute(); 
    }
    else
    {
         requestPermissions();
    }


public boolean checkPermissions() {
    Session s = Session.getActiveSession();
    if (s!=null) {
        return s.getPermissions().contains("xmpp_login");
    }
    else
        return false;
}

public void requestPermissions() {
    Session s = Session.getActiveSession();
    if (s!=null)
        s.requestNewReadPermissions(new Session.NewPermissionsRequest(this, PERMISSIONS));
}

【讨论】:

    【解决方案2】:

    首先要获得访问令牌,您必须登录

    fb.authorize(FacebookActivity.this, new String[] {"xmpp_login"},Facebook.FORCE_DIALOG_AUTH, new DialogListner());
    

    SASLXFacebookPlatformMecha 类

    import java.io.IOException;
    import java.net.URLEncoder;
    import java.util.GregorianCalendar;
    import java.util.HashMap;
    import java.util.Map;
    
    import org.apache.harmony.javax.security.auth.callback.CallbackHandler;
    import org.apache.harmony.javax.security.sasl.Sasl;
    import org.jivesoftware.smack.SASLAuthentication;
    import org.jivesoftware.smack.XMPPException;
    import org.jivesoftware.smack.sasl.SASLMechanism;
    import org.jivesoftware.smack.util.Base64;
    
    public class SASLXFacebookPlatformMecha extends SASLMechanism {
    
    private static final String NAME = "X-FACEBOOK-PLATFORM";
    
    private String apiKey = "";
    private String access_token = "";
    
    /**
     * Constructor.
     */
    public SASLXFacebookPlatformMecha(SASLAuthentication saslAuthentication) {
        super(saslAuthentication);
    }
    
    @Override
    protected void authenticate() throws IOException, XMPPException {
    
        getSASLAuthentication().send(new AuthMechanism(NAME, ""));
    }
    
    @Override
    public void authenticate(String apiKey, String host, String acces_token)
            throws IOException, XMPPException {
        if (apiKey == null || acces_token == null) {
            throw new IllegalArgumentException("Invalid parameters");
        }
    
        this.access_token = acces_token;
        this.apiKey = apiKey;
        this.hostname = host;
    
        String[] mechanisms = { NAME };
        Map<String, String> props = new HashMap<String, String>();
        this.sc = Sasl.createSaslClient(mechanisms, null, "xmpp", host, props,
                this);
        authenticate();
    }
    
    @Override
    public void authenticate(String username, String host, CallbackHandler cbh)
            throws IOException, XMPPException {
        String[] mechanisms = { NAME };
        Map<String, String> props = new HashMap<String, String>();
        this.sc = Sasl.createSaslClient(mechanisms, null, "xmpp", host, props,
                cbh);
        authenticate();
    }
    
    @Override
    protected String getName() {
        return NAME;
    }
    
    @Override
    public void challengeReceived(String challenge) throws IOException {
        byte[] response = null;
    
        if (challenge != null) {
            String decodedChallenge = new String(Base64.decode(challenge));
            Map<String, String> parameters = getQueryMap(decodedChallenge);
    
            String version = "1.0";
            String nonce = parameters.get("nonce");
            String method = parameters.get("method");
    
            long callId = new GregorianCalendar().getTimeInMillis();
    
            String composedResponse = "api_key="
                    + URLEncoder.encode(apiKey, "utf-8") + "&call_id=" + callId
                    + "&method=" + URLEncoder.encode(method, "utf-8")
                    + "&nonce=" + URLEncoder.encode(nonce, "utf-8")
                    + "&access_token="
                    + URLEncoder.encode(access_token, "utf-8") + "&v="
                    + URLEncoder.encode(version, "utf-8");
    
            response = composedResponse.getBytes("utf-8");
        }
    
        String authenticationText = "";
    
        if (response != null) {
            authenticationText = Base64.encodeBytes(response,
                    Base64.DONT_BREAK_LINES);
        }
    
        // Send the authentication to the server
        getSASLAuthentication().send(new Response(authenticationText));
    }
    
    private Map<String, String> getQueryMap(String query) {
        Map<String, String> map = new HashMap<String, String>();
        String[] params = query.split("\\&");
    
        for (String param : params) {
            String[] fields = param.split("=", 2);
            map.put(fields[0], (fields.length > 1 ? fields[1] : null));
        }
    
        return map;
    }
    }
    

    我创建了 ChatManager 类

    import org.jivesoftware.smack.Chat;
    import org.jivesoftware.smack.ChatManagerListener;
    import org.jivesoftware.smack.ConnectionConfiguration;
    import org.jivesoftware.smack.MessageListener;
    import org.jivesoftware.smack.Roster;
    import org.jivesoftware.smack.RosterListener;
    import org.jivesoftware.smack.SASLAuthentication;
    import org.jivesoftware.smack.XMPPConnection;
    import org.jivesoftware.smack.XMPPException;
    import org.jivesoftware.smack.packet.Presence;
    import org.jivesoftware.smack.packet.Presence.Type;
    import org.jivesoftware.smackx.pubsub.PresenceState;
    
    public class FacebookChatManager {
    
    private static FacebookChatManager chatManager;
    private XMPPConnection connection;
    private final String SERVER = "chat.facebook.com";
    private final int PORT = 5222;
    private final String FACEBOOK_MECHANISM = "X-FACEBOOK-PLATFORM";
    private RosterListener rosterListner;
    
    private FacebookChatManager(RosterListener rosterListner)
    {
        this.rosterListner = rosterListner;
        ConnectionConfiguration connFig = new ConnectionConfiguration(SERVER,
                PORT);
        connFig.setSASLAuthenticationEnabled(true);
        connection = new XMPPConnection(connFig);
        //setup facebook authentication mechanism
        SASLAuthentication.registerSASLMechanism(FACEBOOK_MECHANISM,
                SASLXFacebookPlatformMecha.class);
        SASLAuthentication.supportSASLMechanism(FACEBOOK_MECHANISM, 0);
    }
    
    public static FacebookChatManager getInstance(RosterListener rosterListner)
    {
        if(chatManager == null)
        {
            chatManager =  new FacebookChatManager(rosterListner);
        }
        return chatManager;
    }
    
    public boolean connect()
    {
        try {
            connection.connect();
            return true;
        } catch (XMPPException e) {
            e.printStackTrace();
            connection.disconnect();
        }
        return false;
    }
    
    public void disConnect()
    {
        connection.disconnect();
    }
    
    public boolean logIn(String apiKey, String accessToken)
    {
        try {
            connection.login(apiKey, accessToken);
            setPresenceState(Presence.Type.available, "");
            connection.getRoster().addRosterListener(rosterListner);
            return true;
        } catch (XMPPException e) {
            connection.disconnect();
            e.printStackTrace();
        }
        return false;
    }
    
    public Roster getRoster()
    {
        return connection.getRoster();
    }
    
    public Chat createNewChat(String user, MessageListener messageListner)
    {
        return connection.getChatManager().createChat(user, messageListner);
    }
    
    public void registerNewIncomingChatListner(ChatManagerListener chatManagerListner)
    {
        connection.getChatManager().addChatListener(chatManagerListner);
    }
    
    public void setPresenceState(Type precenseType, String status)
    {
        Presence presence = new Presence(precenseType);
        presence.setStatus(status);
        connection.sendPacket(presence);
    }
    
    public Presence getUserPresence(String userId)
    {
        return connection.getRoster().getPresence(userId);
    }
    }
    

    最后使用 FacebookChatManager 类注意 rosterListnr 用于获取有关您的朋友状态更改的信息,根据需要实现一个

    FacebookChatManager facebookChatManager = FacebookChatManager.getInstance(rosterListner);
    
    if (facebookChatManager.connect()) {
                if (facebookChatManager.logIn(FacebookActivity.APP_ID,
                        access_token)) {
                    return facebookChatManager.getRoster();
                }
            }
    

    【讨论】:

    • 您好,感谢您的回复,我能够获得该 access_token,但我仍然收到错误未连接到服务器错误。
    • 我会再次检查清楚,可能是我做错了。检查后通知您。
    • @GökhanBarışAker 我正在使用 asmack-issue15.jar 并且这些类与其他导入的类一起使用。这是 Android 版本的 smack 库
    【解决方案3】:

    【讨论】:

    • 这个工具作为令牌与普通令牌不同吗?为什么我要问是我在以前的应用程序中使用 fb sdk 我得到了一个大令牌,这里的显示比那个小。以及如何通过动态 bez 获取此令牌。它将过期。
    • @RajaReddy P 您从这里获得的令牌用于测试,但最后您应该使用通常从 sdk 获得的令牌。要使用 APIKey 和 accessToken 请看我的回答stackoverflow.com/questions/5317329/…
    • @alexw 你能解释清楚吗...我能够从 android sdk 获取 access_token。登录需要 apiKey、sessionKey、sionSecret 我怎样才能获得这些值..
    • 能否给我一个下载jar的链接,以便在我的android项目中导入XMPP、Sasl和ConnectionConfiguration来实现FB聊天。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    • 2012-10-30
    • 1970-01-01
    • 2015-06-01
    • 1970-01-01
    相关资源
    最近更新 更多