presenceupdatehandler.java
来自「基于Jabber协议的即时消息服务器」· Java 代码 · 共 474 行 · 第 1/2 页
JAVA
474 行
* <p/>
* Is there a safe way to cache the query results while maintaining
* integrity with roster changes?
*
* @param update The update to broadcast
*/
private void broadcastUpdate(Presence update) throws PacketException {
if (update.getFrom() == null) {
return;
}
if (localServer.isLocal(update.getFrom())) {
// Do nothing if roster service is disabled
if (!RosterManager.isRosterServiceEnabled()) {
return;
}
// Local updates can simply run through the roster of the local user
String name = update.getFrom().getNode();
try {
if (name != null && !"".equals(name)) {
Roster roster = rosterManager.getRoster(name);
roster.broadcastPresence(update);
}
}
catch (UserNotFoundException e) {
Log.warn("Presence being sent from unknown user " + name, e);
}
catch (PacketException e) {
Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
}
}
else {
// Foreign updates will do a reverse lookup of entries in rosters
// on the server
Log.warn("Presence requested from server "
+ localServer.getServerInfo().getName()
+ " by unknown user: " + update.getFrom());
/*
Connection con = null;
PreparedStatement pstmt = null;
try {
pstmt = con.prepareStatement(GET_ROSTER_SUBS);
pstmt.setString(1, update.getSender().toBareString().toLowerCase());
ResultSet rs = pstmt.executeQuery();
while (rs.next()){
long userID = rs.getLong(1);
try {
User user = server.getUserManager().getUser(userID);
update.setRecipient(user.getAddress());
server.getSessionManager().userBroadcast(user.getUsername(),
update.getPacket());
} catch (UserNotFoundException e) {
Log.error(LocaleUtils.getLocalizedString("admin.error"),e);
} catch (UnauthorizedException e) {
Log.error(LocaleUtils.getLocalizedString("admin.error"),e);
}
}
}
catch (SQLException e) {
Log.error(LocaleUtils.getLocalizedString("admin.error"),e);
}
*/
}
}
/**
* Notification method sent to this handler when a user has sent a directed
* presence to an entity. If the sender of the presence is local (to this server)
* and the target entity does not belong to the user's roster then update the
* registry of sent directed presences by the user.
*
* @param update the directed Presence sent by the user to an entity.
* @param handler the handler that routed the presence to the entity.
* @param jid the jid that the handler has processed
*/
public void directedPresenceSent(Presence update, ChannelHandler handler, String jid) {
if (update.getFrom() == null) {
return;
}
if (localServer.isLocal(update.getFrom())) {
boolean keepTrack = false;
WeakHashMap<ChannelHandler, Set<String>> map;
String name = update.getFrom().getNode();
if (name != null && !"".equals(name)) {
// Keep track of all directed presences if roster service is disabled
if (!RosterManager.isRosterServiceEnabled()) {
keepTrack = true;
}
else {
try {
Roster roster = rosterManager.getRoster(name);
// If the directed presence was sent to an entity that is not in the user's
// roster, keep a registry of this so that when the user goes offline we
// will be able to send the unavailable presence to the entity
RosterItem rosterItem = null;
try {
rosterItem = roster.getRosterItem(update.getTo());
}
catch (UserNotFoundException e) {}
if (rosterItem == null ||
RosterItem.SUB_NONE == rosterItem.getSubStatus() ||
RosterItem.SUB_TO == rosterItem.getSubStatus()) {
keepTrack = true;
}
}
catch (UserNotFoundException e) {
Log.warn("Presence being sent from unknown user " + name, e);
}
catch (PacketException e) {
Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
}
}
}
else if (update.getFrom().getResource() != null){
// Keep always track of anonymous users directed presences
keepTrack = true;
}
if (keepTrack) {
map = directedPresences.get(update.getFrom().toString());
if (map == null) {
// We are using a set to avoid duplicate jids in case the user
// sends several directed presences to the same handler. The Map also
// ensures that if the user sends several presences to the same handler
// we will have only one entry in the Map
map = new WeakHashMap<ChannelHandler, Set<String>>();
map.put(handler, new ConcurrentHashSet<String>());
directedPresences.put(update.getFrom().toString(), map);
}
if (Presence.Type.unavailable.equals(update.getType())) {
// It's a directed unavailable presence
if (handler instanceof ClientSession) {
// Client sessions will receive only presences to the same JID (the
// address of the session) so remove the handler from the map
map.remove(handler);
if (map.isEmpty()) {
// Remove the user from the registry since the list of directed
// presences is empty
directedPresences.remove(update.getFrom().toString());
}
}
else {
// A service may receive presences for many JIDs so in this case we
// just need to remove the jid that has received a directed
// unavailable presence
Set<String> jids = map.get(handler);
if (jids != null) {
jids.remove(jid);
if (jids.isEmpty()) {
map.remove(handler);
if (map.isEmpty()) {
// Remove the user from the registry since the list of directed
// presences is empty
directedPresences.remove(update.getFrom().toString());
}
}
}
}
}
else {
// Add the handler to the list of handler that processed the directed
// presence sent by the user. This handler will be used to send
// the unavailable presence when the user goes offline
if (map.get(handler) == null) {
map.put(handler, new ConcurrentHashSet<String>());
}
map.get(handler).add(jid);
}
}
}
}
/**
* Sends an unavailable presence to the entities that received a directed (available) presence
* by the user that is now going offline.
*
* @param update the unavailable presence sent by the user.
*/
private void broadcastUnavailableForDirectedPresences(Presence update) {
if (update.getFrom() == null) {
return;
}
if (localServer.isLocal(update.getFrom())) {
// Remove the registry of directed presences of this user
Map<ChannelHandler, Set<String>> map = directedPresences.remove(update.getFrom().toString());
if (map != null) {
// Iterate over all the entities that the user sent a directed presence
for (ChannelHandler handler : new HashSet<ChannelHandler>(map.keySet())) {
Set<String> jids = map.get(handler);
if (jids == null) {
continue;
}
for (String jid : jids) {
Presence presence = update.createCopy();
presence.setTo(new JID(jid));
try {
handler.process(presence);
}
catch (UnauthorizedException ue) {
Log.error(ue);
}
}
}
}
}
}
public boolean hasDirectPresence(Session session, JID recipientJID) {
Map<ChannelHandler, Set<String>> map =
directedPresences.get(session.getAddress().toString());
if (map != null) {
String recipient = recipientJID.toBareJID();
for (Set<String> fullJIDs : map.values()) {
for (String fullJID : fullJIDs) {
if (fullJID.contains(recipient)) {
return true;
}
}
}
}
return false;
}
public void initialize(XMPPServer server) {
super.initialize(server);
localServer = server;
rosterManager = server.getRosterManager();
presenceManager = server.getPresenceManager();
deliverer = server.getPacketDeliverer();
messageStore = server.getOfflineMessageStore();
sessionManager = server.getSessionManager();
userManager = server.getUserManager();
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?