📄 sessionmanager.java
字号:
List<JID> addresses = routingTable.getRoutes(searchJID, null);
for (JID address : addresses) {
if (address.equals(originatingResource)) {
continue;
}
// Send the presence of the session whose presence has changed to
// this other user's session
presence.setTo(address);
routingTable.routePacket(address, presence, false);
}
}
/**
* Notification message sent when a client sent an unavailable presence for the session. Making
* the session unavailable means that the session is not eligible for receiving messages from
* other clients.
*
* @param session the session that received an unavailable presence.
*/
public void sessionUnavailable(LocalClientSession session) {
if (session.getAddress() != null && routingTable != null &&
session.getAddress().toBareJID().trim().length() != 0) {
// Update route to unavailable session (anonymous or not)
routingTable.addClientRoute(session.getAddress(), session);
}
}
/**
* Change the priority of a session, that was already available, associated with the sender.
*
* @param session The session whose presence priority has been modified
* @param oldPriority The old priority for the session
*/
public void changePriority(LocalClientSession session, int oldPriority) {
if (session.getAuthToken().isAnonymous()) {
// Do nothing if the session belongs to an anonymous user
return;
}
int newPriority = session.getPresence().getPriority();
if (newPriority < 0 || oldPriority >= 0) {
// Do nothing if new presence priority is not positive and old presence negative
return;
}
// Check presence's priority of other available resources
JID searchJID = new JID(session.getAddress().toBareJID());
for (JID address : routingTable.getRoutes(searchJID, null)) {
if (address.equals(session.getAddress())) {
continue;
}
ClientSession otherSession = routingTable.getClientRoute(address);
if (otherSession.getPresence().getPriority() >= 0) {
return;
}
}
// User sessions had negative presence before this change so deliver messages
if (session.canFloodOfflineMessages()) {
OfflineMessageStore messageStore = server.getOfflineMessageStore();
Collection<OfflineMessage> messages = messageStore.getMessages(session.getAuthToken().getUsername(), true);
for (Message message : messages) {
session.process(message);
}
}
}
public boolean isAnonymousRoute(String username) {
// JID's node and resource are the same for anonymous sessions
return isAnonymousRoute(new JID(username, serverName, username, true));
}
public boolean isAnonymousRoute(JID address) {
// JID's node and resource are the same for anonymous sessions
return routingTable.isAnonymousRoute(address);
}
public boolean isActiveRoute(String username, String resource) {
boolean hasRoute = false;
Session session = routingTable.getClientRoute(new JID(username, serverName, resource));
// Makes sure the session is still active
if (session != null && !session.isClosed()) {
hasRoute = session.validate();
}
return hasRoute;
}
/**
* Returns the session responsible for this JID data. The returned Session may have never sent
* an available presence (thus not have a route) or could be a Session that hasn't
* authenticated yet (i.e. preAuthenticatedSessions).
*
* @param from the sender of the packet.
* @return the <code>Session</code> associated with the JID.
*/
public ClientSession getSession(JID from) {
// Return null if the JID is null or belongs to a foreign server. If the server is
// shutting down then serverName will be null so answer null too in this case.
if (from == null || serverName == null || !serverName.equals(from.getDomain())) {
return null;
}
// Initially Check preAuthenticated Sessions
if (from.getResource() != null) {
ClientSession session = localSessionManager.getPreAuthenticatedSessions().get(from.getResource());
if (session != null) {
return session;
}
}
if (from.getResource() == null || from.getNode() == null) {
return null;
}
return routingTable.getClientRoute(from);
}
/**
* Returns a list that contains all authenticated client sessions connected to the server.
* The list contains sessions of anonymous and non-anonymous users.
*
* @return a list that contains all client sessions connected to the server.
*/
public Collection<ClientSession> getSessions() {
return routingTable.getClientsRoutes(false);
}
public Collection<ClientSession> getSessions(SessionResultFilter filter) {
List<ClientSession> results = new ArrayList<ClientSession>();
if (filter != null) {
// Grab all the matching sessions
results.addAll(getSessions());
// Now we have a copy of the references so we can spend some time
// doing the rest of the filtering without locking out session access
// so let's iterate and filter each session one by one
List<ClientSession> filteredResults = new ArrayList<ClientSession>();
for (ClientSession session : results) {
// Now filter on creation date if needed
filteredResults.add(session);
}
// Sort list.
Collections.sort(filteredResults, filter.getSortComparator());
int maxResults = filter.getNumResults();
if (maxResults == SessionResultFilter.NO_RESULT_LIMIT) {
maxResults = filteredResults.size();
}
// Now generate the final list. I believe it's faster to to build up a new
// list than it is to remove items from head and tail of the sorted tree
List<ClientSession> finalResults = new ArrayList<ClientSession>();
int startIndex = filter.getStartIndex();
Iterator<ClientSession> sortedIter = filteredResults.iterator();
for (int i = 0; sortedIter.hasNext() && finalResults.size() < maxResults; i++) {
ClientSession result = sortedIter.next();
if (i >= startIndex) {
finalResults.add(result);
}
}
return finalResults;
}
return results;
}
/**
* Returns the incoming server session hosted by this JVM that matches the specified stream ID.
*
* @param streamID the stream ID that identifies the incoming server session hosted by this JVM.
* @return the incoming server session hosted by this JVM or null if none was found.
*/
public LocalIncomingServerSession getIncomingServerSession(String streamID) {
return localSessionManager.getIncomingServerSession(streamID);
}
/**
* Returns the list of sessions that were originated by a remote server. The list will be
* ordered chronologically. IncomingServerSession can only receive packets from the remote
* server but are not capable of sending packets to the remote server.
*
* @param hostname the name of the remote server.
* @return the sessions that were originated by a remote server.
*/
public List<IncomingServerSession> getIncomingServerSessions(String hostname) {
List<String> streamIDs;
// Get list of sockets/sessions coming from the remote hostname
Lock lock = CacheFactory.getLock(hostname, hostnameSessionsCache);
try {
lock.lock();
streamIDs = hostnameSessionsCache.get(hostname);
}
finally {
lock.unlock();
}
if (streamIDs == null) {
return Collections.emptyList();
}
else {
// Collect the sessions associated to the found stream IDs
List<IncomingServerSession> sessions = new ArrayList<IncomingServerSession>();
for (String streamID : streamIDs) {
// Search in local hosted sessions
IncomingServerSession session = localSessionManager.getIncomingServerSession(streamID);
RemoteSessionLocator locator = server.getRemoteSessionLocator();
if (session == null && locator != null) {
// Get the node hosting this session
byte[] nodeID = incomingServerSessionsCache.get(streamID);
if (nodeID != null) {
session = locator.getIncomingServerSession(nodeID, streamID);
}
}
if (session != null) {
sessions.add(session);
}
}
return sessions;
}
}
/**
* Returns a session that was originated from this server to a remote server.
* OutgoingServerSession an only send packets to the remote server but are not capable of
* receiving packets from the remote server.
*
* @param hostname the name of the remote server.
* @return a session that was originated from this server to a remote server.
*/
public OutgoingServerSession getOutgoingServerSession(String hostname) {
return routingTable.getServerRoute(new JID(null, hostname, null, true));
}
public Collection<ClientSession> getSessions(String username) {
List<ClientSession> sessionList = new ArrayList<ClientSession>();
if (username != null) {
List<JID> addresses = routingTable.getRoutes(new JID(username, serverName, null, true), null);
for (JID address : addresses) {
sessionList.add(routingTable.getClientRoute(address));
}
}
return sessionList;
}
/**
* Returns number of client sessions that are connected to the server. Sessions that
* are authenticated and not authenticated will be included
*
* @param onlyLocal true if only sessions connected to this JVM will be considered. Otherwise count cluster wise.
* @return number of client sessions that are connected to the server.
*/
public int getConnectionsCount(boolean onlyLocal) {
int total = connectionsCounter.get();
if (!onlyLocal) {
Collection<Object> results =
CacheFactory.doSynchronousClusterTask(new GetSessionsCountTask(false), false);
for (Object result : results) {
if (result == null) {
continue;
}
total = total + (Integer) result;
}
}
return total;
}
/**
* Returns number of client sessions that are authenticated with the server. This includes
* anonymous and non-anoymous users.
*
* @param onlyLocal true if only sessions connected to this JVM will be considered. Otherwise count cluster wise.
* @return number of client sessions that are authenticated with the server.
*/
public int getUserSessionsCount(boolean onlyLocal) {
int total = routingTable.getClientsRoutes(true).size();
if (!onlyLocal) {
Collection<Object> results =
CacheFactory.doSynchronousClusterTask(new GetSessionsCountTask(true), false);
for (Object result : results) {
if (result == null) {
continue;
}
total = total + (Integer) result;
}
}
return total;
}
/**
* Returns number of sessions coming from remote servers. <i>Current implementation is only counting
* sessions connected to this JVM and not adding up sessions connected to other cluster nodes.</i>
*
* @param onlyLocal true if only sessions connected to this JVM will be considered. Otherwise count cluster wise.
* @return number of sessions coming from remote servers.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -