- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试为 Android 开发 XMPP 聊天客户端(使用连接到 C#/Unity 的 Java)。我的 Java -> Unity/C# 连接运行良好。我还下载了 Asmack,可以生成一个库和我的包装类,用于初始化与 OpenFire XMPP 服务器的连接。但是,我似乎无法发送或接收状态。我可以登录、注册新用户并填充他们的花名册、发送消息,但不能发送任何状态。
该代码会自动注册以前从未使用过该应用程序的用户。它还使用预设的 friend 列表,并自动将这些 friend 填充到花名册中。
代码如下(抱歉所有调试行,使用Unity时不能使用断点):
public class ASmackWrapper
{
private XMPPConnection connection;
private String[] friends;
private static final String eventClass = "ASmackEventListener";
private static ASmackWrapper wrapper;
public static ASmackWrapper instance()
{
System.out.println("instancecreator of ASmackWrapper 1!");
if (wrapper == null)
wrapper = new ASmackWrapper();
return wrapper;
}
public ASmackWrapper()
{
System.out.println("constructor of ASmackWrapper");
}
public boolean tryToRegister(String user, String pass){
AccountManager acManager = connection.getAccountManager();
try {
Map<String, String> attributes = new HashMap<String,String>();
attributes.put("email", "MY email");
acManager.createAccount(user, pass,attributes);
} catch (XMPPException e) {
System.out.println("cant autoregister user "+ user +" ... with pass: "+pass+" on server. error:" + e.getLocalizedMessage());
if (e.getLocalizedMessage().contains("conflict"))
return false; // Wrong password, since there is already an account with that id!
return false;
}
return true;
}
public void setFriends(String[] _friends) {
friends = _friends;
}
public void start(String host, String user, String pass)
{
System.out.println("Java: openConenction host:"+host);
ConnectionConfiguration cc = new ConnectionConfiguration(host,5222);
//cc.setSendPresence(true);
this.connection = new XMPPConnection(cc);
Connection.DEBUG_ENABLED = true;
try {
this.connection.connect();
} catch (XMPPException e) {
System.out.println("Error connecting to server");
return;
}
if(!this.connection.isConnected()) {
System.out.println("Java: is not connected");
onError("Connection failed");
return;
}
boolean loginStatus = login(user, pass);
if (!loginStatus) {
onError("Login Failed");
return;
}
RosterListener rl = new RosterListener() {
public void entriesAdded(Collection<String> addresses) {}
public void entriesUpdated(Collection<String> addresses) {}
public void entriesDeleted(Collection<String> addresses) {}
public void presenceChanged(Presence presence) {
System.out.println("presence changed!" + presence.getFrom() + " "+presence.getStatus());
onPresence(presence);
}
};
if (connection.getRoster() != null) {
connection.getRoster().setSubscriptionMode(Roster.SubscriptionMode.accept_all);
System.out.println("7");
connection.getRoster().addRosterListener(rl);
}
onAuthenticate("");
System.out.println("10");
//Set presence to online!
Presence presence = new Presence(Presence.Type.available);
presence.setStatus("Online, Programmatically!");
presence.setPriority(24);
presence.setMode(Presence.Mode.available);
connection.sendPacket(presence);
}
private void addFriends() throws Exception {
if (friends == null) {
System.out.println("No friends to add");
return;
}
System.out.println("Number of friends to add: "+friends.length);
for (int i = 0;i<friends.length;i++) {
System.out.println("Create user in roster: "+friends[i]);
connection.getRoster().createEntry("fb"+friends[i], "No name_",null);
}
}
private boolean login(String jid, String password) {
System.out.println("1");
boolean isLoggedIn=true;
try {
this.connection.login(jid, password);
} catch (XMPPException e) {
isLoggedIn=false;
}
System.out.println("2");
if(!isLoggedIn) {
boolean isRegistred = tryToRegister(jid,password);
if (isRegistred) {
connection.disconnect();
try {
connection.connect();
connection.login(jid, password);
} catch (XMPPException e) {
onError("Could not connect and login after registring");
return false;
}
} else {
return false;
}
}
try {
addFriends();
} catch (Exception e) {
onError("Could not add friends to roster");
}
ChatManager chatmanager = connection.getChatManager();
chatmanager.addChatListener(new ChatManagerListener()
{
public void chatCreated(final Chat chat, final boolean createdLocally)
{
System.out.println("OK Chat created!");
chat.addMessageListener(new MessageListener()
{
public void processMessage(Chat chat, Message message)
{
onMessage(chat, message);
}
});
}
});
return true;
}
public void sendMessage(String rec, String message) {
System.out.println("sendMessage(string,string) to host :"+connection.getHost());
Chat chat = connection.getChatManager().createChat(rec+"@"+connection.getHost(), new MessageListener() {
public void processMessage(Chat chat, Message message) {
// Print out any messages we get back to standard out.
System.out.println("Probably an error, since we got a instant reply on sent message. Received message body: " + message.getBody() + " from:"+message.getFrom() + " to:"+message.getTo());
}
});
try {
chat.sendMessage(message);
System.out.println("Message sent");
} catch (XMPPException e) {
System.out.println("Error sending message: "+e.toString());
e.printStackTrace();
}
}
public void logout () {
System.out.println("Login out...");
connection.disconnect();
}
public void getOnlineFriends() {
Roster roster = connection.getRoster();
Collection<RosterEntry> entries = roster.getEntries();
for(RosterEntry rosterEntry: entries) {
String user = rosterEntry.getUser();
Presence presence = roster.getPresence(user);
System.out.println("Presence : "+presence);
System.out.println("Presence type: "+presence.getType());
System.out.println("Presence mode: "+presence.getMode());
}
//Set presence to online!
Presence presence = new Presence(Presence.Type.available);
presence.setStatus("Online, Programmatically!");
presence.setPriority(24);
presence.setMode(Presence.Mode.available);
connection.sendPacket(presence);
}
private void onMessage(Chat chat, Message message) {
String m = ("Received message: " + (message != null ? message.getBody() : "NULL"));
System.out.println(m);
UnityPlayer.UnitySendMessage(eventClass, "Message", m);
}
private void onError(String message) {
UnityPlayer.UnitySendMessage(eventClass, "Error", message);
}
private void onAuthenticate(String message) {
UnityPlayer.UnitySendMessage(eventClass, "Authenticate", message);
}
private void onPresence(Presence presence) {
String user = presence.getFrom();
if (presence.getType() == Presence.Type.available)
UnityPlayer.UnitySendMessage(eventClass, "Online", user);
else
UnityPlayer.UnitySendMessage(eventClass, "Offline", user);
System.out.println("Java: Presence changed, from:" +presence.getFrom() + " type:"+presence.getType() + " toString:"+presence.toString());
}
}
在线状态检查有两种方式,一种是设置在线状态监听器,另一种是在登录后获取状态。此 SO 页面建议等待 5 秒后再获取前缀:Unable to get presence of roster by using smack, openfire我也尝试过通过按钮调用 getOnlineFriends,登录后超过 5 秒。监听器永远不会被调用。它只会在登录后触发一次,对于名册上存在 = null 的每个人触发一次。
编辑:在 Asmack 上打开 Debug模式后,我看到以下对我的状态发送消息的回复:
SENT <presence id="3sG7l-11"><status>Online, Programmatically!</status><priority>24</priority></presence>
RCV <presence id="6s7BX-5" to="787122012@xxx.tripnet.se/Smack" from="10000063946242" type="error">
<error code="404" type="cancel">
<remote-server-not-found xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
</error></presence>
服务器日志:
org.jivesoftware.openfire.nio.ConnectionHandler - Closing connection due to error while processing message:
<iq id="566-4" type="error" from="xxx.tripnet.se/f55aea72" to="xxx.tripnet.se">
<error /><error type="cancel" code="501">
<feature-not-implemented xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" /></error>
<ping xmlns="urn:xmpp:ping" /></iq>
java.lang.IllegalArgumentException: IQ must be of type 'set' or 'get'. Original IQ:
<iq id="566-4" type="error" from="xxx.tripnet.se/f55aea72" to="xxx.tripnet.se">
<error/><error type="cancel" code="501">
<feature-not-implemented xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/></error>
<ping xmlns="urn:xmpp:ping"/></iq>
at org.xmpp.packet.IQ.createResultIQ(IQ.java:384)
我还尝试将 setSendPresence = true 传递给 connect() 中传递的连接配置,但没有区别。
我还尝试在 OpenFire 服务器中手动将两个用户的订阅模式设置为“两者”(从“无”),但没有效果。
最佳答案
成功了!可能是因为我在花名册列表中的 jid 上没有使用正确的格式。正确的格式必须是 user@myserver.se,而不仅仅是 user。
关于java - 无法使用 ASmack 发送或接收状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12248512/
我正在使用 Asmack API 在 android 上创建一个多用户聊天室,我想通过使用获取所有托管的房间 MultiUserChat.getHostedRooms(connection, serv
我正在基于 asmack 库在 Android 上开发聊天应用程序。我创建了 1 个用户并在好友列表中添加了 3 个 friend 。当我使用名册显示好友列表时。我无法在好友列表中获取所有用户,只有
我正在尝试为我的聊天应用程序实现离线文件扩展。我正在使用 PacketExtension 和 EmbeddedExtensionProvider 添加和解析自定义扩展。我可以看到在发送消息时添加了值和
基本上我有一个运行整个项目的主类。该代码运行良好,但一旦应用程序失去焦点,它就会变得不活动。我想知道我将如何让它成为一项服务。一个会在启动时启动的。 该应用程序将是一种用于通知的单向消息系统。即 De
我有一个 aSmack 实现的应用程序,(8-4.0.5),据我们所知,它有一个内部重新连接管理,但它并不令人满意,因为有时我们应该等待 5 分钟才能重新连接,而我们现在知道这是一个这样做的好时机,所
我正在我正在开发的 Android 应用程序中使用 asmack xmpp 客户端,并希望使用压缩。我找到了 setCompressionEnabled,但当我尝试它时,它告诉我我需要 smackx。
我正在使用 asmack 库,并面临多用户聊天请求的问题。 发送 session 请求时,它不会进入邀请监听器,尽管相同的代码在 java 中使用 smack 库。 调试时它显示我正在接收消息,但没有
我完全按照答案建议的操作( Asmack not loading VCard ),但它仍然不起作用。 DEBUG 输出显示 Smack 收到带有 VCard 信息的数据包,但随后在 https://g
我正在努力让 aSmack 在我的项目中发挥作用。在 eclipse 中创建一个标准项目,添加 jar 以构建路径/库。开始使用 XMPP 类,但我不确定我是否应该做其他事情来正确设置项目(稍后再说)
我正在开发 Android 平台上的聊天应用程序。我想通过 xmpp 库中的 PubSub 共享我的当前位置。谁能给我代码,说明如何使用 pubsub API。 提前致谢。 最佳答案 Smack do
我建立了一个基于 aSmack 的应用程序,显然所有关于连接的东西都在一个服务中运行,所以保持它的连接是非常重要的,因为我们知道在后台运行的服务可能会在手机资源不足时被杀死(通常是 Ram),因此在服
我在我的 android 应用程序中使用 aSmack 库进行群聊,我的问题是有时当连接丢失时,ReconnectionManager 无法重新连接并出现此错误: java.lang.IllegalT
我在通过 XMPP 发送图像时遇到了一个问题。下面是我完成的代码 fragment 。我不知道代码有什么问题。 Message msg = new Message(emailId, Message.T
我不熟悉 smack 库的使用和制作一个聊天应用程序。当我添加 friend 时,从这段代码..,它有效。 public void Addcontact() { Roster.setDefaul
我正在使用 Asmack 的二进制版本(我会尽快构建它,因为我第一次尝试时遇到了问题)。我还设置了自己的 ejabberd 服务器。 当我尝试加载一些联系人 VCard 时,服务器返回信息但 Asma
我尝试用 asmack 编写一个 android 演示。存在名为 “host-unknown” 的错误。我该如何解决? 这是我在 LogCat 中看到的: 03-16 08:31:10.671: I/
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
我遇到了 XML 节中缺少属性的问题。根据服务器端的日志文件,我可以确认属性是从客户端发送到服务器的。此外,当服务器将 XML 节传递给接收者时,该属性也存在(仍然基于服务器端的日志文件)。问题是,当
我无法使用 asmack 接收文件,但我能够发送文件。下面是接收文件的代码,请告诉我我做错了什么 ServiceDiscoveryManager serv= new Ser
我正在使用 openfire 和 asmack 库。我正在 android 聊天应用程序中实现在线 和离线 按钮。如何将我的在线状态设置为“不可用”。 注意:我不想使用connection.disco
我是一名优秀的程序员,十分优秀!