Java 关闭聊天室后将打印消息
我正在开发一个简单的Java 关闭聊天室后将打印消息,java,ejabberd,smack,system.out,Java,Ejabberd,Smack,System.out,我正在开发一个简单的ejabberd聊天工具。 我想为发送方和接收方制作一个程序。这个想法是这样的: 运行该程序时,会询问用户您是想与某人聊天(即想成为发送者)还是等待某人发起聊天(即想成为接收者) 如果您选择发件人,它将询问收件人地址 然后,它将启动与接收器的聊天 相同的代码为: import java.util.*; import java.io.*; import java.lang.*; import org.jivesoftware.smack.Chat; import org.
ejabberd
聊天工具。我想为发送方和接收方制作一个程序。这个想法是这样的:
- 运行该程序时,会询问用户您是想与某人聊天(即想成为发送者)还是等待某人发起聊天(即想成为接收者)
- 如果您选择发件人,它将询问收件人地址
- 然后,它将启动与接收器的聊天
import java.util.*;
import java.io.*;
import java.lang.*;
import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.ChatManager;
import org.jivesoftware.smack.ChatManagerListener;
public class Client implements MessageListener{
static XMPPConnection connection;
public void login(String userName, String password) throws XMPPException {
ConnectionConfiguration config = new ConnectionConfiguration("10.100.99.107",5222,"localhost");
connection = new XMPPConnection(config);
connection.connect();
connection.login(userName, password);
}
public Chat createChat(String to) throws XMPPException{
return connection.getChatManager().createChat(to, this);
}
public void sendMessage(Chat chat, String message) throws XMPPException {
chat.sendMessage(message);
}
public void disconnect() {
connection.disconnect();
}
public void processMessage(Chat chat, Message message) {
System.out.println("Here");
if(message.getType() == Message.Type.chat)
System.out.println(chat.getParticipant() + " says: " + message.getBody());
}
public static void main(String args[]) throws XMPPException, IOException, InterruptedException {
// declare variables
final Client client = new Client();
final BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// turn on the enhanced debugger
// XMPPConnection.DEBUG_ENABLED = true;
// Enter your login information here
System.out.println("Login information:\nusername: ");
String login_username = br.readLine();
System.out.print("password: ");
String login_pass = br.readLine();
client.login(login_username, login_pass);
if(connection.isAuthenticated()==true){
System.out.println("\n"+login_username+" :Successfully logged in");
final Chat chat;
System.out.println("Do you want to talk? (y/n)");
String choice = br.readLine();
if( choice.equals("y")){
//Sender's code
System.out.println("Whom do you want to talk to? - Type contacts full email address:");
chat = client.createChat(br.readLine());
chat.addMessageListener(client);
System.out.println("Enter your message in the console (Type 'quit' to exit.):\n");
String msg;
while( !(msg=br.readLine()).equals("quit")) {
client.sendMessage(chat, msg);
}
}else if(choice.equals("n")){
//Reciever's code
ChatManager chatmanager = connection.getChatManager();
chatmanager.addChatListener( new ChatManagerListener() {
@Override
public void chatCreated(Chat chatReceived, boolean createdLocally)
{
System.out.println("Chat Created");
chatReceived.addMessageListener(client);
System.out.println("Enter your message in the console (Type 'quit' to exit.):\n");
String msg;
try {
while( !(msg=br.readLine()).equals("quit")) {
client.sendMessage(chatReceived, msg);
}
}
catch(Exception e){
System.out.println(e.getMessage());
}
}
});
//put receiver on waiting
while (true) {
Thread.sleep(200);
}
}else{
System.out.println("Wrong Input");
}
client.disconnect();
System.exit(0);
}
}
}
错误:
当发送方发送消息时,接收方接收消息(我通过调试进行了检查),但不显示消息。当我退出接收端的聊天时,它会立即打印所有消息。只有当发送方发送消息时,接收方才会发生这种情况。我不确定我在哪里阻塞了输出流。问题应该出在我对
中断
或等待while循环的理解上
问题在于您的读取循环在回调函数中的位置
如果你看一下,你会发现每次聊天都有一个线程。在接收方代码中,chatCreated
回调将在该线程上发生。然后你坐在那里读stdin的文章来锁定线程。您看到的是,当您退出时,processMessage
回调终于可以自由启动,您可以收到您的消息
您需要在chatCreated
中派生一个读卡器线程来处理所有输入。然后您立即从回调返回。事实上,您应该始终创建一个单独的线程来阻止输入。这是正确的方法,即使在像这样的玩具问题上,你也会以奇怪的方式被绊倒,所以你最好养成一个习惯
其他几点建议:
- 不要调用
退出。这会终止JVM,并且某些代码可能不会完全关闭。只需从系统。退出(0)
main
- 你的
循环很难看。一个更好的方法是将主线程块放在一个线程上,并让读线程在获得“退出”时释放锁。或者在读卡器线程上调用while(true){Thread.sleep(200);}
Thread#join()