io.hekate.network.NetworkService Maven / Gradle / Ivy
Show all versions of hekate-core Show documentation
/*
* Copyright 2020 The Hekate Project
*
* The Hekate Project licenses this file to you 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 io.hekate.network;
import io.hekate.codec.Codec;
import io.hekate.codec.CodecFactory;
import io.hekate.core.Hekate;
import io.hekate.core.HekateBootstrap;
import io.hekate.core.service.DefaultServiceFactory;
import io.hekate.core.service.Service;
import java.net.InetSocketAddress;
import java.util.List;
/**
* « start hereEntry point to TCP-based client/server communication API.
*
* Overview
*
* {@link NetworkService} provides an abstraction layer on top of sockets API for building connection-oriented communication protocols.
*
*
*
* - Service Configuration
* - Connectors
* - Connectors Configuration
* - Protocol Identifier
* - SSL Encryption
* - Data Serialization
* - Thread Management
* - Example
*
*
*
* Service Configuration
*
* {@link NetworkService} can be configured and registered within the {@link HekateBootstrap} via the {@link NetworkServiceFactory} class
* as in the example below:
*
*
*
*
* - Java
* - Spring XSD
* - Spring bean
*
*
* ${source: network/NetworkServiceJavadocTest.java#config}
*
*
* Note: This example requires Spring Framework integration
* (see HekateSpringBootstrap).
* ${source: network/service-xsd.xml#example}
*
*
* Note: This example requires Spring Framework integration
* (see HekateSpringBootstrap).
* ${source: network/service-bean.xml#example}
*
*
*
*
* Please see the documentation of {@link NetworkServiceFactory} class for more details about the available configuration options.
*
*
*
* Connectors
*
* Communication units in the {@link NetworkService} are represented by the {@link NetworkConnector} interface. This interface provides API
* for creating client connections based on the connector options as well as accepting connections from remote clients (optional).
*
*
*
* The client side of a connector API is represented by the {@link NetworkClient} interface. Each client manages a single socket
* connection and provides API for connecting to remote endpoints and sending/receiving messages to/from them. Instances if this interface
* can be be obtained from {@link NetworkConnector} as illustrated in the example below.
*
*
*
* The server side of a connector API is represented by the {@link NetworkServerHandler} interface. This interface provides callback
* methods that get notified upon various events of remote clients (connects, disconnects, new messages, etc). Instances of this
* interface can be registered via {@link NetworkConnectorConfig#setServerHandler(NetworkServerHandler)} method as illustrated in the
* example below.
*
*
*
* Note: {@link NetworkServerHandler} is optional and if not specified for particular {@link NetworkConnector} then such connector
* will act in a pure client mode and will not be able to accept connections from remote addresses.
*
*
*
* Connectors Configuration
*
* {@link NetworkConnector} configuration is represented by the {@link NetworkConnectorConfig} class. Please see its documentation for the
* complete list of all available configuration options.
*
*
*
* Instances of this class can be registered within the {@link NetworkService} via {@link NetworkServiceFactory#setConnectors(List)}
* method.
*
*
*
* Protocol Identifier
*
* Each connector must have a protocol identifier. This identifier is used by the {@link NetworkService} to select which {@link
* NetworkConnector} should be responsible for processing each particular connection from a remote {@link NetworkClient}. When {@link
* NetworkClient} established a new connection to a remote {@link NetworkService} it submits its protocol identifier as part of an initial
* handshake message. This identifier is used by the remote {@link NetworkService} to select a {@link NetworkConnector} instance that is
* configured with exactly the same protocol identifier. If such instance can be found then all subsequent communication events will be
* handled by its {@link NetworkServerHandler}. If such instance can't be found then connection will be rejected.
*
*
*
* SSL Encryption
*
* It is possible to configure {@link NetworkService} to use secure communications by setting {@link
* NetworkServiceFactory#setSsl(NetworkSslConfig) SSL configuration}. Please see the documentation of the {@link NetworkSslConfig}
* class for available configuration options.
*
*
*
* Note that SSL encryption will be applied to all network communications at the cluster node level, thus it is important to make sure that
* all nodes in the cluster are configured to use SSL encryption. Mixed mode, when some nodes do use SSL and some do not use it, is not
* supported. In such case non-SSL nodes will not be able to connect to SSL-enabled nodes and vice versa.
*
*
*
* Protocol identifier must be specified within the {@link NetworkConnector} configuration via {@link
* NetworkConnectorConfig#setProtocol(String)} method.
*
*
*
* Data Serialization
*
* Data serialization and deserialization within connectors is handled by the {@link Codec} interface. Instances of this interface can
* be specified for each connector independently via {@link NetworkConnectorConfig#setMessageCodec(CodecFactory)} method. If not
* specified the the default general purpose codec of a {@link Hekate} instance will be used (see {@link
* HekateBootstrap#setDefaultCodec(CodecFactory)}).
*
*
*
* Please see the documentation of {@link Codec} interface for more details about data serialization.
*
*
*
* Thread Management
*
* {@link NetworkService} manages a core NIO thread pool of {@link NetworkServiceFactory#setNioThreads(int)} size. This thread pools
* is used to process all incoming and outgoing connections by default.
*
*
*
* It is also possible to configure each {@link NetworkConnector} to use its own thread pool via {@link
* NetworkConnectorConfig#setNioThreads(int)} option. In such case all incoming and outgoing connections of that connector will be
* handled by a dedicated thread pool of the specified size and will not interfere with {@link NetworkService}'s core thread nor with
* thread pool of any other connector.
*
*
*
* Whenever a new connection is created by the connector (either {@link NetworkClient client connection} or {@link
* NetworkServerHandler#onConnect(Object, NetworkEndpoint)} server connection}) it obtains a worker thread from the {@link
* NetworkConnector}'s thread pool and uses this thread to process all of the NIO events. Due to the event-based nature of NIO each thread
* can handle multiple connections and doesn't require a one-to-one relationship between the pool size and the amount of active
* connections. Typically thread pool size must be much less than the number of active connections. When connection gets closed it
* unregisters itself from its worker thread.
*
*
*
* Example
*
* The code example below shows how {@link NetworkService} can be used to implement client/server communications. For the sake of brevity
* this example uses the default Java serialization and messages of {@link String} type. For real world applications it is recommended to
* implement custom message classes and provide a more optimized implementation of {@link Codec} in order to increase communication
* speed and to support a more complex application logic.
*
*
*
* Server Example
*
* 1) Prepare server handler.
* ${source: network/NetworkServiceJavadocTest.java#server_handler_example}
*
*
*
*
* 2) Prepare connector configuration.
* ${source: network/NetworkServiceJavadocTest.java#server_handler_config_example}
*
*
*
* 3) Start new node.
* ${source: network/NetworkServiceJavadocTest.java#server_example}
*
*
*
* Client Example
*
* Note: This example uses the same connector configuration as in the server example.
*
*
*
* 1) Instantiate a new client and connect to the server.
* ${source: network/NetworkServiceJavadocTest.java#client_connect_example}
*
*
*
* 2) Start sending messages (can be done even if connection establishment is still in progress).
* ${source: network/NetworkServiceJavadocTest.java#client_send_example}
*
*
* @see NetworkServiceFactory
*/
@DefaultServiceFactory(NetworkServiceFactory.class)
public interface NetworkService extends Service {
/**
* Returns a connector instance for the specified {@link NetworkConnectorConfig#setProtocol(String) protocol name}.
*
*
* Please see the overview section of this class for more details about connectors.
*
*
* @param protocol Protocol name (see {@link NetworkConnectorConfig#setProtocol(String)}).
* @param Base type of connector protocol messages.
*
* @return TCP connector instance.
*
* @throws IllegalArgumentException If there is no such connector with the specified protocol name.
*/
NetworkConnector connector(String protocol) throws IllegalArgumentException;
/**
* Returns {@code true} if this service has a connector with the specified protocol name.
*
* @param protocol Protocol name (see {@link NetworkConnectorConfig#setProtocol(String)}).
*
* @return {@code true} if connector exists.
*/
boolean hasConnector(String protocol);
/**
* Asynchronously checks if connection can be established with a {@link NetworkService} at the specified address and notifies the
* provided callback on operation result.
*
*
* Example:
* ${source: network/NetworkServiceJavadocTest.java#ping}
*
*
* @param address Address.
* @param callback Callback to be notified.
*
* @see NetworkPingResult
*/
void ping(InetSocketAddress address, NetworkPingCallback callback);
}