All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.atmosphere.vibe.ClusteredServer Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2014 The Vibe Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.atmosphere.vibe;

import java.io.Serializable;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;

import org.atmosphere.vibe.platform.action.Action;
import org.atmosphere.vibe.platform.action.Actions;
import org.atmosphere.vibe.platform.action.ConcurrentActions;

/**
 * {@link Server} implementation for clustering.
 * 

* With this implementation, {@code server.all(action)} have {@code action} be * executed with every socket in every server in the cluster. *

* This implementation adopts the publish and subscribe model from Java Message * Service to support clustering. Here, the exchanged message represents method * invocation to be executed by every server in the cluster. The following * methods create such messages. *

    *
  • {@link Server#all()}
  • *
  • {@link Server#all(Action)}
  • *
  • {@link Server#byTag(String...)}
  • *
  • {@link Server#byTag(String, Action)}
  • *
  • {@link Server#byTag(String[], Action)}
  • *
* A message created by this server is passed to * {@link ClusteredServer#publishAction(Action)} and a message created by other * servers is expected to be passed to {@link ClusteredServer#messageAction()}. * Therefore, what you need to do is to publish a message given through * {@link ClusteredServer#publishAction(Action)} to every server in the cluster * and to subscribe a published message by other servers to delegate it to * {@link ClusteredServer#messageAction()}. *

* Accordingly, such message must be able to be serialized and you have to pass * {@link Action} implementing {@link Serializable}. However, serialization of * inner classes doesn't work in some cases as expected so that always use * {@link Sentence} instead of action if possible unless you use lambda * expressions. * * @author Donghwan Kim * @see Note * of the Serializable Interface */ public class ClusteredServer extends DefaultServer { private Actions> publishActions = new ConcurrentActions<>(); private Action> messageAction = new Action>() { @SuppressWarnings("unchecked") @Override public void on(Map map) { String methodName = (String) map.get("method"); Object[] args = (Object[]) map.get("args"); switch (methodName) { case "all": ClusteredServer.super.all((Action) args[0]); break; case "byTag": ClusteredServer.super.byTag((String[]) args[0], (Action) args[1]); break; default: throw new IllegalArgumentException("Illegal method name in processing message: " + methodName); } } }; @Override public Server all(Action action) { publishMessage("all", action); return this; } @Override public Server byTag(String[] names, Action action) { publishMessage("byTag", names, action); return this; } private void publishMessage(String method, Object... args) { Map map = new LinkedHashMap<>(); map.put("method", method); map.put("args", args); publishActions.fire(Collections.unmodifiableMap(map)); } /** * Adds an action to be called with a message to be published to every node * in the cluster. */ public Server publishAction(Action> action) { publishActions.add(action); return this; } /** * An action to receive a message published from one of nodes in the * cluster. */ public Action> messageAction() { return messageAction; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy