📄 sessionmanager.java
字号:
/**
* Handle a session that just closed.
*
* @param handback The session that just closed
*/
public void onConnectionClose(Object handback) {
IncomingServerSession session = (IncomingServerSession)handback;
// Remove all the hostnames that were registered for this server session
for (String hostname : session.getValidatedDomains()) {
unregisterIncomingServerSession(hostname, session);
}
}
}
private class OutgoingServerSessionListener implements ConnectionCloseListener {
/**
* Handle a session that just closed.
*
* @param handback The session that just closed
*/
public void onConnectionClose(Object handback) {
OutgoingServerSession session = (OutgoingServerSession)handback;
// Remove all the hostnames that were registered for this server session
for (String hostname : session.getHostnames()) {
// Remove the route to the session using the hostname
server.getRoutingTable().removeServerRoute(new JID(hostname));
}
}
}
private class ConnectionMultiplexerSessionListener implements ConnectionCloseListener {
/**
* Handle a session that just closed.
*
* @param handback The session that just closed
*/
public void onConnectionClose(Object handback) {
ConnectionMultiplexerSession session = (ConnectionMultiplexerSession)handback;
// Remove all the hostnames that were registered for this server session
String domain = session.getAddress().getDomain();
localSessionManager.getConnnectionManagerSessions().remove(session.getAddress().toString());
// Remove track of the cluster node hosting the CM connection
multiplexerSessionsCache.remove(session.getAddress().toString());
if (getConnectionMultiplexerSessions(domain).isEmpty()) {
// Terminate ClientSessions originated from this connection manager
// that are still active since the connection manager has gone down
ConnectionMultiplexerManager.getInstance().multiplexerUnavailable(domain);
}
}
}
public void initialize(XMPPServer server) {
super.initialize(server);
this.server = server;
router = server.getPacketRouter();
userManager = server.getUserManager();
routingTable = server.getRoutingTable();
serverName = server.getServerInfo().getXMPPDomain();
serverAddress = new JID(serverName);
if (JiveGlobals.getBooleanProperty("xmpp.audit.active")) {
streamIDFactory = new AuditStreamIDFactory();
}
else {
streamIDFactory = new BasicStreamIDFactory();
}
String conflictLimitProp = JiveGlobals.getProperty("xmpp.session.conflict-limit");
if (conflictLimitProp == null) {
conflictLimit = 0;
JiveGlobals.setProperty("xmpp.session.conflict-limit", Integer.toString(conflictLimit));
}
else {
try {
conflictLimit = Integer.parseInt(conflictLimitProp);
}
catch (NumberFormatException e) {
conflictLimit = 0;
JiveGlobals.setProperty("xmpp.session.conflict-limit", Integer.toString(conflictLimit));
}
}
// Initialize caches.
componentSessionsCache = CacheFactory.createCache(COMPONENT_SESSION_CACHE_NAME);
multiplexerSessionsCache = CacheFactory.createCache(CM_CACHE_NAME);
incomingServerSessionsCache = CacheFactory.createCache(ISS_CACHE_NAME);
hostnameSessionsCache = CacheFactory.createCache("Sessions by Hostname");
validatedDomainsCache = CacheFactory.createCache("Validated Domains");
sessionInfoCache = CacheFactory.createCache(C2S_INFO_CACHE_NAME);
// Listen to cluster events
ClusterManager.addListener(this);
}
/**
* Sends a message with a given subject and body to all the active user sessions in the server.
*
* @param subject the subject to broadcast.
* @param body the body to broadcast.
*/
public void sendServerMessage(String subject, String body) {
sendServerMessage(null, subject, body);
}
/**
* Sends a message with a given subject and body to one or more user sessions related to the
* specified address. If address is null or the address's node is null then the message will be
* sent to all the user sessions. But if the address includes a node but no resource then
* the message will be sent to all the user sessions of the requeted user (defined by the node).
* Finally, if the address is a full JID then the message will be sent to the session associated
* to the full JID. If no session is found then the message is not sent.
*
* @param address the address that defines the sessions that will receive the message.
* @param subject the subject to broadcast.
* @param body the body to broadcast.
*/
public void sendServerMessage(JID address, String subject, String body) {
Message packet = createServerMessage(subject, body);
if (address == null || address.getNode() == null || !userManager.isRegisteredUser(address)) {
broadcast(packet);
}
else if (address.getResource() == null || address.getResource().length() < 1) {
userBroadcast(address.getNode(), packet);
}
else {
routingTable.routePacket(address, packet, true);
}
}
private Message createServerMessage(String subject, String body) {
Message message = new Message();
message.setFrom(serverAddress);
if (subject != null) {
message.setSubject(subject);
}
message.setBody(body);
return message;
}
public void start() throws IllegalStateException {
super.start();
localSessionManager.start();
}
public void stop() {
Log.debug("SessionManager: Stopping server");
// Stop threads that are sending packets to remote servers
OutgoingSessionPromise.getInstance().shutdown();
if (JiveGlobals.getBooleanProperty("shutdownMessage.enabled")) {
sendServerMessage(null, LocaleUtils.getLocalizedString("admin.shutdown.now"));
}
localSessionManager.stop();
serverName = null;
}
/**
* Returns true if remote servers are allowed to have more than one connection to this
* server. Having more than one connection may improve number of packets that can be
* transfered per second. This setting only used by the server dialback mehod.<p>
*
* It is highly recommended that {@link #getServerSessionTimeout()} is enabled so that
* dead connections to this server can be easily discarded.
*
* @return true if remote servers are allowed to have more than one connection to this
* server.
*/
public boolean isMultipleServerConnectionsAllowed() {
return JiveGlobals.getBooleanProperty("xmpp.server.session.allowmultiple", true);
}
/**
* Sets if remote servers are allowed to have more than one connection to this
* server. Having more than one connection may improve number of packets that can be
* transfered per second. This setting only used by the server dialback mehod.<p>
*
* It is highly recommended that {@link #getServerSessionTimeout()} is enabled so that
* dead connections to this server can be easily discarded.
*
* @param allowed true if remote servers are allowed to have more than one connection to this
* server.
*/
public void setMultipleServerConnectionsAllowed(boolean allowed) {
JiveGlobals.setProperty("xmpp.server.session.allowmultiple", Boolean.toString(allowed));
if (allowed && JiveGlobals.getIntProperty("xmpp.server.session.idle", 10 * 60 * 1000) <= 0)
{
Log.warn("Allowing multiple S2S connections for each domain, without setting a " +
"maximum idle timeout for these connections, is unrecommended! Either " +
"set xmpp.server.session.allowmultiple to 'false' or change " +
"xmpp.server.session.idle to a (large) positive value.");
}
}
/******************************************************
* Clean up code
*****************************************************/
/**
* Sets the number of milliseconds to elapse between clearing of idle server sessions.
*
* @param timeout the number of milliseconds to elapse between clearings.
*/
public void setServerSessionTimeout(int timeout) {
if (getServerSessionTimeout() == timeout) {
return;
}
// Set the new property value
JiveGlobals.setProperty("xmpp.server.session.timeout", Integer.toString(timeout));
}
/**
* Returns the number of milliseconds to elapse between clearing of idle server sessions.
*
* @return the number of milliseconds to elapse between clearing of idle server sessions.
*/
public int getServerSessionTimeout() {
return JiveGlobals.getIntProperty("xmpp.server.session.timeout", 5 * 60 * 1000);
}
public void setServerSessionIdleTime(int idleTime) {
if (getServerSessionIdleTime() == idleTime) {
return;
}
// Set the new property value
JiveGlobals.setProperty("xmpp.server.session.idle", Integer.toString(idleTime));
if (idleTime <= 0 && isMultipleServerConnectionsAllowed() )
{
Log.warn("Allowing multiple S2S connections for each domain, without setting a " +
"maximum idle timeout for these connections, is unrecommended! Either " +
"set xmpp.server.session.allowmultiple to 'false' or change " +
"xmpp.server.session.idle to a (large) positive value.");
}
}
public int getServerSessionIdleTime() {
return JiveGlobals.getIntProperty("xmpp.server.session.idle", 10 * 60 * 1000);
}
public Cache<String, ClientSessionInfo> getSessionInfoCache() {
return sessionInfoCache;
}
public void joinedCluster() {
restoreCacheContent();
// Track information about local sessions and share it with other cluster nodes
for (ClientSession session : routingTable.getClientsRoutes(true)) {
sessionInfoCache.put(session.getAddress().toString(), new ClientSessionInfo((LocalClientSession)session));
}
}
public void joinedCluster(byte[] nodeID) {
// Do nothing
}
public void leftCluster() {
if (!XMPPServer.getInstance().isShuttingDown()) {
// Add local sessions to caches
restoreCacheContent();
}
}
public void leftCluster(byte[] nodeID) {
// Do nothing
}
public void markedAsSeniorClusterMember() {
// Do nothing
}
private void restoreCacheContent() {
// Add external component sessions hosted locally to the cache (using new nodeID)
for (Session session : localSessionManager.getComponentsSessions()) {
componentSessionsCache.put(session.getAddress().toString(), server.getNodeID().toByteArray());
}
// Add connection multiplexer sessions hosted locally to the cache (using new nodeID)
for (String address : localSessionManager.getConnnectionManagerSessions().keySet()) {
multiplexerSessionsCache.put(address, server.getNodeID().toByteArray());
}
// Add incoming server sessions hosted locally to the cache (using new nodeID)
for (LocalIncomingServerSession session : localSessionManager.getIncomingServerSessions()) {
String streamID = session.getStreamID().getID();
incomingServerSessionsCache.put(streamID, server.getNodeID().toByteArray());
for (String hostname : session.getValidatedDomains()) {
// Update list of sockets/sessions coming from the same remote hostname
Lock lock = CacheFactory.getLock(hostname, hostnameSessionsCache);
try {
lock.lock();
List<String> streamIDs = hostnameSessionsCache.get(hostname);
if (streamIDs == null) {
streamIDs
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -