We are integrating MUC in our app for group chat. where we can create group(conference) and adding members. Questions are-
Removed member still getting group messages. What is proper way of remove a member from group?
How to get total members of group (online/offline)?
We are using following methods to remove a members-
public void kickOutRoomMember(String groupJid, String memberNickName) {
MultiUserChat muc;
try {
if (manager == null) {
manager = MultiUserChatManager.getInstanceFor(connection);
}
muc = manager.getMultiUserChat(groupJid);
muc.kickParticipant(memberNickName, "");
} catch (Exception e) {
e.printStackTrace();
}
}
public void removeOutRoomMember(String groupJid, String memberNickName) {
MultiUserChat muc;
try {
if (manager == null) {
manager = MultiUserChatManager.getInstanceFor(connection);
}
muc = manager.getMultiUserChat(groupJid);
muc.banUser(memberNickName, "");
} catch (Exception e) {
e.printStackTrace();
}
}
Theorically you are right.
Just check
If user who invokes banUser has grants to do it
to pass bare
jid and not memberNickName as first parameter in method.
javadoc
muc.banUser("Mickey Mouse", ""); //does not works
muc.banUser("mickeymouse#server","") // will works
Install "Rest API" plugin.
Rest API plugin provides all the API related group. Create Or delete a group, Add or remove a member from a group, get all members of group etc..
Related
I can create group chat room successfully XMPP(smack). I have added
invitation listener, but never called. Does anyone know how to do it?
Using:
XMPP
Smack 4.2
Openfire server
Send Invitation code:
muc.invite(userId +"#" +XMPP.getInstance().HOST + "/Smack", "Meet me in this excellent room");
Invitation listener code:
MultiUserChatManager manager = MultiUserChatManager.getInstanceFor(connection);
manager.addInvitationListener(new InvitationListener() {
#Override
public void invitationReceived(XMPPConnection xmppConnection, MultiUserChat muc, String inviter, String reason, String password, Message message) {
try {
muc.join(nickname);
} catch (SmackException.NoResponseException e) {
e.printStackTrace();
} catch (XMPPException.XMPPErrorException e) {
e.printStackTrace();
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
}
}
});
Probably you have an issue about RESOURCE.
When you send an invitation to a certain JID, you might omit resource part or the message will be sent only to specified resource.
JID it's composed in following way:
user#serverdomain/resource
With this invitation, you are inviting only user using "Smack" as Resource.
Resource it's configurated in AbstractXMPPConnection object or in login phase
XMPPTCPConnectionConfiguration.builder()
.setServiceName(serverName)
.setHost(server)
.setPort(port)
.setResource( RESOURCE_IDENTIFIER)
.build();
connection = new XMPPTCPConnection(config);
connection.login(username, password, RESOURCE_IDENTIFIER);
So, probably, you declared as your resource identificator (just an arbitrary String) not "Smack" but "Spark" o something else or left default one.
Just omit Resource part (or fix with correct one, but I suggest to omit)
muc.invite(userId +"#" +XMPP.getInstance().HOST, "Meet me in this excellent room");
Of course, userId must exist and HOST it's the valid one
Hey i am developing Chat Application using XMPP Smack Library. Recently i am working on Group Chat While sending Group message some message will be drop so receiver wouldn't receives message from the sender side. it will gives me 400 bad request.
it is working sometimes. and sometimes not work
here i found this kind of message in 400 bad request.
<?xml version="1.0" encoding="UTF-8"?>
<message to="156#abc.com/Android" id="nXlV6-1144" type="error" from="24#confrence.abc.com/156#abc.com.com">
<received xmlns="urn:xmpp:receipts" id="nXlV6-1142" />
<error code="400" type="modify">
<bad-request xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" />
</error>
</message>
if successfully send message it will give this kind of message.
<?xml version="1.0" encoding="UTF-8"?>
<message to="156#abc.com/Android" id="nXlV6-1411" type="groupchat" from="24#conference.abc.com/156#abc.com">
<body>eyu4u4</body>
<chatDetail xmlns="jabber:x:oob">
<UID>156</UID>
<time>04:20 PM</time>
<user_icon>24_group_icon.jpg</user_icon>
<SentTime>1474368652960</SentTime>
<USERName>vasudev89</USERName>
<user_name>cryan</user_name>
<message>eyu4u4</message>
<type>group</type>
<phone_number>24</phone_number>
</chatDetail>
<request xmlns="urn:xmpp:receipts" />
</message>
how i can send message persistently? Any idea?
Thank You in Advance.
here is my code sending muc message:
public boolean sendGroupMessage(Message message, String strGroupID) {
DeliveryReceiptRequest.addTo(message);
try {
Log.i(TAG, "sendGroupMessage");
//Log.i("JOIN MUC","To join group chat: " + groupChat.getClassId());
// Get the MultiUserChatManager
MultiUserChatManager manager = MultiUserChatManager.getInstanceFor(AbstractXMPPConnection);
// Create a MultiUserChat using an XMPPConnection for a room
MultiUserChat muc = manager.getMultiUserChat(strGroupID + AppWSConstants.XMPP_JID_GROUP_CHAT_SUFFIX);
muc.sendMessage(message);
return true;
} catch (NotConnectedException e) {
e.printStackTrace();
}
return false;
}
#LearnPainLess, follow these steps to solve group chat issue
-when creating groups, save the jid of group in the database, like "somegroup#conference.{domain}.com"
-create background task for creating xmpp connection (this way it will always be connected)
-after logging in to xmpp, get the group names from the database and connect to them
also, in openfire, Group Chat > Group Chat Settings > Edit Icon > Default Room Settings > Check "Make Room Persistant"
also, in other settings > Never kick idle users
I have an XmppBase class where i put all my xmpp code
All listeners in seperate folder
Connection is stored in static variable and i retrive it using
Utils.getConnection()
// this function m calling from background service and everywhere if not connectect to xmpp
public static XMPPConnection CreateXmppConnection() {
if (Utils.getConnection() == null) {
try {
Boolean isConnected = new XmppAsync(mUsername, mPassword,context).execute().get();
if (isConnected && Utils.getConnection() != null) {
RegisterConnListeners(Utils.getConnection());
updateMyProfileImg();
// connect to all groups
DBAdapter adapter = new DBAdapter(context);
adapter.openForRead();
List<UserDetail> groups = new ArrayList<>();
adapter.addAllGroups(groups);
adapter.addPastChatGroups(groups);
adapter.close();
for(UserDetail g : groups)
{
CreateXmppMUCSession(g.getGroupTemp());
}
return Utils.getConnection();
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
return null;
} else
return Utils.getConnection();
}
// get muc chat manager
public static MultiUserChatManager getMucManager() {
if(mucManager != null)
return mucManager;
if (Utils.getConnection() != null) {
return MultiUserChatManager.getInstanceFor(Utils.getConnection());
} else {
if (CreateXmppConnection() != null)
return MultiUserChatManager.getInstanceFor(Utils.getConnection());
else {
Log.v("error", "Some Error Occured");
Toast.makeText(context, "Cant Connect to Xmpp", Toast.LENGTH_SHORT).show();
return null;
}
}
}
// create muc session and m passing group name - call when you open chat page
public static void CreateXmppMUCSession(String gName)
{
RegisterGroupChatListeners(gName);
}
// connect to muc if not already connected
public static void RegisterGroupChatListeners(String groupName)
{
try {
mStateManager = getChatStateManager();
multiUserChat = getMUC(groupName);
// if(multiUserChat != null) {
multiUserChat.addMessageListener(new MyMUCMessageListener());
try {
if (!multiUserChat.isJoined()) {
DiscussionHistory discussionHistory = new DiscussionHistory();
discussionHistory.setMaxStanzas(0);
multiUserChat.join(new MyPrefrence(context).getUsername().split("#")[0], "123",
discussionHistory, SmackConfiguration.getDefaultPacketReplyTimeout());
}
} catch (SmackException.NoResponseException e) {
e.printStackTrace();
} catch (XMPPException.XMPPErrorException e) {
e.printStackTrace();
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
}
// }
}
catch (Exception ex)
{
//
}
}
// get muc
public static MultiUserChat getMUC(String groupName)
{
// Log.v("nick",multiUserChat.getNickname() + " , g = " + groupName);
// if(multiUserChat != null && multiUserChat.getRoom().contains(groupName))
// {
// return multiUserChat;
// }
if (Utils.getConnection() != null) {
MultiUserChatManager chatManager = getMucManager();
if (chatManager != null) {
return chatManager.getMultiUserChat(groupName);
} else {
Toast.makeText(context, "Cannot create Chat", Toast.LENGTH_SHORT).show();
return null;
}
} else {
if (CreateXmppConnection() != null) {
MultiUserChatManager chatManager = getMucManager();
if (chatManager != null) {
return chatManager.getMultiUserChat(groupName);
} else {
Toast.makeText(context, "Cannot create Chat", Toast.LENGTH_SHORT).show();
return null;
}
}
else {
Toast.makeText(context, "Cannot create Chat", Toast.LENGTH_SHORT).show();
return null;
}
}
}
and whenever i want to send message i just call this
public static Boolean sendMUCChatMsg(Message msg)
{
if(multiUserChat != null)
try {
multiUserChat.sendMessage(msg);
return true;
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
}
return false;
}
Sorry if it looks clumpsy, if I missed any function there let me know, but this is working code which i am using
try this,
I modified your last function
static MultiUserChat multiUserChat;
// call this function when you open the chat window
private void CreateGroupConnection(String strGroupID ) {
// Get the MultiUserChatManager
MultiUserChatManager manager = MultiUserChatManager.getInstanceFor(AbstractXMPPConnection);
// Create a MultiUserChat using an XMPPConnection for a room
MultiUserChat multiUserChat = manager.getMultiUserChat(strGroupID + AppWSConstants.XMPP_JID_GROUP_CHAT_SUFFIX);
return multiUserChat;
}
// whenever sending message from chat call this
publilc static void sendMucMessage(Message message){
if(multiUserChat != null)
multiUserChat.sendMessage(message);
}
I am working on "seen and delivered" in MUC and facing with this issue when replying back with the same packet id, still testing but I think in your case you should move your xmpp connection to background service and after connecting to xmpp on device launch up, connect to all the muc in your database. This way you will always be connected to groups.
cause : according to me, when the other user is not connected to the muc and you send a message or when you reply to the group with the same packet id.
Note: I am using multiuserchat.sendmessage to send group message and chat.sendmessage to send message to single user
SMACK 4.1
** update **
I fixed it by creating new packet instead of modifying the one i am receiving
here is the packet
Message msgg = new Message();
msgg.setBody(message.getPacketID());
msgg.setSubject(MessageModel.CHAT_STATUS_SEEN + "");
XmppBase.sendMUCChatMsg(msgg);
in your case, try with simple packet first. if all works well, then add extension one by one and see where you get the error, Thanks
Is any way in xmpp that i get offline message of MultiUserChat, when my user login and join room.
I want implement group chat like WhatsApp, Is any other way to implement this please suggest
Thanks in advance
At least in ejjaberd when you enter the chat group, you have to enter your last timestamp, given that timestamp you will receive the messages from that moment.
Save the timestamp from your last message, and when you enter to your room, like the following:
MultiUserChat muc = new MultiUserChat(mConnection, room_name);
Log.d(TAG, "JOINING => " + room_name);
DiscussionHistory history = new DiscussionHistory();
if (mLastMessageDate == null)
history.setMaxStanzas(300);
else
history.setSince(mLastMessageDate); //timestamp from your last message
muc.join(mNickName, null, history,
SmackConfiguration.getDefaultPacketReplyTimeout());
Hope it helps
First declare a MultiUserChat this way
private static MultiUserChat muc = null;
then in your oncreate method instantiate it this way
muc = new MultiUserChat(CONNECTION, room);
try {
muc.join(USERJID);
} catch (SmackException.NoResponseException e) {
e.printStackTrace();
} catch (XMPPException.XMPPErrorException e) {
e.printStackTrace();
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
}
and call this method in the beginning of your app
void setMessageListner() {
muc.addMessageListener(new PacketListener() {
#Override
public void processPacket(Packet packet) throws SmackException.NotConnectedException {
Message msg = (Message)packet;
msg.setSubject(msg,getBody);
Logger.i("Received message : "+msg.getBody()+" From "+msg.getSubject());
});
}
this way whenever the user get into a GroupChat he will get the last Messages of the group
Am using the Xabber open source project and am able to create a new group, But it always says: This room is locked from entry until configuration is confirmed. I tried to set a default configuration but it throws me exception: 401 not authorized. Whats exactly the problem.
final MultiUserChat multiUserChat;
try {
multiUserChat = new MultiUserChat(xmppConnection, room);
// CHANAKYA: set default config for the MUC
// Send an empty room configuration form which indicates that we want
// an instant room
try {
multiUserChat.sendConfigurationForm(new Form(Form.TYPE_SUBMIT));
} catch (XMPPException e) {
e.printStackTrace();
}
I was also facing the same error. Here I modified the code and it's work for me.
Error 401 is not authorized error when we are calling the any getConfigurationForm(), without joining it.
multiUserChat.join(nickname, password);
setConfig(multiUserChat); // Here I am calling submit form
private void setConfig(MultiUserChat multiUserChat) {
try {
Form form = multiUserChat.getConfigurationForm();
Form submitForm = form.createAnswerForm();
for (Iterator<FormField> fields = submitForm.getFields(); fields
.hasNext();) {
FormField field = (FormField) fields.next();
if (!FormField.Type.hidden.equals(field.getType())
&& field.getVariable() != null) {
submitForm.setDefaultAnswer(field.getVariable());
}
}
submitForm.setAnswer("muc#roomconfig_publicroom", true);
submitForm.setAnswer("muc#roomconfig_persistentroom", true);
multiUserChat.sendConfigurationForm(submitForm);
} catch (Exception e) {
e.printStackTrace();
}
}
And now I am able to successfully submit the form without any exception. Hope this will work for you.
You must have permissions to set the configuration. This can usually be changed in the server settings. If you have Openfire for example you should go to Group Chat>Group chat settings>Click your Group Chat service>Room Creation Permissions or Administrators.
You are probably unable to change this client side, it's only possible if you have access to the server you are trying to connect to.
I am new to the use of smack library and making one chatting application. I have made upto much extent and at this step i want to ask two questions.
when i add a friend the friend got added in my list but there is not any notification sent to the FRIEND whom i have added, How to achieve the same. I have added the code below.
The second thing i want to ask is that how can I check whether the user which I am going to add is a part or member of the app or not ( mean it is on the server or not). So that the user who is not registered to the app should not be added in the friends list.
here is the code
public static boolean addFriend(String jid) {
String nickname = null;
nickname = StringUtils.parseBareAddress(jid);
RosterEntry entry4 = roster.getEntry("samsad");
if (!roster.contains(jid)) {
try {
Presence subscribe = new Presence(Presence.Type.subscribe);
subscribe.setTo(jid);
connection.sendPacket(subscribe);
roster.createEntry(jid, nickname, null);
// Send a roster entry (any) to user2
RosterExchangeManager REM = new RosterExchangeManager(connection);
REM.send(entry4, jid);
return true;
} catch (XMPPException e) {
System.err.println("Error in adding friend");
return false;
}
} else {
return false;
}
}
Roster Exchange manager running in the service in background
/**Remotr Exchange Manager*/
RosterExchangeManager rem = new RosterExchangeManager(connection);
// Create a RosterExchangeListener that will iterate over the received roster entries
RosterExchangeListener rosterExchangeListener = new RosterExchangeListener() {
public void entriesReceived(String from, Iterator remoteRosterEntries) {
notification("Receive==4");
while (remoteRosterEntries.hasNext()) {
try {
// Get the received entry
RemoteRosterEntry remoteRosterEntry = (RemoteRosterEntry) remoteRosterEntries.next();
// Display the remote entry on the console
System.out.println(remoteRosterEntry);
// Add the entry to the user2's roster
roster.createEntry(
remoteRosterEntry.getUser(),
remoteRosterEntry.getName(),
remoteRosterEntry.getGroupArrayNames());
notification("Receive==1");
}
catch (XMPPException e) {
e.printStackTrace();
}
}
}
};
rem.addRosterListener(rosterExchangeListener);
}
else{
showToast("Connection lost-",0);
}
}
1, The problem is you must register a PacketListener for Presence.Type.subscribe before you connect to server. All the process of add and accept friend i answered in here
2, You can use UserSearch class to search for a specific user and if user is not found on server then you can assume that user is not registered on server.