0

我开发了一个简单的聊天客户端,它可以发送和接收消息以及用户在 2 个用户(userx 和 usery)之间输入 CHatState 通知。在调试窗口中,我看到包含正文或带有聊天状态的数据包。所有数据包都被正确记录。

问题 1:但我的窗口同时显示在聊天(JLabel)中。正因为如此,每当一个用户开始打字时,另一个用户会在他的窗口中看到一条空消息,这实际上是一个包含聊天状态通知的数据包,没有任何正文。我尝试了各种条件,但都失败了。我尝试了以下荒谬的 if 条件,但它显示空数据包。

if (message != null || message.getBody().isEmpty() == false
                    || message.getBody() != null
                    || message.getBody().toString().compareTo("null") == 1
                                            && message.getError() == null)

问题 2:我无法记录发送的通知聊天状态。我的代码如下:

import java.applet.Applet;

public class ChatBoard extends JFrame implements MessageListener {

    private static final long serialVersionUID = 1L;
    private JPanel contentPane;
    static String username, password;
    static XMPPConnection connection;
    private JTextField textField;
    static JLabel board = new JLabel("<html>");
    static Chat chat;
    String message;
    static ChatState status;
    static String to;
    static boolean flag = false;
    JLabel typingStat;

    public class typingStatus implements ChatStateListener {

        @Override
        public void stateChanged(Chat arg0, ChatState arg1) {
            // TODO Auto-generated method stub

            System.out.println(arg1.name());

        }

        @Override
        public void processMessage(Chat arg0, Message arg1) {
            // TODO Auto-generated method stub
            System.out.println(arg1.getBody());

        }

    }

    public void sendChat(String msg) {
        try {
            to = "harsh00008";
            if (username.compareTo(to) == 0)
                to = "usery@xyz";
            else
                to = "userx@xyz";

            chat = connection.getChatManager().createChat(to, this);

            chat.sendMessage(msg);
        } catch (XMPPException e) {

            e.printStackTrace();
        }

    }

    public void changeStatus() {
        // TODO Auto-generated method stub
        if (username.compareTo("harsh00008") == 0)
            chat = connection.getChatManager().createChat("test@prc.p1.im",
                    this);
        else
            chat = connection.getChatManager().createChat(
                    "harsh00008@prc.p1.im", this);

        if (textField.getText().isEmpty() == false && flag == false) {
            try {
                ChatStateManager.getInstance(connection).setCurrentState(
                        ChatState.composing, ChatBoard.chat);

                flag = true;
            } catch (XMPPException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        } else {
            if (textField.getText().isEmpty() == true && flag == true) {
                try {
                    ChatStateManager.getInstance(connection).setCurrentState(
                            ChatState.paused, ChatBoard.chat);

                    flag = false;
                } catch (XMPPException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
            }

        }

    }

    public ChatBoard(String user, String pass) {

        setVisible(true);

        username = user;
        password = pass;

        //JFRAME CREATION CODE OMITTED



        textField.getDocument().addDocumentListener(new DocumentListener() {

            @Override
            public void removeUpdate(DocumentEvent e) {
                // TODO Auto-generated method stub
                changeStatus();

            }

            @Override
            public void insertUpdate(DocumentEvent e) {
                // TODO Auto-generated method stub
                changeStatus();

            }

            @Override
            public void changedUpdate(DocumentEvent e) {
                // TODO Auto-generated method stub
                changeStatus();

            }
        });


        sendButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (textField.getText().isEmpty() == false) {
                    sendChat(textField.getText().toString());
                    board.setText(board.getText() + "<br>me : "
                            + textField.getText());
                    changeStatus();
                    textField.setText("");
                }

            }
        });

        JLabel info = new JLabel("Press Enter or click");

        JButton exit = new JButton("Exit");
        exit.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                setVisible(false);
                WelcomeUser w = new WelcomeUser();
                connection.disconnect();
                w.setVisible(true);
            }
        });


        // ////////////////////////////////////////////

        XMPPConnection.DEBUG_ENABLED = true;

        ConnectionConfiguration config = new ConnectionConfiguration(
                "prc.p1.im", 5222, "prc.p1.im");

        connection = new XMPPConnection(config);

        try {
            connection.connect();

        } catch (XMPPException e) {

            e.printStackTrace();
            System.out.println("Not Connected. Error :" + e.getMessage());
        }

        try {
            connection.login(username, password);

        } catch (XMPPException e) {

            flag = false;

            textField.setVisible(false);
            sendButton.setVisible(false);

            info.setText("Invalid Login!");

            welcomeLabel.setText("Invalid user!");

        }

        connection.getChatManager().addChatListener(new ChatManagerListener() {

            public void chatCreated(final Chat chat,
                    final boolean createdLocally) {

                chat.addMessageListener(new MessageListener() {

                    public void processMessage(Chat chat, final Message message) {
                        try {
                            SwingUtilities.invokeAndWait(new Runnable() {

                                @Override
                                public void run() {

                                    String sender = message.getFrom();
                                    if (username.compareTo("usery") == 0)
                                        sender = "h";
                                    else
                                        sender = "t";

                                    if (message != null
                                            || message.getBody().isEmpty() == false
                                            || message.getBody() != null
                                            || message.getBody().toString()
                                                    .compareTo("null") == 1
                                            && message.getError() == null)
                                        board.setText(board.getText()
                                                + "<br> <font color=red>"
                                                + sender
                                                + " </font>:<font color=black> "
                                                + message.getBody() + "</font>");
                                    URL url = getClass().getResource(
                                            "resource/ultrakill_ultimate.wav");
                                    AudioClip clip = Applet.newAudioClip(url);
                                    clip.play();
                                }
                            });
                        } catch (InvocationTargetException e) {

                            e.printStackTrace();
                        } catch (InterruptedException e) {

                            e.printStackTrace();
                        }

                    }

                });

            }

        });

    }

    @Override
    public void processMessage(Chat arg0, Message arg1) {

        message = arg1.getBody();
        try {
            SwingUtilities.invokeAndWait(new Runnable() {

                @Override
                public void run() {

                }
            });
        } catch (InvocationTargetException e) {

            e.printStackTrace();
        } catch (InterruptedException e) {

            e.printStackTrace();
        }

    }

}

详细信息: 正常的消息包是这样的:

<message id="5KE6T-11" to="usery@xyz" from="userx@xyz/Smack" type="chat">
  <body>hi people</body>
  <thread>fqw5912</thread>
  <active xmlns="http://jabber.org/protocol/chatstates"/>
</message>

聊天状态数据包是这样的:

<message id="IgIbv-13" to="userx@xyz" from="usery@xyz/Smack" type="chat">
  <thread>fqw5913</thread>
  <composing xmlns="http://jabber.org/protocol/chatstates"/>
</message>

截屏 : 在此处输入图像描述

任何意见?

4

3 回答 3

2

1)你是对的,这种情况很荒谬,而且非常错误。

if (message != null || message.getBody().isEmpty() == false
                        || message.getBody() != null
                        || message.getBody().toString().compareTo("null") == 1
                                                && message.getError() == null)

总会有一条消息传入,因此消息永远不会为空,并且此条件将始终通过,这是一件好事,因为如果正文为空,它将抛出 NPE。

你想要做的是:

if (message.getBody() != null)  // getBody() returns null if there is no body so check for empty is unnecessary.

所有其他检查要么是不必要的,要么是多余的。

2)您实际上并没有创建您的 ChatStateListener 或将其注册到 Chat (addMessageListener)。这就是您收不到聊天状态消息的原因。

除了这些之外,您每次发送消息或调用 DocumentListener 时都会创建一个新的聊天。我不认为这是你真正想要的。我认为您想在同一个聊天中发送和接收。

提示和技巧

您的代码在编码标准方面也存在很多明显的问题,因此我还将添加一些提示(请不要认为这是一种侮辱,我只是想帮助您提高 Java 技能)。

if (<boolean condition> == false) // It is already evaluated to true or false

应该

if (!<boolean condition>)

例如

if (message.getBody().isEmpty() == false)

应该

if (!message.getBody().isEmpty())

如果 ( == true)

应该

if (<boolean condition>)
  • 不要把你的内部类和方法混在一起,要么把它们都放在之前或之后。
  • 类名总是以大写字母开头。
  • 不要将静态变量用于基于实例的数据。
于 2012-12-14T19:37:56.980 回答
0

对于第二个问题,你可以参考这个例子来使用 ChatStateListener :

/**
* 
* listening for chat state change from server and change that state in
* model
* 
* */
private class DefaultChatStateListener implements ChatStateListener {

public void stateChanged(Chat user, ChatState event) {
    System.out.println("Getting called here...");
    System.out.println(user.getParticipant() + " is " + event.name());

    String state = event.name();
    TypingStateType typingState = null;
    if (state.equals("active")) {
        typingState = TypingStateType.ACTIVE;
    } else if (state.equals("composing")) {
        typingState = TypingStateType.TYPING;
    } else if (state.equals("paused")) {
        typingState = TypingStateType.PAUSED;
    } else if (state.equals("inactive")) {
        typingState = TypingStateType.INACTIVE;
    } else if (state.equals("gone")) {
        typingState = TypingStateType.GONE;
    }
    controller.typingStateUpdated(genericConnection, typingState, user
            .getParticipant().toString());
}

public void processMessage(Chat arg0, Message arg1) {
    // Do nothing

}

}

使用 DefaultChatStateListener :

lastChat = connection.getChatManager().createChat(
                                    connection.getHost(),
                                    new DefaultChatStateListener());
于 2018-06-28T05:20:27.223 回答
0

这是一个更简单的演示,您可以参考:

import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManager;
import org.jivesoftware.smack.ChatManagerListener;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Message;

public class Test {
    public static void main(String args[]) throws XMPPException {
        ConnectionConfiguration config = new ConnectionConfiguration("127.0.0.1", 5222);
        XMPPConnection connection = new XMPPConnection(config);             
        connection.connect();       
        connection.login("userx", "123456");    
        ChatManager cm = connection.getChatManager();   
        Chat chat = cm.createChat("usery", null);   
        /**
         * add listener
         */
        cm.addChatListener(new ChatManagerListener() {
            @Override
            public void chatCreated(Chat chat, boolean create) {
                chat.addMessageListener(new MessageListener() {
                    @Override
                    public void processMessage(Chat chat, Message msg) {
                        System.out.println(chat.getParticipant() + ":" + msg.getBody());
                    }
                });
            }
        });
        chat.sendMessage("test");   
        while(true);            //keep this chat
        //connection.disconnect();  
    }
}
于 2018-06-28T09:25:07.723 回答