{"id":15014355,"url":"https://github.com/esastack/esa-codec-dubbo","last_synced_at":"2025-04-12T07:45:38.245Z","repository":{"id":43824469,"uuid":"365468042","full_name":"esastack/esa-codec-dubbo","owner":"esastack","description":"A simple implementation of the Dubbo protocol.","archived":false,"fork":false,"pushed_at":"2023-06-27T12:37:41.000Z","size":418,"stargazers_count":13,"open_issues_count":0,"forks_count":6,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-12T07:45:33.695Z","etag":null,"topics":["codec","dubbo","netty","sdk"],"latest_commit_sha":null,"homepage":"https://www.esastack.io","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/esastack.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-05-08T09:04:18.000Z","updated_at":"2022-11-21T03:15:25.000Z","dependencies_parsed_at":"2024-09-24T20:18:03.798Z","dependency_job_id":null,"html_url":"https://github.com/esastack/esa-codec-dubbo","commit_stats":{"total_commits":84,"total_committers":5,"mean_commits":16.8,"dds":0.5,"last_synced_commit":"8f7435fa3eea8cb63710a70ce5edd79a046d5689"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esastack%2Fesa-codec-dubbo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esastack%2Fesa-codec-dubbo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esastack%2Fesa-codec-dubbo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esastack%2Fesa-codec-dubbo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/esastack","download_url":"https://codeload.github.com/esastack/esa-codec-dubbo/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248537004,"owners_count":21120687,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["codec","dubbo","netty","sdk"],"created_at":"2024-09-24T19:45:30.959Z","updated_at":"2025-04-12T07:45:38.221Z","avatar_url":"https://github.com/esastack.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Codec-dubbo\n![Build](https://github.com/esastack/esa-codec-dubbo/workflows/Build/badge.svg?branch=main)\n[![codecov](https://codecov.io/gh/esastack/esa-codec-dubbo/branch/main/graph/badge.svg?token=CCQBCBQJP6)](https://codecov.io/gh/esastack/codec-dubbo)\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.esastack/codec-dubbo/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.esastack/codec-dubbo/)\n[![GitHub license](https://img.shields.io/github/license/esastack/esa-codec-dubbo)](https://github.com/esastack/esa-codec-dubbo/blob/main/LICENSE)\n\nCodec-dubbo is a binary codec framework for dubbo protocol\n\n## Features\n- Fully compatible with Dubbo protocol\n- Completely rewritten based on Netty, does not rely on native Dubbo\n- Support only parsing metadata but not body (suitable for proxy scenarios)\n- Support Dubbo Server\n- Support Dubbo Client\n- Multiple serialization protocols support\n\n##  Quick Start\n#### 1、Introduce Maven dependencies\n```xml  \n\u003c!-- commons.version \u003e= 0.1.1 --\u003e \n\u003cdependency\u003e\n    \u003cgroupId\u003eio.esastack\u003c/groupId\u003e\n    \u003cartifactId\u003ecommons\u003c/artifactId\u003e\n    \u003cversion\u003e${commons.version}\u003c/version\u003e\n\u003c/dependency\u003e\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.esastack\u003c/groupId\u003e\n    \u003cartifactId\u003ecodec-dubbo-client\u003c/artifactId\u003e\n    \u003cversion\u003e${mvn.version}\u003c/version\u003e\n\u003c/dependency\u003e\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.esastack\u003c/groupId\u003e\n    \u003cartifactId\u003ecodec-dubbo-server\u003c/artifactId\u003e\n    \u003cversion\u003e${mvn.version}\u003c/version\u003e\n\u003c/dependency\u003e\n\n\u003c!--netty--\u003e\n\u003c!-- netty.version \u003e= 4.1.52.Final, netty-tcnative.version \u003e= 2.0.34.Final --\u003e\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.netty\u003c/groupId\u003e\n    \u003cartifactId\u003enetty-all\u003c/artifactId\u003e\n    \u003cversion\u003e${netty.version}\u003c/version\u003e\n\u003c/dependency\u003e\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.netty\u003c/groupId\u003e\n    \u003cartifactId\u003enetty-tcnative\u003c/artifactId\u003e\n    \u003cversion\u003e${netty-tcnative.version}\u003c/version\u003e\n\u003c/dependency\u003e\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.netty\u003c/groupId\u003e\n    \u003cartifactId\u003enetty-tcnative-boringssl-static\u003c/artifactId\u003e\n    \u003cversion\u003e${netty-tcnative.version}\u003c/version\u003e\n\u003c/dependency\u003e\n```\n #### 2、Quick Start for Dubbo Client\n ```java\npublic class DubboSDKClient {\n    public static void main(String[] args) throws Exception {\n\n        // build client config\n        final Map\u003cChannelOption, Object\u003e channelOptions = new HashMap\u003c\u003e();\n        channelOptions.put(ChannelOption.SO_KEEPALIVE, true);\n        channelOptions.put(ChannelOption.TCP_NODELAY, true);\n        channelOptions.put(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000);\n        NettyConnectionConfig nettyConnectionConfig = new NettyConnectionConfig();\n        NettyConnectionConfig.MultiplexPoolBuilder multiplexPoolBuilder =\n                NettyConnectionConfig.MultiplexPoolBuilder.newBuilder();\n        nettyConnectionConfig.setMultiplexPoolBuilder(multiplexPoolBuilder)\n                .setChannelOptions(channelOptions)\n                .setHost(\"localhost\")\n                .setPort(20880);\n        final DubboClientBuilder builder = new DubboClientBuilder().setConnectionConfig(nettyConnectionConfig);\n\n        // build client\n        NettyDubboClient nettyDubboClient = new NettyDubboClient(builder);\n\n        // build request\n        RpcInvocation rpcInvocation = new RpcInvocation();\n        rpcInvocation.setMethodName(\"sayHello\");\n        rpcInvocation.setParameterTypes(new Class[]{String.class});\n        rpcInvocation.setArguments(new String[]{\"dubbo\"});\n        rpcInvocation.setInterfaceName(\"org.apache.dubbo.demo.DemoService\");\n        rpcInvocation.setReturnType(String.class);\n        // set serialization type\n        // rpcInvocation.setSeriType(KRYO_SERIALIZATION_ID);\n\n        Map\u003cString, String\u003e attachments = new HashMap\u003c\u003e();\n        rpcInvocation.setAttachments(attachments);\n\n        DubboMessage request = ClientCodecHelper.toDubboMessage(rpcInvocation);\n\n        // Send the request and handle the return value\n        CompletableFuture\u003cDubboRpcResult\u003e responseFuture = nettyDubboClient.sendRequest(request, String.class);\n\n        responseFuture.whenComplete((r, t) -\u003e {\n            if (t != null || r.getException() != null ||\n                    (r.getErrorMessage() != null \u0026\u0026 !\"\".equals(r.getErrorMessage()))) {\n                // handle exception\n            }\n            // handle return value r.getValue();\n        });\n    }\n}\n```\n\n #### 3、 Quick Start for Dubbo Server\n```java\npublic class ServerDemo {\n\n    static ExecutorService workerThreadPool = new ThreadPoolExecutor(200, 200, 60, TimeUnit.SECONDS, \n            new SynchronousQueue\u003c\u003e(),\n            new ThreadFactory() {\n                final AtomicInteger index = new AtomicInteger(0);\n                @Override\n                public Thread newThread(Runnable r) {\n                    Thread thread = new Thread(r);\n                    thread.setName(\"thread-\" + index.getAndIncrement());\n                    return thread;\n                }\n            },\n            new ThreadPoolExecutor.AbortPolicy()\n    );\n\n    public static void main(String[] args) {\n\n        // build server config\n        final Map\u003cChannelOption, Object\u003e options = new HashMap\u003c\u003e();\n        options.put(ChannelOption.SO_BACKLOG, 128);\n        options.put(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);\n        final Map\u003cChannelOption, Object\u003e childOptions = new HashMap\u003c\u003e();\n        childOptions.put(ChannelOption.SO_REUSEADDR, true);\n        childOptions.put(ChannelOption.SO_KEEPALIVE, true);\n        childOptions.put(ChannelOption.TCP_NODELAY, true);\n        NettyServerConfig nettyServerConfig = new NettyServerConfig();\n        nettyServerConfig.setBindIp(\"localhost\")\n                .setPort(20880)\n                .setIoThreads(1)\n                .setBossThreads(4)\n                .setChannelOptions(options)\n                .setChildChannelOptions(childOptions)\n                .setHeartbeatTimeoutSeconds(60);\n\n        // build server\n        DubboServerBuilder dubboServerBuilder = new DubboServerBuilder()\n                .setServerConfig(nettyServerConfig)\n                .setBizHandler(new DubboServerBizHandler() { // handle request and return response\n                    @Override\n                    public void process(DubboMessage request, DubboResponseHolder dubboResponseHolder) {\n                        final RpcInvocation invocation;\n                        try {\n                            // parse request\n                            invocation = ServerCodecHelper.toRpcInvocation(request);\n                        } catch (Exception e) {\n                            dubboResponseHolder.end(null);\n                            return;\n                        }\n                        workerThreadPool.execute(() -\u003e {\n                            String response = \"requestId:\" +\n                                    invocation.getRequestId() +\n                                    \" Hello \" + invocation.getArguments()[0] +\n                                    \", response from provider. seriType:\" +\n                                    invocation.getSeriType();\n\n                            DubboMessage dubboResponse = null;\n                            try {\n                                // build response\n                                dubboResponse = ServerCodecHelper.toDubboMessage(\n                                        DubboRpcResult.success(\n                                                invocation.getRequestId(),\n                                                invocation.getSeriType(),\n                                                response),\n                                        request.getBody().alloc());\n                            } catch (SerializationException e) {\n                                dubboResponseHolder.getChannelHandlerContext().channel().close();\n                            }\n                            // send response\n                            dubboResponseHolder.end(dubboResponse);\n                        });\n                    }\n\n                    @Override\n                    public void shutdown() {\n\n                    }\n                });\n        NettyDubboServer nettyDubboServer = new NettyDubboServer(dubboServerBuilder);\n\n        // start server\n        nettyDubboServer.start();\n    }\n}\n```\n## Serialization\n#### 1、 Supported serialization\nThe default serialization method is **hessian2**, and the following serialization methods are also supported:\n- fastjson\n- fst\n- json(jackson)\n- kryo        \n- protobuf    \n- protostuff \n\n#### 2、 Examples of supported serialization usage(take kryo as an example)\n1. Introduce Maven dependencies\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.esastack\u003c/groupId\u003e\n    \u003cartifactId\u003ecodec-serialization-kryo\u003c/artifactId\u003e\n    \u003cversion\u003e${mvn.version}\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n2. Set serialization method\nBefore we send a request, we need to set serialization type of this request as follows:\n```java\nrpcInvocation.setSeriType(KRYO_SERIALIZATION_ID);\n```\nWe can get the numbers corresponding to all serialization methods from the **SerializeConstants** interface\n#### 3、 Custom serialization\nIf the existing serialization method cannot meet the needs, you can customize the serialization method through SPI.\n1. Implement serialization class\n```java\npublic class TestSerialization implements Serialization {\n\n    @Override\n    public byte getSeriTypeId() {\n        return TEST_SERIALIZATION_ID;\n    }\n\n    @Override\n    public String getContentType() {\n        return \"x-application/test\";\n    }\n\n    @Override\n    public String getSeriName() {\n        return \"test\";\n    }\n\n    // We need to implement TestDataOutputStream and TestDataInputStream\n    @Override\n    public DataOutputStream serialize(OutputStream out) throws IOException {\n        return new TestDataOutputStream(out);\n    }\n\n    @Override\n    public DataInputStream deserialize(InputStream is) throws IOException {\n        return new TestDataInputStream(is);\n    }\n}\n```\n\n\n2. Add SPI file\n\nAdd the SPI configuration file in the module's resources to activate this serialization, the file path and file name: \n`META-INF/esa/io.esastack.codec.serialization.api.Serialization`\nthe file content is as follows:\n```\ntest=xxx.xxx.xxx.TestSerialization\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fesastack%2Fesa-codec-dubbo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fesastack%2Fesa-codec-dubbo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fesastack%2Fesa-codec-dubbo/lists"}