smart-socket是什么

smart-socket是什么

smart-socket文档地址

http://smartsocket.mydoc.io/?t=260338

码云地址:

https://gitee.com/smartboot/smart-socket

smart(百度翻译:聪明的;敏捷的;漂亮的;整齐的),从为项目起名开始,便对其寄予了厚望。专注于通信组件的研究与发展,摒弃一切大而全的解决方案,仅提供小而美的基础服务。无论您是从事IOT、IM、RPC,还是其余通信领域的开发工作,相信smart-socket都是非常酷的选择。如果要用一句话来为smart-socket打call,那就是:遇见smart-socket,你就已经赢在起跑线了。 输入图片说明

关于开源

JDK7虽然已经发布很长一段时间了,但开源社区对于其AIO的新特性貌似并不热情。对于通信方面的技术诉求,似乎大家都习惯于Netty、Mina。“Stop Trying to Reinvent the Wheel”不要重复造轮子,几乎每个程序员都被灌输过这个概念,理所当然的沉浸在各自的舒适区,享受着开源社区提供的各项技术支撑。举个跟本文相契合的例子,如果工作中遇到通信相关的需求,广大Java程序员脑海里首先想到的必然是Netty或Mina,即便从未接触过Netty/Mina,但在心里认定只有这两个框架才能解决自己面临的问题。这样的现状可能归咎于现在我们太急躁,工作的压力致使没时间给自己充电,尤其是那种不常用且稍微有点深度的技术点,已经没心力再去细细琢磨了。所幸还有一批好学的程序员在工作之余做着一些看似平凡的事,踏踏实实专研这些技术点并作出一些小小的作品,同时为开源社区注入新鲜血液。目前码云上已知的Java AIO项目有tio、Voovan、baseio以及本文的主角:smart-socket,这几个作品还无任何一款能形成足够的影响力被广大Javaer认可,但通过开源的推广与磨练,相信未来AIO的开源环境会比现在更加繁荣。

smart-socket立项之初便已严苛的要求进行开发,追求各方面都达到极致。首先,smart-socket是个非常轻量级的项目,只有依赖log4j2作为项目的日志组件。smart-socket发布的jar包仅仅20KB,简洁的接口设计可以非常方便的在业务中接入通信服务。不过我们更期望看到的是接触到smart-socket的朋友可以将其作为学习Java Socket编程的素材,如果smart-socket能在这方面给予您一丝帮助,那我便会绝对自己做了一件有意义的事。

官方指南假设您已了解ByteBuffer,并对Socket编程具备一定基础。如果您刚开始接触Socket,将smart-socket作为您的第一步可能不是个好的决定。

Maven依赖

smart-socket已上传至Maven仓库,使用前需要向其引入您的项目工程中。

<!-- https://mvnrepository.com/artifact/org.smartboot.socket/aio-core -->
<dependency>
    <groupId>org.smartboot.socket</groupId>
    <artifactId>aio-core</artifactId>
    <version>1.3.2</version>
</dependency>

通信开发

基于smart-socket进行通信服务的开发,主要有三个步骤:

  1. 协议编解码
  2. 消息处理
  3. 启动服务

接下来我们会通过一个简单例子来演示如何通过smart-socket开发服务端与客户端程序。为简化操作,服务端与客户端交互的数据为一个整型数据。

一、协议编解码

正常情况下服务端与客户端通信共用同一套协议规则,因此我们只需编写一份协议编解码实现即可。如下所示,协议编解码的需要实现接口Protocol。

public class IntegerProtocol implements Protocol<Integer> {

    private static final int INT_LENGTH = 4;

    @Override
    public Integer decode(ByteBuffer data, AioSession<Integer> session, boolean eof) {
        if (data.remaining() < INT_LENGTH)
            return null;
        return data.getInt();
    }

    @Override
    public ByteBuffer encode(Integer s, AioSession<Integer> session) {
        ByteBuffer b = ByteBuffer.allocate(INT_LENGTH);
        b.putInt(s);
        b.flip();
        return b;
    }
}

上述代码很简单,一个整数的长度为4byte,所以只要长度大于等于4,我们就能解析到一个整数。

二、消息处理

业务消息的处理需要实现接口MessageProcessor,该接口只有两个方法:process,stateEvent。其中 stateEvent用于定义AioSession状态机的监控与处理。process则会处理每一个接收到的业务消息。

服务端

public class IntegerServerProcessor implements MessageProcessor<Integer> {
    @Override
    public void process(AioSession<Integer> session, Integer msg) {
        Integer respMsg = msg + 1;
        System.out.println("接受到客户端数据:" + msg + " ,响应数据:" + (respMsg));
        try {
            session.write(respMsg);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void stateEvent(AioSession<Integer> session, StateMachineEnum stateMachineEnum, Throwable throwable) {

    }
}

客户端

public class IntegerClientProcessor implements MessageProcessor<Integer> {
    private AioSession<Integer> session;

    @Override
    public void process(AioSession<Integer> session, Integer msg) {
        System.out.println("接受到服务端响应数据:" + msg);
    }

    @Override
    public void stateEvent(AioSession<Integer> session, StateMachineEnum stateMachineEnum, Throwable throwable) {
        switch (stateMachineEnum) {
            case NEW_SESSION:
                this.session = session;
                break;
            default:
                System.out.println("other state:" + stateMachineEnum);
        }

    }

    public AioSession<Integer> getSession() {
        return session;
    }
}

三、启动服务

服务端

    public class IntegerServer {
        public static void main(String[] args) {
            AioQuickServer server = new AioQuickServer()
                    .bind(8888)
                    .setProtocol(new IntegerProtocol())
                    .setProcessor(new IntegerServerProcessor());
            try {
                server.start();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

客户端

    public class IntegerClient {
        public static void main(String[] args) throws Exception {
            IntegerClientProcessor processor=new IntegerClientProcessor();
            AioQuickClient aioQuickClient=new AioQuickClient()
                    .connect("localhost",8888)
                    .setProtocol(new IntegerProtocol())
                    .setProcessor(processor);
            aioQuickClient.start();
            processor.getSession().write(1);
            Thread.sleep(1000);
            aioQuickClient.shutdown();
        }
    }

猜你喜欢

转载自my.oschina.net/u/2428630/blog/1813369