无法将简单的Java Smack示例连接到Google Talk

时间:2014-01-22 10:55:45

标签: java xmpp smack google-talk

我已经学习了一系列教程,并提出了一个非常简单和简约的Java应用程序,它应该连接到谷歌对话并允许我向帐户发送消息。

我已关闭SASLAuth安全设置以使示例正常工作,但是当我尝试连接到Google服务器时,我收到了一个复杂的TLS错误,我认为我被迫启用SASLAuth安全设置。但是,如果我启用它们,我又会出现另一个错误。这是我正在使用的非常简单的代码示例。我错过了什么?

XmppManager.java

package try2;

import java.util.Collection;

import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManager;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.SmackConfiguration;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.Presence.Type;

public class XmppManager {

    private static final int packetReplyTimeout = 500; // millis

    private String server;
    private int port;
    private String service;

    private ConnectionConfiguration config;
    private XMPPConnection connection;

    private ChatManager chatManager;
    private MessageListener messageListener;

    public XmppManager(String aServer, int aPort, String aService) {
        server = aServer;
        port = aPort;
        service = aService;
    }

    public XmppManager(String server, int port) {
        this(server, port, null);
    }

    public void init() throws XMPPException {

        System.out.println(String.format("Initializing connection to server " +  server + ", port " + port 
                + ", service " + service));

        SmackConfiguration.setPacketReplyTimeout(packetReplyTimeout);

        if(service != null)
            config = new ConnectionConfiguration(server, port, service);
        else
            config = new ConnectionConfiguration(server, port);

        config.setSASLAuthenticationEnabled(false);
        config.setSecurityMode(SecurityMode.disabled);

        connection = new XMPPConnection(config);
        connection.connect();

        System.out.println("Connected: " + connection.isConnected());

        chatManager = connection.getChatManager();
        messageListener = new MyMessageListener();

    }

    public void performLogin(String username, String password) throws XMPPException {
        if (connection!=null && connection.isConnected()) {
            connection.login(username, password);
        }
    }

    public void setStatus(boolean available, String status) {

        Presence.Type type = available? Type.available: Type.unavailable;
        Presence presence = new Presence(type);

        presence.setStatus(status);
        connection.sendPacket(presence);

    }

    public void destroy() {
        if (connection!=null && connection.isConnected()) {
            connection.disconnect();
        }
    }

    public void sendMessage(String message, String buddyJID) throws XMPPException {
        System.out.println(String.format("Sending message " + message + " to user " + buddyJID));
        Chat chat = chatManager.createChat(buddyJID, messageListener);
        chat.sendMessage(message);
    }

    public void createEntry(String user, String name) throws Exception {
        System.out.println(String.format("Creating entry for buddy " + user + " with name " + name));
        Roster roster = connection.getRoster();
        roster.createEntry(user, name, null);
    }

    public void printRoster() throws Exception {
        Roster roster = connection.getRoster();
        Collection<RosterEntry> entries = roster.getEntries();  
        for (RosterEntry entry : entries) {
            System.out.println(String.format("Buddy:" + entry.getName() + " - Status:" + entry.getStatus()));
        }
    }


    private class MyMessageListener implements MessageListener {

        @Override
        public void processMessage(Chat chat, Message message) {
            String from = message.getFrom();
            String body = message.getBody();
            System.out.println(String.format("Received message " + body + " from " + from));
        }

    }

}

XmppTest.java

package try2;

public class XmppTest {

    public static void main(String[] args) throws Exception {

        String username = "user1";
        String password = "user1.pass";

        XmppManager xmppManager = new XmppManager("talk.google.com", 5222, "gmail.com");

        xmppManager.init();
        xmppManager.performLogin(username, password);
        xmppManager.setStatus(true, "Hello everyone");

        String buddyJID = "user2";
        String buddyName = "user2";
        xmppManager.createEntry(buddyJID, buddyName);

        xmppManager.sendMessage("Hello mate", "user2@gmail.com");

        xmppManager.printRoster();

        boolean isRunning = true;

        while (isRunning) {
            Thread.sleep(50);
        }

        xmppManager.destroy();

    }

}

我认为错误与这两个代码行有关:

config.setSASLAuthenticationEnabled(false);
config.setSecurityMode(SecurityMode.disabled);

但如果是,那我就不知道如何正确配置它们了!

禁用SASLAuth时出错

Initializing connection to server talk.google.com, port 5222, service gmail.com
java.lang.IllegalStateException: TLS required by server but not allowed by connection configuration
    at org.jivesoftware.smack.XMPPConnection.startTLSReceived(XMPPConnection.java:768)
    at org.jivesoftware.smack.PacketReader.parseFeatures(PacketReader.java:414)
    at org.jivesoftware.smack.PacketReader.parsePackets(PacketReader.java:254)
    at org.jivesoftware.smack.PacketReader.access$000(PacketReader.java:46)
    at org.jivesoftware.smack.PacketReader$1.run(PacketReader.java:72)
Connected: true
Exception in thread "main" No response from the server.: 
    at org.jivesoftware.smack.NonSASLAuthentication.authenticate(NonSASLAuthentication.java:73)
    at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:252)
    at org.jivesoftware.smack.Connection.login(Connection.java:366)
    at try2.XmppManager.performLogin(XmppManager.java:70)
    at try2.XmppTest.main(XmppTest.java:13)

启用SASLAuth时出错

Exception in thread "main" SASL authentication PLAIN failed: invalid-authzid: 
    at org.jivesoftware.smack.SASLAuthentication.authenticate(SASLAuthentication.java:342)
    at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:243)
    at org.jivesoftware.smack.Connection.login(Connection.java:366)
    at try2.XmppManager.performLogin(XmppManager.java:70)
    at try2.XmppTest.main(XmppTest.java:13)

2 个答案:

答案 0 :(得分:1)

更改两行
config.setSASLAuthenticationEnabled(true);
config.setSecurityMode(ConnectionConfiguration.SecurityMode.enabled);

答案 1 :(得分:1)

您需要在Google帐户中启用“访问安全性较低的应用”,以便进行简单的用户名/密码登录。或者您需要使用用户ID和访问令牌实现OAUTH2身份验证。