继续上一章,这里讲述监听器,在Openfire的开发过程中监听器是一个很重要的部分。在消息的交互工程中,监听器起到了触发事件给开发者。
1.最简单的IQ包监听器
PacketTypeFilter packetTypeFilter = new PacketTypeFilter(IQ.class);
connectManager.getConnection().addPacketListener(new PacketListener() {
public void processPacket(Packet packet) {
System.out.println(packet.toXML());
}
}, packetTypeFilter);// 监听iq包set类型
这里用到smack中的过滤器集
PacketTypeFilter --特定类的packet过滤器。
PacketIDFilter --含有特定packet ID的packet过滤器。
ThreadFilter --含有特定线程ID的消息packet过滤器。
ToContainsFilter --发送到特定地址的packet过滤器。
FromContainsFilter --来自特定地址的packet过滤器。
PacketExtensionFilter --含有特定packet扩充的packet过滤器 filters for s that have a particular extension.
AndFilter --实现两个过滤器的逻辑“与”操作。
OrFilter -- 实现两个过滤器的逻辑“或”操作。
NotFilter --实现一个过滤器的逻辑“非”操作。
不过在平常开发过程中,可以使用smack装门针对一些特殊事件都提供了装门的监听器类和事件给开发者,这样编程可以面向对象,更好的区分出消息的来源。
2.连接的监听器
会提供连接的情况给开发者,有断开连接,异常断开,重新连接。smack在异常断链的时候会自动去重连。
connectManager.getConnection().addConnectionListener(ucConnectionListener);
public class UcConnectionListener implements ConnectionListener {
private Logger log = FileLogger.getLogger();
private UcManager ucManager;
public UcConnectionListener(UcManager ucManager) {
this.ucManager = ucManager;
}
public void connectionClosed() {
log.error("正常断开连接");
ucManager.handleDisConnectEvent(ucManager.getConnectManager().getNode());
if (ucManager.getConnectManager().isConnected()) {
ucManager.disConnect();
ucManager.connect();
if (ucManager.getConnectManager().isConnected()) {
ucManager.handleConnectEvent(ucManager.getConnectManager().getNode());
}
}
}
public void connectionClosedOnError(Exception e) {
log.error("因为异常断开连接", e);
ucManager.handleDisConnectEvent(ucManager.getConnectManager().getNode());
}
public void reconnectingIn(int seconds) {
log.error("重连,秒数:" + seconds);
}
public void reconnectionSuccessful() {
log.error("重连成功");
ucManager.handleConnectEvent(ucManager.getConnectManager().getNode());
}
public void reconnectionFailed(Exception e) {
log.error("重连失败", e);
}
3.监听普通消息
chatManager = connectManager.getConnection().getChatManager();
chatManager.addChatListener(ucChatManagerListener);
import org.apache.log4j.Logger;
import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManagerListener;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.packet.Message;
import com.telthink.util.FileLogger;
import ecc.openfire.uc.UcManager;
public class UcChatManagerListener implements ChatManagerListener {
private Logger log = FileLogger.getLogger();
private UcManager ucManager;
public UcChatManagerListener(UcManager ucManager) {
this.ucManager = ucManager;
}
public void chatCreated(Chat chat, boolean createdLocally) {
chat.addMessageListener(new MessageListener() {
public void processMessage(Chat chat, Message message) {
log.debug("普通聊天,收到消息" + message.toXML());
String from = message.getFrom();
String body = message.getBody();
ucManager.handleChatMessagEvent(from, body);
}
});
}
}
4.监听Roster的好友变化事件
roster = connectManager.getConnection().getRoster();
roster.addRosterListener(ucRosterListener);
import java.util.Collection;
import org.apache.log4j.Logger;
import org.jivesoftware.smack.RosterListener;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.util.StringUtils;
import com.telthink.util.FileLogger;
import ecc.openfire.uc.UcManager;
public class UcRosterListener implements RosterListener {
private Logger log = FileLogger.getLogger();
private UcManager ucManager;
public UcRosterListener(UcManager ucManager) {
this.ucManager = ucManager;
}
public void entriesAdded(Collection<String> addresses) {
log.debug("添加新的好友:" + addresses);
}
public void entriesDeleted(Collection<String> addresses) {
log.debug("删除的好友:" + addresses);
}
public void entriesUpdated(Collection<String> addresses) {
log.debug("变化的好友:" + addresses);
}
public void presenceChanged(Presence presence) {
String from = StringUtils.parseName(presence.getFrom());
String to = StringUtils.parseName(presence.getTo());
String status = presence.getStatus();
Presence.Type type = presence.getType();
log.debug("好友状态变化Presence changed:" + from + ":" + status + ":" + type + ",to:" + to);
if (from.equals(to)) {
ucManager.handleOwnerStatusEvent(from, status, type.toString());
} else {
ucManager.handleFriendStatusEvent(from, status, type.toString());
}
}
}
5.聊天室的各种事件监听器
MultiUserChat muc = new MultiUserChat(connectManager.getConnection(), roomName + "@conference." + connectManager.getDomain());
// 添加消息监听
muc.addMessageListener(new UcGroupChatManagerListener(this));
// 添加其他聊天室人员状态变化监听
muc.addParticipantStatusListener(new UcParticipantStatusListener(this, roomName));
// 添加直接在聊天室的状态变化监听
muc.addUserStatusListener(new UcUserStatusListener(this, roomName));
// 添加邀请被拒绝的监听
muc.addInvitationRejectionListener(new UcInvitationRejectionListener(this, roomName));
import org.apache.log4j.Logger;
import org.jivesoftware.smackx.muc.ParticipantStatusListener;
import com.telthink.util.FileLogger;
import ecc.openfire.uc.UcManager;
public class UcParticipantStatusListener implements ParticipantStatusListener {
private Logger log = FileLogger.getLogger();
private UcManager ucManager;
private String roomName;
public UcParticipantStatusListener(UcManager ucManager, String roomName) {
this.ucManager = ucManager;
this.roomName = roomName;
}
public void adminGranted(String participant) {
log.debug(participant + "授予管理员权限");
ucManager.handleMucParticPantStatusEvent(roomName, participant, "授予管理员权限");
}
public void adminRevoked(String participant) {
log.debug(participant + "移除管理员权限");
ucManager.handleMucParticPantStatusEvent(roomName, participant, "移除管理员权限");
}
public void banned(String participant, String actor, String reason) {
log.debug(participant + "禁止加入房间(拉黑,不知道怎么理解,呵呵)");
ucManager.handleMucParticPantStatusEvent(roomName, participant, "禁止加入房间");
}
public void joined(String participant) {
log.debug(participant + "加入了房间");
ucManager.handleMucParticPantStatusEvent(roomName, participant, "加入房间");
}
public void kicked(String participant, String actor, String reason) {
log.debug(participant + "被踢出房间");
ucManager.handleMucParticPantStatusEvent(roomName, participant, "被踢出房间");
}
public void left(String participant) {
log.debug(participant + "离开房间");
ucManager.handleMucParticPantStatusEvent(roomName, participant, "离开房间");
}
public void membershipGranted(String participant) {
log.debug(participant + "授予成员权限");
ucManager.handleMucParticPantStatusEvent(roomName, participant, "授予成员权限");
}
public void membershipRevoked(String participant) {
log.debug(participant + "成员权限被移除");
ucManager.handleMucParticPantStatusEvent(roomName, participant, "成员权限被移除");
}
public void moderatorGranted(String participant) {
log.debug(participant + "授予主持人权限");
ucManager.handleMucParticPantStatusEvent(roomName, participant, "授予主持人权限");
}
public void moderatorRevoked(String participant) {
log.debug(participant + "移除主持人权限");
ucManager.handleMucParticPantStatusEvent(roomName, participant, "移除主持人权限");
}
public void nicknameChanged(String participant, String newNickname) {
log.debug(participant + "昵称变化");
ucManager.handleMucParticPantStatusEvent(roomName, participant, "昵称变化:" + newNickname);
}
public void ownershipGranted(String participant) {
log.debug(participant + "授予所有者权限");
ucManager.handleMucParticPantStatusEvent(roomName, participant, "授予所有者权限");
}
public void ownershipRevoked(String participant) {
log.debug(participant + "移除所有者权限");
ucManager.handleMucParticPantStatusEvent(roomName, participant, "移除所有者权限");
}
public void voiceGranted(String participant) {
log.debug(participant + "被批准发言了!");
ucManager.handleMucParticPantStatusEvent(roomName, participant, "被批准发言了");
}
public void voiceRevoked(String participant) {
log.debug(participant + "被禁言了!");
ucManager.handleMucParticPantStatusEvent(roomName, participant, "被禁言了");
}
}
监听器的编写的时候,尽量用smack已经有的,只有实在找不到了再去用那些过滤器集来拼装过滤到我们想要的消息。