Giter Site home page Giter Site logo

cettia / cettia-java-server Goto Github PK

View Code? Open in Web Editor NEW
40.0 5.0 3.0 155 KB

A full-featured real-time web application framework for Java

Home Page: https://cettia.io

License: Apache License 2.0

Java 99.54% JavaScript 0.46%
cettia java server real-time websocket long-polling streaming comet web-fragment framework-agnostic

cettia-java-server's Introduction

Cettia

Cettia is a full-featured real-time web application framework for Java that you can use to exchange events between server and client in real-time. It is meant for when you run into issues which are tricky to resolve with WebSocket, JSON, and switch statement per se:

  • Avoiding repetitive boilerplate code
  • Supporting environments where WebSocket is not available
  • Handling both text and binary data together
  • Recovering missed events
  • Providing multi-device user experience
  • Scaling out an application, and so on.

It offers a reliable full duplex message channel and elegant patterns to achieve better user experience in the real-time web, and is compatible with any web frameworks on the Java Virtual Machine.


The following is a summary of the Cettia starter kit to help you get started quickly. In the summary, comments starting with ## refer to a title of a related chapter in the tutorial, Building Real-Time Web Applications With Cettia, where you can find a detailed explanation. You may want to highlight the ##.

Maven dependencies.

<!-- ## Setting Up the Project -->
<!-- To write a Cettia application -->
<dependency>
  <groupId>io.cettia</groupId>
  <artifactId>cettia-server</artifactId>
  <version>1.2.0</version>
</dependency>
<!-- To run a Cettia application on Servlet 3 and Java WebSocket API 1 -->
<!-- Besides them, you can also use Spring WebFlux, Spring MVC, Grizzly, Vert.x, Netty, and so on -->
<dependency>
  <groupId>io.cettia.asity</groupId>
  <artifactId>asity-bridge-servlet3</artifactId>
  <version>2.0.0</version>
</dependency>
<dependency>
  <groupId>io.cettia.asity</groupId>
  <artifactId>asity-bridge-jwa1</artifactId>
  <version>2.0.0</version>
</dependency>

A class to play with the Cettia server. Import statements, verbose try-catch blocks, empty methods, etc. are skipped for brevity.

@WebListener
public class CettiaConfigListener implements ServletContextListener {
  public void contextInitialized(ServletContextEvent event) {
    // Cettia part
    // If you don't want to form a cluster,
    // replace the following line with 'Server server = new DefaultServer();'
    ClusteredServer server = new ClusteredServer();
    HttpTransportServer httpAction = new HttpTransportServer().ontransport(server);
    WebSocketTransportServer wsAction = new WebSocketTransportServer().ontransport(server);

    // If a client opens a socket, the server creates and passes a socket to socket handlers
    server.onsocket((ServerSocket socket) -> {
      // ## Socket Lifecycle
      Action<Void> logState = v -> System.out.println(socket + " " + socket.state());
      socket.onopen(logState).onclose(logState).ondelete(logState);

      // ## Sending and Receiving Events
      // An 'echo' event handler where any received echo event is sent back
      socket.on("echo", data -> socket.send("echo", data));

      // ## Attributes and Tags
      // Attributes and tags are contexts to store the socket state in the form of Map and Set
      String username = findParam(socket.uri(), "username");
      if (username == null) {
        // Attaches a tag to the socket
        socket.tag("nonmember");
      } else {
        // Associates an attribute with the the socket
        socket.set("username", username);
      }

      // ## Working with Sockets
      // A 'chat' event handler to send a given chat event to every socket in every server in the cluster
      socket.on("chat", data -> server.find(ServerSocketPredicates.all()).send("chat", data));

      // ## Advanced Sockets Handling
      if (username != null) {
        // A group of sockets representing the same user, whose username is the given one
        Sentence user = server.find(ServerSocketPredicates.attr("username", username));
        // A 'myself' event handler to send a given myself event to myself whose username is the same
        socket.on("myself", data -> {
          // You can directly handle each socket through the execute method of Sentence if needed
          user.execute(s -> s.send("myself"));
        });

        // Limits only one socket per user
        boolean onlyOneSocket = Boolean.parseBoolean(findParam(socket.uri(), "onlyOneSocket"));
        if (onlyOneSocket) {
          // Finds sockets opened by whose username is the same other than this socket and
          // sends a 'signout' event to prevent reconnection and closes a connection
          user.find(id(socket).negate()).send("signout").close();
        }
      }

      // ## Disconnection Handling
      Queue<Object[]> queue = new ConcurrentLinkedQueue<>();
      // Caches events that fail to send due to disconnection
      socket.oncache(args -> queue.offer(args));
      // Sends cached events on the next connection
      socket.onopen(v -> {
        while (socket.state() == ServerSocket.State.OPENED && !queue.isEmpty()) {
          Object[] args = queue.poll();
          socket.send((String) args[0], args[1], (Action<?>) args[2], (Action<?>) args[3]);
        }
      });
      // If the client fails to connect within 1 minute after disconnection,
      // You may want to consider notifying the user of finally missed events, like push notifications
      socket.ondelete(v -> queue.forEach(args -> {
        System.out.println(socket + " missed event - name: " + args[0] + ", data: " + args[1]);
      }));
    });

    // ## Working with Sockets
    // To deal with sockets, inject the server wherever you want
    ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
    // Sends a 'welcome' event to sockets representing user not signed in every 5 seconds
    executor.scheduleAtFixedRate(() -> server.byTag("nonmember").send("welcome"), 0, 5, SECONDS);

    // ## Plugging Into the Web Framework
    // Cettia is designed to run on any web framework seamlessly on the JVM
    // Note how 'httpAction' and 'wsAction' are plugged into Servlet and Java API for Websocket
    ServletContext context = event.getServletContext();
    AsityServlet asityServlet = new AsityServlet().onhttp(/* ㅇㅅㅇ */ httpAction);
    ServletRegistration.Dynamic reg = context.addServlet(AsityServlet.class.getName(), asityServlet);
    reg.setAsyncSupported(true);
    reg.addMapping("/cettia");

    ServerContainer container = (ServerContainer) context.getAttribute(ServerContainer.class.getName());
    ServerEndpointConfig.Configurator configurator = new ServerEndpointConfig.Configurator() {
      public <T> T getEndpointInstance(Class<T> endpointClass) {
        AsityServerEndpoint asityServerEndpoint = new AsityServerEndpoint();
        asityServerEndpoint.onwebsocket(/* ㅇㅅㅇ */ wsAction);
        return endpointClass.cast(asityServerEndpoint);
      }
    };
    container.addEndpoint(ServerEndpointConfig.Builder.create(AsityServerEndpoint.class, "/cettia")
      .configurator(configurator).build());

    // ## Scaling a Cettia Application
    // Any publish-subscribe messaging system can be used to scale a Cettia application horizontally,
    // and it doesn’t require any modification in the existing application.
    HazelcastInstance hazelcast = HazelcastInstanceFactory.newHazelcastInstance(new Config());
    ITopic<Map<String, Object>> topic = hazelcast.getTopic("cettia");
    // It publishes messages given by the server
    server.onpublish(message -> topic.publish(message));
    // It relays published messages to the server
    topic.addMessageListener(message -> server.messageAction().on(message.getMessageObject()));
  }
}

Here's an example with the Spring WebFlux 5 to show Cettia's framework-agnostic nature. Consult Asity’s Run Anywhere section for how to plug a Cettia application into other various frameworks.

@SpringBootApplication
@EnableWebFlux
public class CettiaServer {
  @Bean
  public RouterFunction<ServerResponse> httpMapping(HttpTransportServer httpAction) {
    AsityHandlerFunction asityHandlerFunction = new AsityHandlerFunction();
    asityHandlerFunction.onhttp(/* ㅇㅅㅇ */ httpAction);

    RequestPredicate isNotWebSocket = headers(h -> !"websocket".equalsIgnoreCase(h.asHttpHeaders().getUpgrade()));
    return route(path("/cettia").and(isNotWebSocket), asityHandlerFunction);
  }

  @Bean
  public HandlerMapping wsMapping(WebSocketTransportServer wsAction) {
    AsityWebSocketHandler asityWebSocketHandler = new AsityWebSocketHandler();
    asityWebSocketHandler.onwebsocket(/* ㅇㅅㅇ */ wsAction);
    Map<String, WebSocketHandler> map = new LinkedHashMap<>();
    map.put("/cettia", asityWebSocketHandler);

    SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
    mapping.setUrlMap(map);

    return mapping;
  }
}

You need minimal HTML to load the cettia object. Also, if you have a cettia-client npm module installed, you should be able to load the cettia object with require("cettia-client/cettia-bundler"); and require("cettia-client"); in Webpack and Node, respectively.

 <!DOCTYPE html>
 <title>index</title>
 <script src="https://unpkg.com/[email protected]/cettia-browser.min.js"></script>

Below is the JavaScript code to play with the cettia object. Open the above page and its developer console in several browsers, run the script, and watch results on the fly.

// ## Opening a Socket
// Manipulates the below params object to play with the server implementation
var params = {
  username: "flowersinthesand",
  onlyOneSocket: true
};
// Let's assume that each key and value are already encoding safe
var query = Object.keys(params).filter(k => params[k]).map(k => `${k}=${params[k]}`).join("&");
var socket = cettia.open("/cettia?" + query);

// ## Socket Lifecycle
var logState = () => console.log(socket.state());
socket.on("connecting", logState).on("open", logState).on("close", logState);
socket.on("waiting", (delay, attempts) => console.log(socket.state(), delay, attempts));

// ## Sending and Receiving Events
["echo", "chat", "myself", "welcome"].forEach(event => {
  socket.on(event, data => console.log(event, data));
});
socket.on("signout", () => {
  console.log("signout", "You've been signed out since you signed in on another device");
  // It prevents reconnection
  socket.close();
});

// This open event handler registered through `once` is called at maximum once
socket.once("open", () => {
  // Sends an echo event to be returned
  socket.send("echo", "Hello world");
  // Sends a chat event to be broadcast to every sockets in the server
  socket.send("chat", {text: "I'm a text"});
  // Sends an event to sockets whose username is the same
  // with composite data consisting of text data and binary data
  socket.send("myself", {text: "I'm a text", binary: new TextEncoder().encode("I'm a binary")});
});

The full source code for the starter kit is available at the repository, https://github.com/cettia/cettia-starter-kit. If you want to dig deeper, read an introductory tutorial to Cettia, Building Real-Time Web Applications With Cettia. It explains the reason behind key design decisions that the Cettia team have made in the Cettia, as well as various patterns and features required to build real-time oriented applications without compromise with Cettia.


If you run into issues or have questions or are interested and would like to be more involved, feel free to join the mailing list and share your feedback. Also, follow @cettia_project or @flowersits on Twitter for the latest news and updates.

cettia-java-server's People

Contributors

flowersinthesand avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

cettia-java-server's Issues

Rewrite Javadoc

Update out-of-date terminologies, improve the grammars, and so on.

Deprecate finders in favor of ServerSocketPredicates.

As of 1.2, Java 8 is the minimum requirement. Java 8's lambda support makes it more descriptive and expressive to find sockets with various complex conditions comparing to finders. From now on, we will provide more static methods to create various useful predicates through ServerSocketPredicates instead of adding finders to Server.

The following finders in Server are to be deprecated:

  • Sentence all()
    • Instead, use find(ServerSocketPredicates.all()).
  • Sentence byTag(String... names)
    • Instead, use find(ServerSocketPredicates.tag(names)).
  • Server all(SerializableAction<ServerSocket> action)
    • Instead, use find(ServerSocketPredicates.all()).execute(action).
  • Server byTag(String[] names, SerializableAction<ServerSocket> action)
    • Instead, use find(ServerSocketPredicates.tag(names)).execute(action).
  • Server byTag(String name, SerializableAction<ServerSocket> action)
    • Instead, use find(ServerSocketPredicates.tag(name)).execute(action).

Update dependencies

FYI

C:\Users\Donghwan\git\cettia-java-server> mvn versions:display-plugin-updates versions:display-dependency-updates versions:display-property-updates
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO]
[INFO] Cettia Server
[INFO] Cettia Server/Server
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Cettia Server 1.1.0-Beta1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- versions-maven-plugin:2.3:display-plugin-updates (default-cli) @ cettia-server-parent ---
[INFO]
[INFO] The following plugin updates are available:
[INFO]   com.github.eirslett:frontend-maven-plugin ................ 1.4 -> 1.6
[INFO]   maven-javadoc-plugin ................................ 2.10.4 -> 3.0.0
[INFO]
[WARNING] The following plugins do not have their version specified:
[WARNING]   maven-clean-plugin ........................ (from super-pom) 3.0.0
[WARNING]   maven-deploy-plugin ....................... (from super-pom) 2.8.2
[WARNING]   maven-install-plugin ...................... (from super-pom) 2.5.2
[WARNING]   maven-site-plugin ........................... (from super-pom) 3.7
[INFO]
[INFO] Project defines minimum Maven version as: 3.1.0
[INFO] Plugins require minimum Maven version of: 3.1.0
[INFO] Note: the super-pom from Maven 3.3.9 defines some of the plugin
[INFO]       versions and may be influencing the plugins required minimum Maven
[INFO]       version.
[INFO]
[INFO] No plugins require a newer version of Maven than specified by the pom.
[INFO]
[INFO]
[INFO] --- versions-maven-plugin:2.3:display-dependency-updates (default-cli) @ cettia-server-parent ---
[INFO] artifact ch.qos.logback:logback-classic: checking for updates from central
[INFO] artifact ch.qos.logback:logback-core: checking for updates from central
[INFO] artifact com.fasterxml.jackson.core:jackson-databind: checking for updates from central
[INFO] artifact io.cettia.asity:asity-bridge-jwa1: checking for updates from central
[INFO] artifact io.cettia:cettia-server: checking for updates from sonatype-nexus-snapshots
[INFO] artifact io.cettia.asity:asity-bridge-servlet3: checking for updates from central
[INFO] artifact io.cettia.asity:asity-websocket: checking for updates from central
[INFO] artifact io.cettia.asity:asity-http: checking for updates from central
[INFO] artifact javax.servlet:javax.servlet-api: checking for updates from central
[INFO] artifact javax.websocket:javax.websocket-api: checking for updates from central
[INFO] artifact org.apache.commons:commons-exec: checking for updates from central
[INFO] artifact junit:junit: checking for updates from central
[INFO] artifact org.eclipse.jetty.websocket:javax-websocket-server-impl: checking for updates from central
[INFO] artifact org.hamcrest:hamcrest-all: checking for updates from central
[INFO] artifact org.mockito:mockito-core: checking for updates from central
[INFO] artifact org.msgpack:jackson-dataformat-msgpack: checking for updates from central
[INFO] artifact org.slf4j:slf4j-api: checking for updates from central
[INFO] The following dependencies in Dependency Management have newer versions:
[INFO]   ch.qos.logback:logback-classic ................. 1.2.3 -> 1.3.0-alpha4
[INFO]   ch.qos.logback:logback-core .................... 1.2.3 -> 1.3.0-alpha4
[INFO]   com.fasterxml.jackson.core:jackson-databind ......... 2.8.8.1 -> 2.9.6
[INFO]   io.cettia.asity:asity-bridge-jwa1 ..................... 1.0.0 -> 2.0.0
[INFO]   io.cettia.asity:asity-bridge-servlet3 ................. 1.0.0 -> 2.0.0
[INFO]   io.cettia.asity:asity-http ............................ 1.0.0 -> 2.0.0
[INFO]   io.cettia.asity:asity-websocket ....................... 1.0.0 -> 2.0.0
[INFO]   javax.servlet:javax.servlet-api ....................... 3.1.0 -> 4.0.1
[INFO]   org.eclipse.jetty.websocket:javax-websocket-server-impl ...
[INFO]                                           9.2.21.v20170120 -> 9.4.12.RC1
[INFO]   org.mockito:mockito-core ............................. 2.8.9 -> 2.21.0
[INFO]   org.msgpack:jackson-dataformat-msgpack .............. 0.8.12 -> 0.8.16
[INFO]   org.slf4j:slf4j-api ............................ 1.7.25 -> 1.8.0-beta2
[INFO]
[INFO]
[INFO] --- versions-maven-plugin:2.3:display-property-updates (default-cli) @ cettia-server-parent ---
[INFO]
[INFO] The following version property updates are available:
[INFO]   ${slf4j.version} .............................. 1.7.25 -> 1.8.0-beta2
[INFO]   ${asity.version} ..................................... 1.0.0 -> 2.0.0
[INFO]   ${logback.version} ............................ 1.2.3 -> 1.3.0-alpha4
[INFO]
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Cettia Server/Server 1.1.0-Beta1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- versions-maven-plugin:2.3:display-plugin-updates (default-cli) @ cettia-server ---
[INFO]
[INFO] All plugins with a version specified are using the latest versions.
[INFO]
[WARNING] The following plugins do not have their version specified:
[WARNING]   maven-clean-plugin ........................ (from super-pom) 3.0.0
[WARNING]   maven-compiler-plugin ..................... (from super-pom) 3.7.0
[WARNING]   maven-deploy-plugin ....................... (from super-pom) 2.8.2
[WARNING]   maven-install-plugin ...................... (from super-pom) 2.5.2
[WARNING]   maven-jar-plugin .......................... (from super-pom) 3.0.2
[WARNING]   maven-resources-plugin .................... (from super-pom) 3.0.2
[WARNING]   maven-site-plugin ........................... (from super-pom) 3.7
[WARNING]   maven-surefire-plugin .................... (from super-pom) 2.20.1
[INFO]
[INFO] Project inherits minimum Maven version as: 3.1.0
[INFO] Plugins require minimum Maven version of: 3.0
[INFO] Note: the super-pom from Maven 3.3.9 defines some of the plugin
[INFO]       versions and may be influencing the plugins required minimum Maven
[INFO]       version.
[INFO]
[INFO] No plugins require a newer version of Maven than specified by the pom.
[INFO]
[INFO]
[INFO] --- versions-maven-plugin:2.3:display-dependency-updates (default-cli) @ cettia-server ---
[INFO] The following dependencies in Dependency Management have newer versions:
[INFO]   ch.qos.logback:logback-classic ................. 1.2.3 -> 1.3.0-alpha4
[INFO]   ch.qos.logback:logback-core .................... 1.2.3 -> 1.3.0-alpha4
[INFO]   com.fasterxml.jackson.core:jackson-databind ......... 2.8.8.1 -> 2.9.6
[INFO]   io.cettia.asity:asity-bridge-jwa1 ..................... 1.0.0 -> 2.0.0
[INFO]   io.cettia.asity:asity-bridge-servlet3 ................. 1.0.0 -> 2.0.0
[INFO]   io.cettia.asity:asity-http ............................ 1.0.0 -> 2.0.0
[INFO]   io.cettia.asity:asity-websocket ....................... 1.0.0 -> 2.0.0
[INFO]   javax.servlet:javax.servlet-api ....................... 3.1.0 -> 4.0.1
[INFO]   org.eclipse.jetty.websocket:javax-websocket-server-impl ...
[INFO]                                           9.2.21.v20170120 -> 9.4.12.RC1
[INFO]   org.mockito:mockito-core ............................. 2.8.9 -> 2.21.0
[INFO]   org.msgpack:jackson-dataformat-msgpack .............. 0.8.12 -> 0.8.16
[INFO]   org.slf4j:slf4j-api ............................ 1.7.25 -> 1.8.0-beta2
[INFO]
[INFO]
[INFO] --- versions-maven-plugin:2.3:display-property-updates (default-cli) @ cettia-server ---
[INFO]
[INFO] This project does not have any properties associated with versions.
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] Cettia Server ...................................... SUCCESS [ 19.732 s]
[INFO] Cettia Server/Server ............................... SUCCESS [  2.812 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 25.242 s
[INFO] Finished at: 2018-08-07T22:19:42+09:00
[INFO] Final Memory: 19M/196M
[INFO] ------------------------------------------------------------------------

C:\Users\Donghwan\git\cettia-java-server>

Binary event

Derived from cettia/cettia-protocol#9

With this feature, you will be able to exchange events whose data is binary without binary-to-text conversion.

  • Find MessagePack Java implementation
  • Implement the default behavior of send method

Add an Action interface extending Serializable

Asity's Action is not serializable, and not compatible with clustered environments. The current solution is either writing a class implementing Action and Serializable like the SendAction in Sentence or using cast expressions of Java 8 like (Action<ServerSocket> & Serializable) socket -> {}.

With SerializableAction, we can allow to use plain lambdas without using cast expressions.

  • Write a io.cettia.SerializableAction and replace Sentence's private interface of the same name with this one.

It is an io.cettia.asity.action.Action that extends Serializable. BTW, we could add this serialized version to Asity like io.cettia.asity.action.SerializableAction too and use it in Cettia 2?.

  • Replace method signatures whose arguments are supposed to be serialized
    • Server all(SerializableAction<ServerSocket> action)
    • Server byTag(SerializableAction<ServerSocket> action)

This breaks the backward compatibility but I think it would be fine because the recommended usage has been using Sentence and using lambda is not the case.

A predicate to test against the socket attributes

  • Add ServerSocketPredicate attr(String name, Object value) to ServerSocketPredicates.

It returns a predicate that tests the socket attributes against the given key-value pair.

As is

server.find(socket -> socket.get("clientId").equals(receiverId)).send("offer", msg);

To be

server.find(ServerSocketPredicates.attr("clientId", receiverId)).send("offer", msg);

Update dependencies

FYI

➜  cettia-java-server git:(master)  mvn versions:display-plugin-updates versions:display-dependency-updates versions:display-property-updates
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO] 
[INFO] Cettia Server
[INFO] Cettia Server/Server
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building Cettia Server 1.0.0-Beta2-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- versions-maven-plugin:2.2:display-plugin-updates (default-cli) @ cettia-server-parent ---
[INFO] 
[INFO] All plugins with a version specified are using the latest versions.
[INFO] 
[WARNING] The following plugins do not have their version specified:
[WARNING]   maven-clean-plugin .......................... (from super-pom) 2.2
[WARNING]   maven-deploy-plugin ......................... (from super-pom) 2.4
[WARNING]   maven-install-plugin ........................ (from super-pom) 2.2
[WARNING]   maven-site-plugin .................... (from super-pom) 2.0-beta-4
[INFO] 
[WARNING] Project does not define minimum Maven version, default is: 2.0
[INFO] Plugins require minimum Maven version of: 3.1.0
[INFO] Note: the super-pom from Maven 3.3.9 defines some of the plugin
[INFO]       versions and may be influencing the plugins required minimum Maven
[INFO]       version.
[INFO] 
[ERROR] Project does not define required minimum version of Maven.
[ERROR] Update the pom.xml to contain
[ERROR]     <prerequisites>
[ERROR]       <maven>3.1.0</maven>
[ERROR]     </prerequisites>
[INFO] 
[INFO] Require Maven 2.0.1 to use the following plugin updates:
[INFO]   maven-eclipse-plugin ............................................ 2.8
[INFO]   maven-release-plugin ..................................... 2.0-beta-7
[INFO] 
[INFO] Require Maven 2.0.2 to use the following plugin updates:
[INFO]   maven-javadoc-plugin ............................................ 2.2
[INFO]   maven-site-plugin ........................................ 2.0-beta-7
[INFO] 
[INFO] Require Maven 2.0.6 to use the following plugin updates:
[INFO]   maven-clean-plugin .............................................. 2.5
[INFO]   maven-deploy-plugin ........................................... 2.8.1
[INFO]   maven-install-plugin .......................................... 2.5.1
[INFO]   maven-javadoc-plugin ............................................ 2.3
[INFO]   maven-release-plugin ..................................... 2.0-beta-9
[INFO]   maven-site-plugin ............................................. 2.0.1
[INFO] 
[INFO] Require Maven 2.0.8 to use the following plugin updates:
[INFO]   maven-eclipse-plugin ............................................ 2.9
[INFO]   maven-javadoc-plugin ............................................ 2.4
[INFO] 
[INFO] Require Maven 2.0.9 to use the following plugin updates:
[INFO]   maven-javadoc-plugin .......................................... 2.8.1
[INFO]   maven-release-plugin .......................................... 2.2.2
[INFO] 
[INFO] Require Maven 2.1.0 to use the following plugin updates:
[INFO]   maven-site-plugin ............................................. 2.1.1
[INFO] 
[INFO] Require Maven 2.2.0 to use the following plugin updates:
[INFO]   maven-site-plugin ............................................... 3.0
[INFO] 
[INFO] Require Maven 2.2.1 to use the following plugin updates:
[INFO]   maven-clean-plugin ............................................ 2.6.1
[INFO]   maven-deploy-plugin ........................................... 2.8.2
[INFO]   maven-eclipse-plugin ........................................... 2.10
[INFO]   maven-install-plugin .......................................... 2.5.2
[INFO]   maven-javadoc-plugin ......................................... 2.10.3
[INFO]   maven-release-plugin .......................................... 2.5.2
[INFO]   maven-site-plugin ............................................... 3.4
[INFO] 
[INFO] Require Maven 3.0 to use the following plugin updates:
[INFO]   maven-clean-plugin ............................................ 3.0.0
[INFO]   maven-javadoc-plugin ......................................... 2.10.4
[INFO]   maven-release-plugin .......................................... 2.5.3
[INFO]   maven-site-plugin ............................................... 3.6
[INFO] 
[INFO] Require Maven 3.1.0 to use the following plugin updates:
[INFO]   com.github.eirslett:frontend-maven-plugin ....................... 1.4
[INFO] 
[INFO] 
[INFO] --- versions-maven-plugin:2.2:display-dependency-updates (default-cli) @ cettia-server-parent ---
[INFO] The following dependencies in Dependency Management have newer versions:
[INFO]   ch.qos.logback:logback-classic ........................ 1.1.4 -> 1.2.3
[INFO]   ch.qos.logback:logback-core ........................... 1.1.4 -> 1.2.3
[INFO]   com.fasterxml.jackson.core:jackson-databind ..... 2.7.1-1 -> 2.9.0.pr3
[INFO]   org.eclipse.jetty.websocket:javax-websocket-server-impl ...
[INFO]                                      9.2.15.v20160210 -> 9.4.5.v20170502
[INFO]   org.msgpack:jackson-dataformat-msgpack ............... 0.8.3 -> 0.8.12
[INFO]   org.slf4j:slf4j-api ........................... 1.7.16 -> 1.8.0-alpha2
[INFO] 
[INFO] 
[INFO] --- versions-maven-plugin:2.2:display-property-updates (default-cli) @ cettia-server-parent ---
[INFO] 
[INFO] The following version properties are referencing the newest available version:
[INFO]   ${asity.version} ........................................ 1.0.0-Beta1
[INFO] The following version property updates are available:
[INFO]   ${slf4j.version} ............................. 1.7.16 -> 1.8.0-alpha2
[INFO]   ${logback.version} ................................... 1.1.4 -> 1.2.3
[INFO] 
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building Cettia Server/Server 1.0.0-Beta2-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- versions-maven-plugin:2.2:display-plugin-updates (default-cli) @ cettia-server ---
[INFO] 
[INFO] All plugins with a version specified are using the latest versions.
[INFO] 
[WARNING] The following plugins do not have their version specified:
[WARNING]   maven-clean-plugin .......................... (from super-pom) 2.2
[WARNING]   maven-compiler-plugin ..................... (from super-pom) 2.0.2
[WARNING]   maven-deploy-plugin ......................... (from super-pom) 2.4
[WARNING]   maven-install-plugin ........................ (from super-pom) 2.2
[WARNING]   maven-jar-plugin ............................ (from super-pom) 2.1
[WARNING]   maven-resources-plugin ...................... (from super-pom) 2.2
[WARNING]   maven-site-plugin .................... (from super-pom) 2.0-beta-4
[WARNING]   maven-surefire-plugin ..................... (from super-pom) 2.4.2
[INFO] 
[WARNING] Project does not define minimum Maven version, default is: 2.0
[INFO] Plugins require minimum Maven version of: 3.0
[INFO] Note: the super-pom from Maven 3.3.9 defines some of the plugin
[INFO]       versions and may be influencing the plugins required minimum Maven
[INFO]       version.
[INFO] 
[ERROR] Project does not define required minimum version of Maven.
[ERROR] Update the pom.xml to contain
[ERROR]     <prerequisites>
[ERROR]       <maven>3.0</maven>
[ERROR]     </prerequisites>
[INFO] 
[INFO] Require Maven 2.0.2 to use the following plugin updates:
[INFO]   maven-site-plugin ........................................ 2.0-beta-7
[INFO] 
[INFO] Require Maven 2.0.6 to use the following plugin updates:
[INFO]   maven-clean-plugin .............................................. 2.5
[INFO]   maven-deploy-plugin ........................................... 2.8.1
[INFO]   maven-install-plugin .......................................... 2.5.1
[INFO]   maven-jar-plugin ................................................ 2.4
[INFO]   maven-resources-plugin .......................................... 2.6
[INFO]   maven-site-plugin ............................................. 2.0.1
[INFO]   maven-surefire-plugin ......................................... 2.4.3
[INFO] 
[INFO] Require Maven 2.0.9 to use the following plugin updates:
[INFO]   maven-compiler-plugin ........................................... 3.1
[INFO]   maven-surefire-plugin .......................................... 2.17
[INFO] 
[INFO] Require Maven 2.1.0 to use the following plugin updates:
[INFO]   maven-site-plugin ............................................. 2.1.1
[INFO] 
[INFO] Require Maven 2.2.0 to use the following plugin updates:
[INFO]   maven-site-plugin ............................................... 3.0
[INFO] 
[INFO] Require Maven 2.2.1 to use the following plugin updates:
[INFO]   maven-clean-plugin ............................................ 2.6.1
[INFO]   maven-compiler-plugin ........................................... 3.3
[INFO]   maven-deploy-plugin ........................................... 2.8.2
[INFO]   maven-install-plugin .......................................... 2.5.2
[INFO]   maven-jar-plugin ................................................ 2.6
[INFO]   maven-resources-plugin .......................................... 2.7
[INFO]   maven-site-plugin ............................................... 3.4
[INFO]   maven-surefire-plugin .......................................... 2.20
[INFO] 
[INFO] Require Maven 3.0 to use the following plugin updates:
[INFO]   maven-clean-plugin ............................................ 3.0.0
[INFO]   maven-compiler-plugin ......................................... 3.6.1
[INFO]   maven-jar-plugin .............................................. 3.0.2
[INFO]   maven-resources-plugin ........................................ 3.0.2
[INFO]   maven-site-plugin ............................................... 3.6
[INFO] 
[INFO] 
[INFO] --- versions-maven-plugin:2.2:display-dependency-updates (default-cli) @ cettia-server ---
[INFO] The following dependencies in Dependency Management have newer versions:
[INFO]   ch.qos.logback:logback-classic ........................ 1.1.4 -> 1.2.3
[INFO]   ch.qos.logback:logback-core ........................... 1.1.4 -> 1.2.3
[INFO]   com.fasterxml.jackson.core:jackson-databind ..... 2.7.1-1 -> 2.9.0.pr3
[INFO]   org.eclipse.jetty.websocket:javax-websocket-server-impl ...
[INFO]                                      9.2.15.v20160210 -> 9.4.5.v20170502
[INFO]   org.msgpack:jackson-dataformat-msgpack ............... 0.8.3 -> 0.8.12
[INFO]   org.slf4j:slf4j-api ........................... 1.7.16 -> 1.8.0-alpha2
[INFO] 
[INFO] 
[INFO] --- versions-maven-plugin:2.2:display-property-updates (default-cli) @ cettia-server ---
[INFO] 
[INFO] This project does not have any properties associated with versions.
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] 
[INFO] Cettia Server ...................................... SUCCESS [  2.627 s]
[INFO] Cettia Server/Server ............................... SUCCESS [  1.507 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.648 s
[INFO] Finished at: 2017-05-04T13:24:11+09:00
[INFO] Final Memory: 24M/512M
[INFO] ------------------------------------------------------------------------

Add java.util.function.Predicate's default methods to ServerSocketPredicate

They do exactly the same thing with default methods defined in java.util.function.Predicate.

  • default ServerSocketPredicate and(ServerSocketPredicate other)

Returns a composed predicate that represents a short-circuiting logical AND of this predicate and another.

  • default ServerSocketPredicate negate()

Returns a predicate that represents the logical negation of this predicate.

  • default ServerSocketPredicate or(ServerSocketPredicate other)

Review TransportServer interface

TransportServer consumes resource and produces ServerTransport. For example, HttpTransportServer consumes ServerHttpExchange and produces streaming transport and long polling transport. But, that's all. It is the only purpose of TransportServer.

  • Interface name
    Server also consumes transport and produces socket but besides other functionalities like finding socket are also provided as Cettia server. On the other hand, TransportServer does not and should not provide such unnecessary features. In that sense, I feel TransportServer is awkward but couldn't find other proper name. Otherwise, we may need a general term for such interface.
  • Maven artifact
    For those who want to use Cettia transport only e.g. to build custom protocol on top of Cettia transport layer, cettia-transport-server module should be separated from cettia-server module.

Allow to match sockets using ServerSocketPredicate

The basic concept of Cettia is "select some sockets and do something with them". In order for users to do this intuitively, we need to provide a method to match sockets first.

  • Implement Sentence select(ServerSocketPredicate predicate) method in Server

It should create a Sentence that will match the given predicate for sockets. For the definition of ServerSocketPredicate, see @ralscha's #22 (comment). Here's an example:

server.select(socket -> socket.tags().stream().foo.bar).send("event", data);

A collection of useful ServerSocketPredicate

The current finder methods like Server#byTag(String... tagNames) are not flexible enough to describe complex conditions including simple OR condition. In Java 8, we can improve it with lambdas. Spring WebFlux's RequestPredicate and RequestPredicates are good examples.

As with RequestPredicates, we could improve reusability and flexibility in selecting sockets by offering ServerSocketPredicates for the same purpose.

import static io.cettia.ServerSocketPredicates.*;

// ...

server.find(tag("foo").or(tag("bar"))).send(event);

This discussion is ongoing - https://groups.google.com/d/msg/cettia/xk4EU2N2Tc0/MZo-vaO8AAAJ

Add support for resolving HttpSession from Servlet applications

We got a feedback that a process to find javax.servlet.http.HttpSession from a socket is somewhat lengthy. Of course, it can be concise with the helper like this:

Server server = new DefaultServer();
server.onsocket(socket -> {
  HttpSessionResolver httpSessionResolver = new HttpSessionResolver();
  HttpSession httpSession = httpSessionResolver.resolve(socket);
  
  Set<String> tags = (Set<String>) httpSession.getAttribute("tags");
  socket.tags().addAll(tags);
});

Allow to add key/value pairs to a socket i.e. a socket scope

Basically, it is analogous to the request scope defined in Servlet specification so that this attribute set should be initialized and destroyed along with the lifecycle of the socket.

  • Implement <T> T get(String name) in ServerSocket

It should return the value mapped to the given name.

  • Implement ServerSocket socket.set(String name, Object value)

It should associate the value with the given name.

  • Implement ServerSocket socket.remove(String name)

It should remove the value associated with the given name.

Furthermore, we can this attributes to manipulate a selection for socket delicately i.e. Sentence like server.all().has("is-admin", true).send("foo", "bar").

See the discussion at https://groups.google.com/d/topic/cettia/xAzTTqfY4FQ/discussion

Allow to deal with sockets through Sentence

The needs of this feature is the same of #24, and this issue covers 'do something with them'.

  • Implement Sentence execute(SerializableAction<ServerSocket> action)

It allows to deal with sockets directly like Server#all(SerializableAction<ServerSocket>) but through any Sentence object. Here's an example:

server.select(socket -> socket.tags().stream().foo.bar).execute(socket -> {
  // Do complex things with socket
});

Rewrite finder methods using default methods

Awesome. Thanks to default methods of Java 8, we can implement finder methods in an interface like the following:

interface Server extends Action<ServerTransport> {
  // Skipped
  default Sentence all() {
    return find(socket -> true);
  }
}

Massive thread consumption when tens of thousands of connected clients (OOMs)

We have been using this library in production and under extreme load (tens of thousands of connected clients) our services were OOMing. Tracked it down to thread pools being created in the DefaultServer.DefaultServerSocket code where it creates a new scheduled thread pool for every connection.

I've submitted a PR that fixed this issue for us in production, some additional notes in the PR but basically it creates a pool of workers that are shared and a scheduled executor that handles starting everything. PR is here: #18

We saw this in both a beta version we were using and the current 1.0 version (implementation hasn't changed between the two).

Rewrite ClusteredServer

The current implementation deals with each of finders: find, all, byTag. Now that finders are to be deprecated #41 and delegated the method calls to a find(ServerSocketPredicate predicate, SerializableAction<ServerSocket> action) internally, we only have to support the find(ServerSocketPredicate predicate, SerializableAction<ServerSocket> action).

Exception after restarting the server while client is connected

This behaviour can be reproduces with any of my example applications (https://github.com/ralscha/cettia-demo).

  1. Start server
  2. Open browser (http://localhost:8080/)
  3. Restart server (while browser is still open)

The server throws this exception.

Caused by: java.lang.NullPointerException: null
	at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:936) ~[na:1.8.0_181]
	at io.cettia.transport.http.HttpTransportServer.on(HttpTransportServer.java:171) ~[cettia-server-1.1.0-Beta1.jar:na]
	at io.cettia.transport.http.HttpTransportServer.on(HttpTransportServer.java:61) ~[cettia-server-1.1.0-Beta1.jar:na]
	at io.cettia.asity.action.AbstractActions.fireOne(AbstractActions.java:113) ~[asity-action-2.0.0.jar:na]
	at io.cettia.asity.action.AbstractActions.fire(AbstractActions.java:86) ~[asity-action-2.0.0.jar:na]
	at io.cettia.asity.bridge.spring.webflux5.AsityHandlerFunction.lambda$handle$0(AsityHandlerFunction.java:55) ~[asity-bridge-spring-webflux5-2.0.0.jar:na]
	at reactor.core.publisher.FluxDoFinally$DoFinallySubscriber.runFinally(FluxDoFinally.java:156) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
	... 50 common frames omitted

It's not a big deal, because the client is able to reconnect to the server.

Expose socket state

The original purpose is to regard socket as stateless by forcing user to create a socket action and pass it to server's selector method like all(Action<Socket> action) or byId(String id, Action<Socket> action). However, we have no option but to admit that socket is stateful as it is required to deal with socket whose connection is disconnected for a little while.

A need to expose socket state is to determine socket state at any time of course. For example, user might want to cache some events on cache event which couldn't be sent due to temporal disconnection and send them again on open event. If a connection is broken abruptly in triggering open event handler, it may cause infinite loop so that it should check if socket is in opened state or not.

A predicate to exclude a certain socket

  • Add ServerSocketPredicate id(ServerSocket socket) to ServerSocketPredicates.
  • Add ServerSocketPredicate id(String id) to ServerSocketPredicates.

It returns a predicate that tests the socket id with the given socket's id or socket id.

As is

server.find(skt -> !socket.id().equals(skt.id())).send("chat", msg);

To be

server.find(ServerSocketPredicates.id(skt).negate()).send("chat", msg);

io.cettia.HeartbeatFailedException: null

io.cettia.HeartbeatFailedException: null
	at io.cettia.DefaultServer$DefaultServerSocket$6.run(DefaultServer.java:261)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)

Unsure what this means but it would appear that actionsMap.get("error") is null when it shouldn't be. Either a check for null or it is being called in the incorrect state.

Update dependencies

C:\Users\Donghwan\git\cettia-java-server> mvn versions:display-plugin-updates versions:display-dependency-updates versions:display-property-updates
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO]
[INFO] Cettia Server
[INFO] Cettia Server/Server
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Cettia Server 1.2.0-Beta1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- versions-maven-plugin:2.3:display-plugin-updates (default-cli) @ cettia-server-parent ---
[INFO]
[INFO] All plugins with a version specified are using the latest versions.
[INFO]
[WARNING] The following plugins do not have their version specified:
[WARNING]   maven-clean-plugin ........................ (from super-pom) 3.0.0
[WARNING]   maven-deploy-plugin ....................... (from super-pom) 2.8.2
[WARNING]   maven-install-plugin ...................... (from super-pom) 2.5.2
[WARNING]   maven-site-plugin ........................... (from super-pom) 3.7
[INFO]
[INFO] Project defines minimum Maven version as: 3.1.0
[INFO] Plugins require minimum Maven version of: 3.1.0
[INFO] Note: the super-pom from Maven 3.3.9 defines some of the plugin
[INFO]       versions and may be influencing the plugins required minimum Maven
[INFO]       version.
[INFO]
[INFO] No plugins require a newer version of Maven than specified by the pom.
[INFO]
[INFO]
[INFO] --- versions-maven-plugin:2.3:display-dependency-updates (default-cli) @ cettia-server-parent ---
[INFO] artifact com.fasterxml.jackson.core:jackson-databind: checking for updates from central
[INFO] artifact ch.qos.logback:logback-core: checking for updates from central
[INFO] artifact io.cettia:cettia-server: checking for updates from sonatype-nexus-snapshots
[INFO] artifact ch.qos.logback:logback-classic: checking for updates from central
[INFO] artifact io.cettia.asity:asity-bridge-jwa1: checking for updates from central
[INFO] artifact io.cettia.asity:asity-http: checking for updates from central
[INFO] artifact io.cettia.asity:asity-bridge-servlet3: checking for updates from central
[INFO] artifact io.cettia.asity:asity-websocket: checking for updates from central
[INFO] artifact javax.servlet:javax.servlet-api: checking for updates from central
[INFO] artifact javax.websocket:javax.websocket-api: checking for updates from central
[INFO] artifact junit:junit: checking for updates from central
[INFO] artifact org.apache.commons:commons-exec: checking for updates from central
[INFO] artifact org.eclipse.jetty.websocket:javax-websocket-server-impl: checking for updates from central
[INFO] artifact org.hamcrest:hamcrest-all: checking for updates from central
[INFO] artifact org.mockito:mockito-core: checking for updates from central
[INFO] artifact org.msgpack:jackson-dataformat-msgpack: checking for updates from central
[INFO] artifact org.slf4j:slf4j-api: checking for updates from central
[INFO] The following dependencies in Dependency Management have newer versions:
[INFO]   ch.qos.logback:logback-classic ................. 1.2.3 -> 1.3.0-alpha4
[INFO]   ch.qos.logback:logback-core .................... 1.2.3 -> 1.3.0-alpha4
[INFO]   io.cettia.asity:asity-bridge-jwa1 ..................... 1.0.0 -> 2.0.0
[INFO]   io.cettia.asity:asity-bridge-servlet3 ................. 1.0.0 -> 2.0.0
[INFO]   io.cettia.asity:asity-http ............................ 1.0.0 -> 2.0.0
[INFO]   io.cettia.asity:asity-websocket ....................... 1.0.0 -> 2.0.0
[INFO]   javax.servlet:javax.servlet-api ....................... 3.1.0 -> 4.0.1
[INFO]   org.eclipse.jetty.websocket:javax-websocket-server-impl ...
[INFO]                                     9.2.24.v20180105 -> 9.4.12.v20180830
[INFO]   org.mockito:mockito-core ............................ 2.21.0 -> 2.22.0
[INFO]   org.slf4j:slf4j-api ............................ 1.7.25 -> 1.8.0-beta2
[INFO]
[INFO]
[INFO] --- versions-maven-plugin:2.3:display-property-updates (default-cli) @ cettia-server-parent ---
[INFO]
[INFO] The following version property updates are available:
[INFO]   ${slf4j.version} .............................. 1.7.25 -> 1.8.0-beta2
[INFO]   ${asity.version} ..................................... 1.0.0 -> 2.0.0
[INFO]   ${logback.version} ............................ 1.2.3 -> 1.3.0-alpha4
[INFO]
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Cettia Server/Server 1.2.0-Beta1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- versions-maven-plugin:2.3:display-plugin-updates (default-cli) @ cettia-server ---
[INFO]
[INFO] All plugins with a version specified are using the latest versions.
[INFO]
[WARNING] The following plugins do not have their version specified:
[WARNING]   maven-clean-plugin ........................ (from super-pom) 3.0.0
[WARNING]   maven-compiler-plugin ..................... (from super-pom) 3.7.0
[WARNING]   maven-deploy-plugin ....................... (from super-pom) 2.8.2
[WARNING]   maven-install-plugin ...................... (from super-pom) 2.5.2
[WARNING]   maven-jar-plugin .......................... (from super-pom) 3.0.2
[WARNING]   maven-resources-plugin .................... (from super-pom) 3.0.2
[WARNING]   maven-site-plugin ........................... (from super-pom) 3.7
[WARNING]   maven-surefire-plugin .................... (from super-pom) 2.20.1
[INFO]
[INFO] Project inherits minimum Maven version as: 3.1.0
[INFO] Plugins require minimum Maven version of: 3.0
[INFO] Note: the super-pom from Maven 3.3.9 defines some of the plugin
[INFO]       versions and may be influencing the plugins required minimum Maven
[INFO]       version.
[INFO]
[INFO] No plugins require a newer version of Maven than specified by the pom.
[INFO]
[INFO]
[INFO] --- versions-maven-plugin:2.3:display-dependency-updates (default-cli) @ cettia-server ---
[INFO] The following dependencies in Dependency Management have newer versions:
[INFO]   ch.qos.logback:logback-classic ................. 1.2.3 -> 1.3.0-alpha4
[INFO]   ch.qos.logback:logback-core .................... 1.2.3 -> 1.3.0-alpha4
[INFO]   io.cettia.asity:asity-bridge-jwa1 ..................... 1.0.0 -> 2.0.0
[INFO]   io.cettia.asity:asity-bridge-servlet3 ................. 1.0.0 -> 2.0.0
[INFO]   io.cettia.asity:asity-http ............................ 1.0.0 -> 2.0.0
[INFO]   io.cettia.asity:asity-websocket ....................... 1.0.0 -> 2.0.0
[INFO]   javax.servlet:javax.servlet-api ....................... 3.1.0 -> 4.0.1
[INFO]   org.eclipse.jetty.websocket:javax-websocket-server-impl ...
[INFO]                                     9.2.24.v20180105 -> 9.4.12.v20180830
[INFO]   org.mockito:mockito-core ............................ 2.21.0 -> 2.22.0
[INFO]   org.slf4j:slf4j-api ............................ 1.7.25 -> 1.8.0-beta2
[INFO]
[INFO]
[INFO] --- versions-maven-plugin:2.3:display-property-updates (default-cli) @ cettia-server ---
[INFO]
[INFO] This project does not have any properties associated with versions.
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] Cettia Server ...................................... SUCCESS [ 43.608 s]
[INFO] Cettia Server/Server ............................... SUCCESS [  2.406 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 56.752 s
[INFO] Finished at: 2018-09-11T22:51:24+09:00
[INFO] Final Memory: 18M/219M
[INFO] ------------------------------------------------------------------------

C:\Users\Donghwan\git\cettia-java-server>

socket.uri should be available on server's socket event

When a transport has been opened, a socket is created and fired through the socket event. Since the handshake is done after dispatching the event, the socket should not have the transport so that socket.uri returns null.

However, the socket event is designed to initiate business logics associated with socket like authentication so socket.uri should be available on the socket event.

Implement open, delete, cache event

The close event has been enough to handle socket's life cycle so far because a socket is closed only once in its life time but now that socket's life cycle is extended, a socket can be closed and opened many times and deleted from the server due to long-term disconnection. That's why we need more events to describe such events. Here's definitions of each event:

  • server's socket - It is called when a server receives a transport and a socket is newly created. It's the beginning of the life cycle. Unlike Alpha1 it can't exchange event here since the handshake is not performed yet.
  • open - It is called when the handshake is performed successfully and communication is possible. It can be called more than once like close.
  • close - It is called when the underlying transport is closed for any reason. It's the same with one of Alpha1 but can be called more than once like open.
  • delete - It is called when a socket is closed for a long time i.e. 1 minute and deleted from the server. It's the end of the life cycle.
  • cache - It is called when some event is sent while connection is disconnected where socket state is not opened. It takes an object array of event name, event data, resolved callback and rejected callback.

For the overall context of this feature, see cettia/cettia-protocol#1.

Add find(ServerSocketPredicate predicate) to Sentence

EDIT - See #34 (comment) instead of the body.


To improve the reusability of Sentence, I propose to add finder methods such as byTag(String tags...)to Sentence. It would be analogous to jQuery.prototype.find if you ever have used it.

Sentence user = server.find(s -> username.equals(s.get("username"))).send("something");

And then

user.find(s -> s.tags().contains("mobile")).send("bye").close();

Or

user.byTag("mobile").send("bye").close();

Drop support for Java 7

I have thought that we have to drop support for Java 7 in a new major release (2.0.0) but now think we can do that in a minor release (1.2 or 1.3) since 1.1 will be full-featured and no one seems to use Cettia with Java 7. As a bonus, I found that Jetty dropped support for Java 7 as of a minor release, 9.3.

  • Update .travis.yml.
  • Replace anonymous type with lambda expression.
  • Replace lambda expression with method reference.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.