📄 sessionmanager.java
字号:
*/
public int getIncomingServerSessionsCount(boolean onlyLocal) {
int total = localSessionManager.getIncomingServerSessions().size();
if (!onlyLocal) {
// TODO Implement this when needed
}
return total;
}
/**
* Returns the number of sessions for a user that are available. For the count
* of all sessions for the user, including sessions that are just starting
* or closed.
*
* @see #getConnectionsCount(boolean)
* @param username the user.
* @return number of available sessions for a user.
*/
public int getActiveSessionCount(String username) {
return routingTable.getRoutes(new JID(username, serverName, null, true), null).size();
}
public int getSessionCount(String username) {
// TODO Count ALL sessions not only available
return routingTable.getRoutes(new JID(username, serverName, null, true), null).size();
}
/**
* Returns a collection with the established sessions from external components.
*
* @return a collection with the established sessions from external components.
*/
public Collection<ComponentSession> getComponentSessions() {
List<ComponentSession> sessions = new ArrayList<ComponentSession>();
// Add sessions of external components connected to this JVM
sessions.addAll(localSessionManager.getComponentsSessions());
// Add sessions of external components connected to other cluster nodes
RemoteSessionLocator locator = server.getRemoteSessionLocator();
if (locator != null) {
for (Map.Entry<String, byte[]> entry : componentSessionsCache.entrySet()) {
if (!server.getNodeID().equals(entry.getValue())) {
sessions.add(locator.getComponentSession(entry.getValue(), new JID(entry.getKey())));
}
}
}
return sessions;
}
/**
* Returns the session of the component whose domain matches the specified domain.
*
* @param domain the domain of the component session to look for.
* @return the session of the component whose domain matches the specified domain.
*/
public ComponentSession getComponentSession(String domain) {
// Search in the external components connected to this JVM
for (ComponentSession session : localSessionManager.getComponentsSessions()) {
if (domain.equals(session.getAddress().getDomain())) {
return session;
}
}
// Search in the external components connected to other cluster nodes
RemoteSessionLocator locator = server.getRemoteSessionLocator();
if (locator != null) {
byte[] nodeID = componentSessionsCache.get(domain);
if (nodeID != null) {
return locator.getComponentSession(nodeID, new JID(domain));
}
}
return null;
}
/**
* Returns a collection with the hostnames of the remote servers that currently have an
* incoming server connection to this server.
*
* @return a collection with the hostnames of the remote servers that currently have an
* incoming server connection to this server.
*/
public Collection<String> getIncomingServers() {
return hostnameSessionsCache.keySet();
}
/**
* Returns a collection with the hostnames of the remote servers that currently may receive
* packets sent from this server.
*
* @return a collection with the hostnames of the remote servers that currently may receive
* packets sent from this server.
*/
public Collection<String> getOutgoingServers() {
return routingTable.getServerHostnames();
}
/**
* Broadcasts the given data to all connected sessions. Excellent
* for server administration messages.
*
* @param packet the packet to be broadcast.
*/
public void broadcast(Message packet) {
routingTable.broadcastPacket(packet, false);
}
/**
* Broadcasts the given data to all connected sessions for a particular
* user. Excellent for updating all connected resources for users such as
* roster pushes.
*
* @param username the user to send the boradcast to.
* @param packet the packet to be broadcast.
* @throws PacketException if a packet exception occurs.
*/
public void userBroadcast(String username, Packet packet) throws PacketException {
// TODO broadcast to ALL sessions of the user and not only available
for (JID address : routingTable.getRoutes(new JID(username, serverName, null), null)) {
packet.setTo(address);
routingTable.routePacket(address, packet, true);
}
}
/**
* Removes a session.
*
* @param session the session.
* @return true if the requested session was successfully removed.
*/
public boolean removeSession(LocalClientSession session) {
// Do nothing if session is null or if the server is shutting down. Note: When the server
// is shutting down the serverName will be null.
if (session == null || serverName == null) {
return false;
}
AuthToken authToken = session.getAuthToken();
// Consider session anonymous (for this matter) if we are closing a session that never authenticated
boolean anonymous = authToken == null || authToken.isAnonymous();
return removeSession(session, session.getAddress(), anonymous, false);
}
/**
* Removes a session.
*
* @param session the session or null when session is derived from fullJID.
* @param fullJID the address of the session.
* @param anonymous true if the authenticated user is anonymous.
* @param forceUnavailable true if an unavailable presence must be created and routed.
* @return true if the requested session was successfully removed.
*/
public boolean removeSession(ClientSession session, JID fullJID, boolean anonymous, boolean forceUnavailable) {
// Do nothing if server is shutting down. Note: When the server
// is shutting down the serverName will be null.
if (serverName == null) {
return false;
}
if (session == null) {
session = getSession(fullJID);
}
// Remove route to the removed session (anonymous or not)
boolean removed = routingTable.removeClientRoute(fullJID);
if (removed) {
// Fire session event.
if (anonymous) {
SessionEventDispatcher
.dispatchEvent(session, SessionEventDispatcher.EventType.anonymous_session_destroyed);
}
else {
SessionEventDispatcher.dispatchEvent(session, SessionEventDispatcher.EventType.session_destroyed);
}
}
// Remove the session from the pre-Authenticated sessions list (if present)
boolean preauth_removed =
localSessionManager.getPreAuthenticatedSessions().remove(fullJID.getResource()) != null;
// If the user is still available then send an unavailable presence
if (forceUnavailable || session.getPresence().isAvailable()) {
Presence offline = new Presence();
offline.setFrom(fullJID);
offline.setTo(new JID(null, serverName, null, true));
offline.setType(Presence.Type.unavailable);
router.route(offline);
}
// Stop tracking information about the session and share it with other cluster nodes
sessionInfoCache.remove(fullJID.toString());
if (removed || preauth_removed) {
// Decrement the counter of user sessions
connectionsCounter.decrementAndGet();
return true;
}
return false;
}
public int getConflictKickLimit() {
return conflictLimit;
}
/**
* Returns the temporary keys used by the sessions that has not been authenticated yet. This
* is an utility method useful for debugging situations.
*
* @return the temporary keys used by the sessions that has not been authenticated yet.
*/
public Collection<String> getPreAuthenticatedKeys() {
return localSessionManager.getPreAuthenticatedSessions().keySet();
}
/**
* Returns true if the specified address belongs to a preauthenticated session. Preauthenticated
* sessions are only available to the local cluster node when running inside of a cluster.
*
* @param address the address of the session.
* @return true if the specified address belongs to a preauthenticated session.
*/
public boolean isPreAuthenticatedSession(JID address) {
return serverName.equals(address.getDomain()) &&
localSessionManager.getPreAuthenticatedSessions().containsKey(address.getResource());
}
public void setConflictKickLimit(int limit) {
conflictLimit = limit;
JiveGlobals.setProperty("xmpp.session.conflict-limit", Integer.toString(conflictLimit));
}
private class ClientSessionListener implements ConnectionCloseListener {
/**
* Handle a session that just closed.
*
* @param handback The session that just closed
*/
public void onConnectionClose(Object handback) {
try {
LocalClientSession session = (LocalClientSession) handback;
try {
if ((session.getPresence().isAvailable() || !session.wasAvailable()) &&
routingTable.hasClientRoute(session.getAddress())) {
// Send an unavailable presence to the user's subscribers
// Note: This gives us a chance to send an unavailable presence to the
// entities that the user sent directed presences
Presence presence = new Presence();
presence.setType(Presence.Type.unavailable);
presence.setFrom(session.getAddress());
router.route(presence);
}
}
finally {
// Remove the session
removeSession(session);
}
}
catch (Exception e) {
// Can't do anything about this problem...
Log.error(LocaleUtils.getLocalizedString("admin.error.close"), e);
}
}
}
private class ComponentSessionListener implements ConnectionCloseListener {
/**
* Handle a session that just closed.
*
* @param handback The session that just closed
*/
public void onConnectionClose(Object handback) {
LocalComponentSession session = (LocalComponentSession)handback;
try {
// Unbind registered domains for this external component
for (String domain : session.getExternalComponent().getSubdomains()) {
String subdomain = domain.substring(0, domain.indexOf(serverName) - 1);
InternalComponentManager.getInstance().removeComponent(subdomain, session.getExternalComponent());
}
}
catch (Exception e) {
// Can't do anything about this problem...
Log.error(LocaleUtils.getLocalizedString("admin.error.close"), e);
}
finally {
// Remove the session
localSessionManager.getComponentsSessions().remove(session);
// Remove track of the cluster node hosting the external component
// if no more components are handling it.
if (!InternalComponentManager.getInstance().hasComponent(session.getAddress())) {
componentSessionsCache.remove(session.getAddress().toString());
}
}
}
}
private class IncomingServerSessionListener implements ConnectionCloseListener {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -