DEV Community

三刀
三刀

Posted on

A Lightweight Java AIO Framework for Long-Lived Connections

smart-socket: simple API, small core, built for custom protocols and high connection counts.


The problem with “just use Netty”

Netty is the default choice for high-performance networking in Java — and for good reason. It is mature, battle-tested, and has a huge ecosystem.

But it is also heavy.

If you only need:

  • Long-lived TCP connections
  • A custom binary or text protocol
  • A small, understandable networking layer

…you often end up carrying a lot of concepts, classes, and configuration that you never use.

Java’s built-in AIO (NIO.2) looked promising as a simpler alternative. In practice, many teams found it limited under high connection counts: scheduling inefficiencies, higher memory cost per connection, and occasional stability issues under stress.

That gap is where smart-socket sits.


What is smart-socket?

smart-socket is an open-source Java framework that keeps an AIO-style programming model while reimplementing the underlying engine for better efficiency and reliability.

Core ideas:

  • Only two interfaces to implement: Protocol<T> and MessageProcessor<T>
  • A very small, readable core (a few thousand lines)
  • Buffer pooling aimed at large numbers of long-lived connections
  • Explicit connection lifecycle events
  • Optional plugins (SSL/TLS, idle detection, metrics, rate limiting, etc.)

It is not trying to replace Netty for every use case.

It is a focused tool when you want less complexity and tighter control over the transport layer.


Minimal API surface

1. Protocol — turn bytes into messages

public interface Protocol<T> {
    T decode(ByteBuffer readBuffer, AioSession session);
}
Enter fullscreen mode Exit fullscreen mode

Return null when the frame is incomplete (half-packet). That is the entire framing contract.

2. MessageProcessor — handle messages and lifecycle

public interface MessageProcessor<T> {
    void process(AioSession session, T msg);

    default void stateEvent(AioSession session, StateMachineEnum event, Throwable t) {
        // NEW_SESSION, SESSION_CLOSED, DECODE_EXCEPTION, ...
    }
}
Enter fullscreen mode Exit fullscreen mode

3. Bootstrap

// Server
AioQuickServer server = new AioQuickServer(8888, new StringProtocol(), new EchoProcessor());
server.start();

// Client
AioQuickClient client = new AioQuickClient("localhost", 8888, new StringProtocol(), processor);
AioSession session = client.start();
Enter fullscreen mode Exit fullscreen mode

Sending data is straightforward:

WriteBuffer wb = session.writeBuffer();
wb.writeInt(body.length);
wb.write(body);
wb.flush();
Enter fullscreen mode Exit fullscreen mode

No channel pipelines, no bootstrap hierarchies, no codec chains required for the basic case.


A complete echo example

Protocol (length-prefixed UTF-8 string):

public class StringProtocol implements Protocol<String> {
    @Override
    public String decode(ByteBuffer buffer, AioSession session) {
        if (buffer.remaining() < Integer.BYTES) {
            return null;
        }
        buffer.mark();
        int length = buffer.getInt();
        if (length > buffer.remaining()) {
            buffer.reset();
            return null;
        }
        byte[] bytes = new byte[length];
        buffer.get(bytes);
        return new String(bytes, StandardCharsets.UTF_8);
    }
}
Enter fullscreen mode Exit fullscreen mode

Processor:

public class EchoProcessor implements MessageProcessor<String> {
    @Override
    public void process(AioSession session, String msg) {
        byte[] body = msg.getBytes(StandardCharsets.UTF_8);
        WriteBuffer wb = session.writeBuffer();
        try {
            wb.writeInt(body.length);
            wb.write(body);
            wb.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Server:

public class EchoServer {
    public static void main(String[] args) throws Exception {
        new AioQuickServer(8888, new StringProtocol(), new EchoProcessor()).start();
    }
}
Enter fullscreen mode Exit fullscreen mode

Maven dependency:

<dependency>
    <groupId>io.github.smartboot.socket</groupId>
    <artifactId>aio-pro</artifactId>
    <version>2.1.3</version>
</dependency>
Enter fullscreen mode Exit fullscreen mode

Design highlights

Enhanced AIO runtime

smart-socket presents an AIO-style API but uses a carefully tuned asynchronous implementation underneath. The goal is better scheduling behavior and lower overhead for typical server workloads with many concurrent connections, while keeping the programming model familiar.

Memory model

A page-based buffer pool (BufferPagePool + VirtualBuffer) reduces allocation pressure and supports sharing pools across servers/clients when needed. This matters when you hold tens or hundreds of thousands of long-lived connections.

Plugin chain

Cross-cutting concerns stay out of your business code:

Plugin Role
SslPlugin TLS/SSL
IdleStatePlugin Idle / heartbeat
MonitorPlugin Metrics
RateLimiterPlugin Traffic control
StreamMonitorPlugin Byte-level monitoring
BufferPageMonitorPlugin Pool visibility

Extend AbstractMessageProcessor and call addPlugin(...).

Clear state machine

You get explicit callbacks for connection establishment, shutdown, decode/process errors, and accept rejection. That makes it easier to implement reconnect logic, metrics, and graceful close without guessing.


When to choose smart-socket

Good fit

  • Custom binary or text protocols
  • IM, IoT gateways, device management, internal RPC
  • Long-lived TCP connections at scale
  • Teams that want a small core they can actually read
  • Resource-constrained or “keep the stack thin” environments

Probably not the best fit

  • You need a full HTTP/WebSocket stack out of the box
  • You rely heavily on Netty’s ecosystem of codecs and community handlers
  • You want an application framework rather than a focused transport library

Ecosystem

smart-socket is used as the networking foundation for several projects:

  • feat — lightweight high-performance Java web framework
  • smart-mqtt — MQTT broker aimed at large-scale IoT
  • Redisun — lightweight Redis client
  • smart-servlet — Servlet container on the same core

If the framework can power MQTT brokers and web stacks, it is past the “toy project” stage.


Try it

Feedback, issues, and contributions are welcome — especially from people building real long-connection services.

If you have been looking for something lighter than Netty for custom protocols and persistent connections, smart-socket is worth a weekend experiment.

Top comments (0)