blob: 6c2e2ae81f360d4c63d5e139c9cca57cb4151007 [file] [log] [blame]
<!doctype html><html lang=en class=no-js><head><meta name=ROBOTS content="INDEX, FOLLOW"><link rel=canonical href=https://cn.dubbo.apache.org/en/blog/2018/08/14/implementation-of-cross-language-calls-by-dubbo2.js/><script>var _hmt=_hmt||[];(function(){var e,t=document.createElement("script");t.src="https://hm.baidu.com/hm.js?3b78f49ba47181e4d998a66b689446e9",e=document.getElementsByTagName("script")[0],e.parentNode.insertBefore(t,e)})()</script><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta http-equiv=Content-Security-Policy content="frame-src *"><meta name=generator content="Hugo 0.122.0"><link rel="shortcut icon" type=image/png href=/imgs/favicon.png><link rel=apple-touch-icon href=/favicons/apple-touch-icon-180x180.png sizes=180x180><link rel=manifest href=/manifest.webmanifest><title>Implementation of cross-language calls by Dubbo2.js | Apache Dubbo</title><meta property="og:title" content="Implementation of cross-language calls by Dubbo2.js">
<meta property="og:description" content="This article introduces how to use Dubbo.js to implement cross-language calls.
"><meta property="og:type" content="article"><meta property="og:url" content="https://cn.dubbo.apache.org/en/blog/2018/08/14/implementation-of-cross-language-calls-by-dubbo2.js/"><meta property="article:section" content="blog"><meta property="article:published_time" content="2018-08-14T00:00:00+00:00"><meta property="article:modified_time" content="2020-12-22T13:19:33+08:00"><meta itemprop=name content="Implementation of cross-language calls by Dubbo2.js"><meta itemprop=description content="This article introduces how to use Dubbo.js to implement cross-language calls.
"><meta itemprop=datePublished content="2018-08-14T00:00:00+00:00"><meta itemprop=dateModified content="2020-12-22T13:19:33+08:00"><meta itemprop=wordCount content="1814"><meta itemprop=keywords content><meta name=twitter:card content="summary"><meta name=twitter:title content="Implementation of cross-language calls by Dubbo2.js"><meta name=twitter:description content="This article introduces how to use Dubbo.js to implement cross-language calls.
"><script async src="https://www.googletagmanager.com/gtag/js?id=G-NM6FFMT51J"></script><script>var doNotTrack=!1;if(!doNotTrack){window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments)}gtag("js",new Date),gtag("config","G-NM6FFMT51J",{anonymize_ip:!1})}</script><link rel=preload href=/scss/main.min.f77e221bcdbe0cadb996060fe82063c747b60c229a1f8bbf0ee529adbadd84fa.css as=style><link href=/scss/main.min.f77e221bcdbe0cadb996060fe82063c747b60c229a1f8bbf0ee529adbadd84fa.css rel=stylesheet integrity><script src=/js/jquery-3.5.1.min.js integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin=anonymous></script><meta name=theme-color content="#326ce5"><link rel=stylesheet href=/css/feature-states.css><meta name=description content="This article introduces how to use Dubbo.js to implement cross-language calls.
"><meta property="og:description" content="This article introduces how to use Dubbo.js to implement cross-language calls.
"><meta name=twitter:description content="This article introduces how to use Dubbo.js to implement cross-language calls.
"><meta property="og:url" content="https://cn.dubbo.apache.org/en/blog/2018/08/14/implementation-of-cross-language-calls-by-dubbo2.js/"><meta property="og:title" content="Implementation of cross-language calls by Dubbo2.js"><meta name=twitter:title content="Implementation of cross-language calls by Dubbo2.js"><meta name=twitter:image:alt content="Apache Dubbo"><meta property="og:image" content="/imgs/blog/springmvc.png"><meta property="og:type" content="article"><meta name=viewport content="width=device-width"><script async defer src=/js/github-buttons.js></script><link href=/css/community.css rel=stylesheet><link href=/css/contactus.css rel=stylesheet><link href=/css/language.css rel=stylesheet><script src=/js/script.js></script></head><body class="td-page td-documentation"><header><nav class="js-navbar-scroll navbar navbar-expand navbar-dark flex-column flex-md-row td-navbar" data-auto-burger=primary><a class=navbar-brand href=/en/><span class=navbar-logo></span><span class="text-uppercase font-weight-bold">Apache Dubbo</span></a><div class="td-navbar-nav-scroll ml-md-auto" id=main_navbar><ul class="navbar-nav mt-2 mt-lg-0"><li class="nav-item mr-4 mb-2 mb-lg-0"><a class=nav-link href=/en/overview/><span>Overview</span></a></li><li class="nav-item mr-4 mb-2 mb-lg-0"><a class=nav-link href=/en/docs3-v2/><span>SDK Manual</span></a></li><li class="nav-item mr-4 mb-2 mb-lg-0"><a class="nav-link active" href=/en/blog/><span class=active>Blog</span></a></li><li class="nav-item mr-4 mb-2 mb-lg-0"><a class=nav-link href=/en/download/><span>Download</span></a></li><li class="nav-item mr-4 mb-2 mb-lg-0"><a class=nav-link href=https://start.dubbo.apache.org/bootstrap.html target=_blank><span>Initializer</span><i class='fas fa-external-link-alt'></i></a></li><li class="nav-item dropdown d-lg-block"><a class="nav-link dropdown-toggle" href=# id=navbarDropdownMenuLink role=button data-toggle=dropdown aria-haspopup=true aria-expanded=false>English</a><div class="dropdown-menu dropdown-menu-right" aria-labelledby=navbarDropdownMenuLink><a class=dropdown-item href=/zh-cn/>中文</a></div></li><li class="nav-item dropdown d-lg-block"><div class="nav-item d-none d-lg-block"></div></li></ul></div></nav><section class="header-hero text-white pb-0 light-text"></section></header><div class="container-fluid td-outer"><div class=td-main><div class="row flex-md-nowrap"><div class="col-12 col-md-3 col-xl-2 td-sidebar d-print-none"><script>$(function(){$("#td-section-nav a").removeClass("active"),$("#td-section-nav #m-enblog20180814implementation-of-cross-language-calls-by-dubbo2js").addClass("active"),$("#td-section-nav #m-enblog20180814implementation-of-cross-language-calls-by-dubbo2js-li span").addClass("td-sidebar-nav-active-item"),$("#td-section-nav #m-enblog20180814implementation-of-cross-language-calls-by-dubbo2js").parents("li").addClass("active-path"),$("#td-section-nav li.active-path").addClass("show"),$("#td-section-nav li.active-path").children("input").prop("checked",!0),$("#td-section-nav #m-enblog20180814implementation-of-cross-language-calls-by-dubbo2js-li").siblings("li").addClass("show"),$("#td-section-nav #m-enblog20180814implementation-of-cross-language-calls-by-dubbo2js-li").children("ul").children("li").addClass("show"),$("#td-sidebar-menu").toggleClass("d-none")})</script><div id=td-sidebar-menu class="td-sidebar__inner d-none"><div id=content-mobile><form class="td-sidebar__search d-flex align-items-center"><button class="btn btn-link td-sidebar__toggle d-md-none p-0 ml-3 fas fa-bars" type=button data-toggle=collapse data-target=#td-section-nav aria-controls=td-docs-nav aria-expanded=false aria-label="Toggle section navigation"></button></form></div><div id=content-desktop></div><nav class="collapse td-sidebar-nav foldable-nav" id=td-section-nav><ul class="td-sidebar-nav__section pr-md-3 ul-0"><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id=m-enblog-li><ul class=ul-1><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id=m-enblognews-li><input type=checkbox id=m-enblognews-check>
<label for=m-enblognews-check><a href=/en/blog/news/ title="Articles About Apache Dubbo" class="align-left pl-0 td-sidebar-link td-sidebar-link__section" id=m-enblognews><span>Articles</span></a></label><ul class="ul-2 foldable"><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20240131tracing-dubbo-with-opentelemetry-li><input type=checkbox id=m-enblog20240131tracing-dubbo-with-opentelemetry-check>
<label for=m-enblog20240131tracing-dubbo-with-opentelemetry-check><a href=/en/blog/2024/01/31/tracing-dubbo-with-opentelemetry/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20240131tracing-dubbo-with-opentelemetry><span>Tracing Dubbo With OpenTelemetry</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20231023introduction-to-apache-dubbo-plugin-for-intellij-idea-li><input type=checkbox id=m-enblog20231023introduction-to-apache-dubbo-plugin-for-intellij-idea-check>
<label for=m-enblog20231023introduction-to-apache-dubbo-plugin-for-intellij-idea-check><a href=/en/blog/2023/10/23/introduction-to-apache-dubbo-plugin-for-intellij-idea/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20231023introduction-to-apache-dubbo-plugin-for-intellij-idea><span>Introduction to Apache Dubbo plugin for IntelliJ IDEA</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20230415advanced-cloud-native-dubbo-32-officially-released-li><input type=checkbox id=m-enblog20230415advanced-cloud-native-dubbo-32-officially-released-check>
<label for=m-enblog20230415advanced-cloud-native-dubbo-32-officially-released-check><a href=/en/blog/2023/04/15/advanced-cloud-native-dubbo-3.2-officially-released/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20230415advanced-cloud-native-dubbo-32-officially-released><span>Advanced cloud native - Dubbo 3.2 officially released</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20220504how-to-proxy-dubbo-service-in-apache-shenyu-gateway-li><input type=checkbox id=m-enblog20220504how-to-proxy-dubbo-service-in-apache-shenyu-gateway-check>
<label for=m-enblog20220504how-to-proxy-dubbo-service-in-apache-shenyu-gateway-check><a href=/en/blog/2022/05/04/how-to-proxy-dubbo-service-in-apache-shenyu-gateway/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20220504how-to-proxy-dubbo-service-in-apache-shenyu-gateway><span>How to proxy Dubbo service in Apache ShenYu Gateway</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20220118makes-it-more-convenient-for-you-to-proxy-dubbo-services-in-apache-apisix-li><input type=checkbox id=m-enblog20220118makes-it-more-convenient-for-you-to-proxy-dubbo-services-in-apache-apisix-check>
<label for=m-enblog20220118makes-it-more-convenient-for-you-to-proxy-dubbo-services-in-apache-apisix-check><a href=/en/blog/2022/01/18/makes-it-more-convenient-for-you-to-proxy-dubbo-services-in-apache-apisix/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20220118makes-it-more-convenient-for-you-to-proxy-dubbo-services-in-apache-apisix><span>Makes it More Convenient for You to Proxy Dubbo Services in Apache APISIX</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20190826service-test-li><input type=checkbox id=m-enblog20190826service-test-check>
<label for=m-enblog20190826service-test-check><a href=/en/blog/2019/08/26/service-test/ title="Dubbo Admin service test" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20190826service-test><span>Service test in dubbo admin</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20190811tracing-dubbo-service-with-apache-skywalking-li><input type=checkbox id=m-enblog20190811tracing-dubbo-service-with-apache-skywalking-check>
<label for=m-enblog20190811tracing-dubbo-service-with-apache-skywalking-check><a href=/en/blog/2019/08/11/tracing-dubbo-service-with-apache-skywalking/ title="Tracing Dubbo service with Apache Skywalking" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20190811tracing-dubbo-service-with-apache-skywalking><span>Use apache skywalking in dubbo</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20190502dubbo-extensible-mechanism-source-code-analysis-part-2-li><input type=checkbox id=m-enblog20190502dubbo-extensible-mechanism-source-code-analysis-part-2-check>
<label for=m-enblog20190502dubbo-extensible-mechanism-source-code-analysis-part-2-check><a href=/en/blog/2019/05/02/dubbo-extensible-mechanism-source-code-analysis-part-2/ title="Dubbo extensible mechanism source code analysis - part 2" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20190502dubbo-extensible-mechanism-source-code-analysis-part-2><span>Dubbo extensible mechanism - part 2</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20190425dubbo-extensible-mechanism-source-code-analysis-part-1-li><input type=checkbox id=m-enblog20190425dubbo-extensible-mechanism-source-code-analysis-part-1-check>
<label for=m-enblog20190425dubbo-extensible-mechanism-source-code-analysis-part-1-check><a href=/en/blog/2019/04/25/dubbo-extensible-mechanism-source-code-analysis-part-1/ title="Dubbo extensible mechanism source code analysis - part 1" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20190425dubbo-extensible-mechanism-source-code-analysis-part-1><span>Dubbo extensible mechanism - part 1</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20190220implementation-background-and-practice-of-dubbo-client-asynchronous-interface-li><input type=checkbox id=m-enblog20190220implementation-background-and-practice-of-dubbo-client-asynchronous-interface-check>
<label for=m-enblog20190220implementation-background-and-practice-of-dubbo-client-asynchronous-interface-check><a href=/en/blog/2019/02/20/implementation-background-and-practice-of-dubbo-client-asynchronous-interface/ title="Implementation background and practice of Dubbo client asynchronous interface" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20190220implementation-background-and-practice-of-dubbo-client-asynchronous-interface><span>Dubbo Async Client</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20190220implementation-background-and-practice-of-dubbo-server-asynchronous-interface-li><input type=checkbox id=m-enblog20190220implementation-background-and-practice-of-dubbo-server-asynchronous-interface-check>
<label for=m-enblog20190220implementation-background-and-practice-of-dubbo-server-asynchronous-interface-check><a href=/en/blog/2019/02/20/implementation-background-and-practice-of-dubbo-server-asynchronous-interface/ title="Implementation background and practice of Dubbo server asynchronous interface" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20190220implementation-background-and-practice-of-dubbo-server-asynchronous-interface><span>Dubbo Async Server</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20190117how-to-use-seata-to-ensure-consistency-between-dubbo-microservices-li><input type=checkbox id=m-enblog20190117how-to-use-seata-to-ensure-consistency-between-dubbo-microservices-check>
<label for=m-enblog20190117how-to-use-seata-to-ensure-consistency-between-dubbo-microservices-check><a href=/en/blog/2019/01/17/how-to-use-seata-to-ensure-consistency-between-dubbo-microservices/ title="How to use Seata to ensure consistency between Dubbo Microservices" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20190117how-to-use-seata-to-ensure-consistency-between-dubbo-microservices><span>Use Seata in Dubbo</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20181210the-fifth-dubbo-meetup-has-been-held-in-hangzhou-li><input type=checkbox id=m-enblog20181210the-fifth-dubbo-meetup-has-been-held-in-hangzhou-check>
<label for=m-enblog20181210the-fifth-dubbo-meetup-has-been-held-in-hangzhou-check><a href=/en/blog/2018/12/10/the-fifth-dubbo-meetup-has-been-held-in-hangzhou/ title="The fifth Dubbo meetup has been held in Hangzhou" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20181210the-fifth-dubbo-meetup-has-been-held-in-hangzhou><span>The fifth Dubbo meetup</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20181107dubbo-integrates-with-nacos-to-become-a-registry-li><input type=checkbox id=m-enblog20181107dubbo-integrates-with-nacos-to-become-a-registry-check>
<label for=m-enblog20181107dubbo-integrates-with-nacos-to-become-a-registry-check><a href=/en/blog/2018/11/07/dubbo-integrates-with-nacos-to-become-a-registry/ title="Dubbo Integrates with Nacos to Become a Registry" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20181107dubbo-integrates-with-nacos-to-become-a-registry><span>Use Dubbo with Nacos</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20181005introduction-to-the-dubbo-protocol-li><input type=checkbox id=m-enblog20181005introduction-to-the-dubbo-protocol-check>
<label for=m-enblog20181005introduction-to-the-dubbo-protocol-check><a href=/en/blog/2018/10/05/introduction-to-the-dubbo-protocol/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20181005introduction-to-the-dubbo-protocol><span>Introduction to the Dubbo protocol</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20180930integrate-dubbo-with-kubernetes-li><input type=checkbox id=m-enblog20180930integrate-dubbo-with-kubernetes-check>
<label for=m-enblog20180930integrate-dubbo-with-kubernetes-check><a href=/en/blog/2018/09/30/integrate-dubbo-with-kubernetes/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20180930integrate-dubbo-with-kubernetes><span>Integrate Dubbo with Kubernetes</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20180902how-to-prepare-an-apache-release-li><input type=checkbox id=m-enblog20180902how-to-prepare-an-apache-release-check>
<label for=m-enblog20180902how-to-prepare-an-apache-release-check><a href=/en/blog/2018/09/02/how-to-prepare-an-apache-release/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20180902how-to-prepare-an-apache-release><span>How to prepare an Apache Release</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20180902how-to-implement-a-fully-asynchronous-calls-chain-based-on-dubbo-li><input type=checkbox id=m-enblog20180902how-to-implement-a-fully-asynchronous-calls-chain-based-on-dubbo-check>
<label for=m-enblog20180902how-to-implement-a-fully-asynchronous-calls-chain-based-on-dubbo-check><a href=/en/blog/2018/09/02/how-to-implement-a-fully-asynchronous-calls-chain-based-on-dubbo/ title="How to implement a fully asynchronous calls chain based on Dubbo" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20180902how-to-implement-a-fully-asynchronous-calls-chain-based-on-dubbo><span>New Async Call</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20180826the-fourth-dubbo-meetup-has-been-held-in-chengdu-li><input type=checkbox id=m-enblog20180826the-fourth-dubbo-meetup-has-been-held-in-chengdu-check>
<label for=m-enblog20180826the-fourth-dubbo-meetup-has-been-held-in-chengdu-check><a href=/en/blog/2018/08/26/the-fourth-dubbo-meetup-has-been-held-in-chengdu/ title="The fourth Dubbo meetup has been held in Chengdu" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20180826the-fourth-dubbo-meetup-has-been-held-in-chengdu><span>The fourth Dubbo meetup</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20180814dubbo-basic-usage-dubbo-consumer-configuration-li><input type=checkbox id=m-enblog20180814dubbo-basic-usage-dubbo-consumer-configuration-check>
<label for=m-enblog20180814dubbo-basic-usage-dubbo-consumer-configuration-check><a href=/en/blog/2018/08/14/dubbo-basic-usage-dubbo-consumer-configuration/ title=" Dubbo Basic Usage - Dubbo Consumer Configuration" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20180814dubbo-basic-usage-dubbo-consumer-configuration><span>Dubbo Consumer Configuration</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20180814dubbo-several-ways-about-synchronousasynchronous-invoke-li><input type=checkbox id=m-enblog20180814dubbo-several-ways-about-synchronousasynchronous-invoke-check>
<label for=m-enblog20180814dubbo-several-ways-about-synchronousasynchronous-invoke-check><a href=/en/blog/2018/08/14/dubbo-several-ways-about-synchronous/asynchronous-invoke/ title="Dubbo: Several ways about synchronous/asynchronous invoke" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20180814dubbo-several-ways-about-synchronousasynchronous-invoke><span>Dubbo Invoke</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20180814dubbo-basic-usage--dubbo-provider-configuration-li><input type=checkbox id=m-enblog20180814dubbo-basic-usage--dubbo-provider-configuration-check>
<label for=m-enblog20180814dubbo-basic-usage--dubbo-provider-configuration-check><a href=/en/blog/2018/08/14/dubbo-basic-usage--dubbo-provider-configuration/ title="Dubbo Basic Usage -- Dubbo Provider Configuration" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20180814dubbo-basic-usage--dubbo-provider-configuration><span>Dubbo Provider Configuration</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20180814manipulating-services-dynamically-via-qos-li><input type=checkbox id=m-enblog20180814manipulating-services-dynamically-via-qos-check>
<label for=m-enblog20180814manipulating-services-dynamically-via-qos-check><a href=/en/blog/2018/08/14/manipulating-services-dynamically-via-qos/ title="Manipulating Services Dynamically via QoS" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20180814manipulating-services-dynamically-via-qos><span>Dubbo QoS Introduction</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20180814source-code-analysis-of-spring-boot-dubbo-app-start-and-stop-li><input type=checkbox id=m-enblog20180814source-code-analysis-of-spring-boot-dubbo-app-start-and-stop-check>
<label for=m-enblog20180814source-code-analysis-of-spring-boot-dubbo-app-start-and-stop-check><a href=/en/blog/2018/08/14/source-code-analysis-of-spring-boot-dubbo-app-start-and-stop/ title="Source code analysis of spring-boot+Dubbo App start and stop" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20180814source-code-analysis-of-spring-boot-dubbo-app-start-and-stop><span>Dubbo start/stop in spring boot</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20180814implementation-of-cross-language-calls-by-dubbo2js-li><input type=checkbox id=m-enblog20180814implementation-of-cross-language-calls-by-dubbo2js-check>
<label for=m-enblog20180814implementation-of-cross-language-calls-by-dubbo2js-check><a href=/en/blog/2018/08/14/implementation-of-cross-language-calls-by-dubbo2.js/ title="Implementation of cross-language calls by Dubbo2.js" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20180814implementation-of-cross-language-calls-by-dubbo2js><span>dubbo2.js introduction</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20180814generic-invoke-of-dubbo-li><input type=checkbox id=m-enblog20180814generic-invoke-of-dubbo-check>
<label for=m-enblog20180814generic-invoke-of-dubbo-check><a href=/en/blog/2018/08/14/generic-invoke-of-dubbo/ title="Generic invoke of Dubbo" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20180814generic-invoke-of-dubbo><span>Generic invoke</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20180814native-image-using-graalvm-li><input type=checkbox id=m-enblog20180814native-image-using-graalvm-check>
<label for=m-enblog20180814native-image-using-graalvm-check><a href=/en/blog/2018/08/14/native-image-using-graalvm/ title="Native Image using GraalVM" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20180814native-image-using-graalvm><span>Native Image</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20180810dubbos-load-balance-li><input type=checkbox id=m-enblog20180810dubbos-load-balance-check>
<label for=m-enblog20180810dubbos-load-balance-check><a href=/en/blog/2018/08/10/dubbos-load-balance/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20180810dubbos-load-balance><span>Dubbo's Load Balance</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20180807use-annotations-in-dubbo-li><input type=checkbox id=m-enblog20180807use-annotations-in-dubbo-check>
<label for=m-enblog20180807use-annotations-in-dubbo-check><a href=/en/blog/2018/08/07/use-annotations-in-dubbo/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20180807use-annotations-in-dubbo><span>Use Annotations In Dubbo</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20180807using-zookeeper-in-dubbo-li><input type=checkbox id=m-enblog20180807using-zookeeper-in-dubbo-check>
<label for=m-enblog20180807using-zookeeper-in-dubbo-check><a href=/en/blog/2018/08/07/using-zookeeper-in-dubbo/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20180807using-zookeeper-in-dubbo><span>Using Zookeeper in Dubbo</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20180807dubbo-101-li><input type=checkbox id=m-enblog20180807dubbo-101-check>
<label for=m-enblog20180807dubbo-101-check><a href=/en/blog/2018/08/07/dubbo-101/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20180807dubbo-101><span>Your First Dubbo Demo</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20180730the-third-dubbo-meetup-has-been-held-in-shenzhen-li><input type=checkbox id=m-enblog20180730the-third-dubbo-meetup-has-been-held-in-shenzhen-check>
<label for=m-enblog20180730the-third-dubbo-meetup-has-been-held-in-shenzhen-check><a href=/en/blog/2018/07/30/the-third-dubbo-meetup-has-been-held-in-shenzhen/ title="The third Dubbo meetup has been held in Shenzhen" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20180730the-third-dubbo-meetup-has-been-held-in-shenzhen><span>The third Dubbo meetup</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20180727sentinel-the-flow-sentinel-of-dubbo-services-li><input type=checkbox id=m-enblog20180727sentinel-the-flow-sentinel-of-dubbo-services-check>
<label for=m-enblog20180727sentinel-the-flow-sentinel-of-dubbo-services-check><a href=/en/blog/2018/07/27/sentinel-the-flow-sentinel-of-dubbo-services/ title="Sentinel: The flow sentinel of Dubbo services" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20180727sentinel-the-flow-sentinel-of-dubbo-services><span>Introduce sentinel</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20180712tracking-with-pinpoint-li><input type=checkbox id=m-enblog20180712tracking-with-pinpoint-check>
<label for=m-enblog20180712tracking-with-pinpoint-check><a href=/en/blog/2018/07/12/tracking-with-pinpoint/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20180712tracking-with-pinpoint><span>Tracking with Pinpoint</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20180701your-first-dubbo-filter-li><input type=checkbox id=m-enblog20180701your-first-dubbo-filter-check>
<label for=m-enblog20180701your-first-dubbo-filter-check><a href=/en/blog/2018/07/01/your-first-dubbo-filter/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20180701your-first-dubbo-filter><span>Your First Dubbo Filter</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20180623the-second-dubbo-shanghai-meetup-has-been-held-successfully-li><input type=checkbox id=m-enblog20180623the-second-dubbo-shanghai-meetup-has-been-held-successfully-check>
<label for=m-enblog20180623the-second-dubbo-shanghai-meetup-has-been-held-successfully-check><a href=/en/blog/2018/06/23/the-second-dubbo-shanghai-meetup-has-been-held-successfully/ title="The second Dubbo Shanghai meetup has been held successfully" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20180623the-second-dubbo-shanghai-meetup-has-been-held-successfully><span>The second Dubbo meetup</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20180512the-first-dubbo-meetup-has-been-held-in-beijing-li><input type=checkbox id=m-enblog20180512the-first-dubbo-meetup-has-been-held-in-beijing-check>
<label for=m-enblog20180512the-first-dubbo-meetup-has-been-held-in-beijing-check><a href=/en/blog/2018/05/12/the-first-dubbo-meetup-has-been-held-in-beijing/ title="The first Dubbo meetup has been held in Beijing" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20180512the-first-dubbo-meetup-has-been-held-in-beijing><span>The first Dubbo meetup</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20180502the-apachecon-na-schedule-has-been-announced-li><input type=checkbox id=m-enblog20180502the-apachecon-na-schedule-has-been-announced-check>
<label for=m-enblog20180502the-apachecon-na-schedule-has-been-announced-check><a href=/en/blog/2018/05/02/the-apachecon-na-schedule-has-been-announced/ title="The ApacheCon NA schedule has been announced" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20180502the-apachecon-na-schedule-has-been-announced><span>ApacheCon NA</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20180425the-gsocgoogle-summer-of-code-2018-li><input type=checkbox id=m-enblog20180425the-gsocgoogle-summer-of-code-2018-check>
<label for=m-enblog20180425the-gsocgoogle-summer-of-code-2018-check><a href=/en/blog/2018/04/25/the-gsocgoogle-summer-of-code-2018/ title="The GSoC(Google Summer of Code) 2018" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20180425the-gsocgoogle-summer-of-code-2018><span>GSoC 2018</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20180422dubbo-roadmap-is-announced-in-qcon-beijing-2018-li><input type=checkbox id=m-enblog20180422dubbo-roadmap-is-announced-in-qcon-beijing-2018-check>
<label for=m-enblog20180422dubbo-roadmap-is-announced-in-qcon-beijing-2018-check><a href=/en/blog/2018/04/22/dubbo-roadmap-is-announced-in-qcon-beijing-2018/ title="Dubbo roadmap is announced in QCon Beijing 2018" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20180422dubbo-roadmap-is-announced-in-qcon-beijing-2018><span>QCon Beijing 2018</span></a></label></li></ul></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id=m-enblogproposals-li><input type=checkbox id=m-enblogproposals-check>
<label for=m-enblogproposals-check><a href=/en/blog/proposals/ title="Proposals About Apache Dubbo" class="align-left pl-0 td-sidebar-link td-sidebar-link__section" id=m-enblogproposals><span>Proposals</span></a></label><ul class="ul-2 foldable"><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog10101application-level-service-discovery-li><input type=checkbox id=m-enblog10101application-level-service-discovery-check>
<label for=m-enblog10101application-level-service-discovery-check><a href=/en/blog/1/01/01/application-level-service-discovery/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog10101application-level-service-discovery><span>Application-Level Service Discovery</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog10101enhanced-http-standard-capabilities-of-triple-protocol-li><input type=checkbox id=m-enblog10101enhanced-http-standard-capabilities-of-triple-protocol-check>
<label for=m-enblog10101enhanced-http-standard-capabilities-of-triple-protocol-check><a href=/en/blog/1/01/01/enhanced-http-standard-capabilities-of-triple-protocol/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog10101enhanced-http-standard-capabilities-of-triple-protocol><span>Enhanced HTTP Standard Capabilities of Triple Protocol</span></a></label></li></ul></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section with-child" id=m-enblogreleases-li><input type=checkbox id=m-enblogreleases-check>
<label for=m-enblogreleases-check><a href=/en/blog/releases/ title="New Releases" class="align-left pl-0 td-sidebar-link td-sidebar-link__section" id=m-enblogreleases><span>Releases</span></a></label><ul class="ul-2 foldable"><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog202109202714-release-note-li><input type=checkbox id=m-enblog202109202714-release-note-check>
<label for=m-enblog202109202714-release-note-check><a href=/en/blog/2021/09/20/2.7.14-release-note/ title="2.7.14 Release Note" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog202109202714-release-note><span>2.7.14</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog202108233021-release-note-li><input type=checkbox id=m-enblog202108233021-release-note-check>
<label for=m-enblog202108233021-release-note-check><a href=/en/blog/2021/08/23/3.0.2.1-release-note/ title="3.0.2.1 Release Note" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog202108233021-release-note><span>3.0.2.1</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20210818302-release-note-li><input type=checkbox id=m-enblog20210818302-release-note-check>
<label for=m-enblog20210818302-release-note-check><a href=/en/blog/2021/08/18/3.0.2-release-note/ title="3.0.2 Release Note" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20210818302-release-note><span>3.0.2</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20210702301-release-note-li><input type=checkbox id=m-enblog20210702301-release-note-check>
<label for=m-enblog20210702301-release-note-check><a href=/en/blog/2021/07/02/3.0.1-release-note/ title="3.0.1 Release Note" class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20210702301-release-note><span>3.0.1</span></a></label></li><li class="td-sidebar-nav__section-title td-sidebar-nav__section without-child" id=m-enblog20200518past-releases-li><input type=checkbox id=m-enblog20200518past-releases-check>
<label for=m-enblog20200518past-releases-check><a href=/en/blog/2020/05/18/past-releases/ class="align-left pl-0 td-sidebar-link td-sidebar-link__page" id=m-enblog20200518past-releases><span>Past Releases</span></a></label></li></ul></li></ul></li></ul></nav></div></div><main class="col-12 col-md-9 col-xl-8 pl-md-5" role=main><nav aria-label=breadcrumb class=td-breadcrumbs><ol class=breadcrumb><li class=breadcrumb-item><a href=https://cn.dubbo.apache.org/en/blog/>Blog</a></li><li class=breadcrumb-item><a href=https://cn.dubbo.apache.org/en/blog/news/>Articles</a></li><li class="breadcrumb-item active" aria-current=page><a href=https://cn.dubbo.apache.org/en/blog/2018/08/14/implementation-of-cross-language-calls-by-dubbo2.js/ aria-disabled=true class="btn-link disabled">dubbo2.js introduction</a></li></ol></nav><section id=deprecation-warning><div class="content deprecation-warning pageinfo outdated-blog"><p>This article is more than one year old. Older articles may contain outdated content. Check that the information in the page has not become incorrect since its publication.</p></div></section><div class=td-content><h1>Implementation of cross-language calls by Dubbo2.js</h1><div class=lead>This article introduces how to use Dubbo.js to implement cross-language calls.</div><div class="td-byline mb-4"><time datetime=2018-08-14 class=text-muted>Tuesday, August 14, 2018</time></div><header class=article-meta></header><blockquote><p><a href=https://github.com/dubbo/dubbo2.js>dubbo2.js</a> is a Dubbo client for node.js developped by <a href=https://www.qianmi.com/>Qianmiwang</a>. It supports Dubbo&rsquo;s native protocol, which makes the RPC calls between javascript and java efficient and agile. This tool has been contributed to Dubbo&rsquo;s community.</p></blockquote><h2 id=cross-language-calls-for-micro-service>Cross-language calls for micro service</h2><p>Nowadays, Internet architecture tends to be micro-service way. The discussions about micro-service architecture becomes the most mentioned topic in different technical conferences. In China, most of the companies, such as Qianmiwang, choose Dubbo as their micro-servie architecture solution. As most of the internet companies, Qianmiwang uses various of programming languages. Java is for most of the backend services. Each business based on these backend can choose its own programming language such as go, python and javascript. Therefore, here comes a challenge, cross language calls. Some well mentioned solutions are as follows:</p><ul><li>Spring cloud. Spring cloud provides a set of components for micro-service development. It is based on HTTP protocol and is designed in the restful way, which makes it support cross-language calls. Other languages can call the services simply by implementing an HTTP interface.</li><li>Service mesh. People call service mesh the next generation of micro-service framework. The core of this solution is SideCar. Even though the concept of SideCar changes a lot during the revolution of Service mesh, its main job never changed: providing reliable communication between different services.</li><li>Motan. <a href=https://github.com/weibocom/motan>Motan</a> is an open source cross-language service framework developped by Sina Weibo. Its early version only supports motan-java. However, as the new versions come out, more languages are supported in order to handle the cross-language problem. Its newest version(1.1.0) provides motan-go, motan-php, motan-openresty, etc. Similar to SideCar in Service mesh, Motan forwards messages by mortan-go, which can be considered as an agent. Meanwhile, motan2, its own protocol, is built for cross-language calls.</li></ul><p>According to the solutions below, there are two ways to solve the cross-language calls problem:</p><ul><li>communicating by a common protocol.</li><li>implementing an agent as a protocol adapter.</li></ul><p>When a new team is choosing technical solutions, what I mentioned below could be our candidates. Meanwhile, the old system&rsquo;s compatibility and migration costs should also be considered. The first trial we did is to work on RPC protocol.</p><h2 id=cross-language-calls-by-a-common-protocol>Cross-language calls by a common protocol</h2><h3 id=springmvc>SpringMVC</h3><p><img src=/imgs/blog/springmvc.png alt=springmvc></p><p>Before achieving the real cross-language calls, the most common solution is to use the http protocol. We can call Dubbo provider indirectly by controller/restController provided by springmvc. This is easy to carry out, but there are lots of inconveniences. firstly, a call will go through too many nodes. Secondly, an extra communication layer (for http protocol) will be involved, but it could have been handled simply by the TCP protocol. Thirdly, we need to implement the RPC interface in the controller part. This will be extra work for developers.</p><h3 id=we-support-some-common-protocols>We support some common protocols</h3><p>Most of the service management frameworks support multiple protocols, dubbo as well. Besides its own protocol, the common protocols such as Dangdangwang&rsquo;s <a href=https://dangdangdotcom.github.io/dubbox/rest.html>Rest</a> protocol and Qianmiwang&rsquo;s <a href=https://github.com/apache/dubbo-rpc-jsonrpc>json-rpc</a> protocol are also supported.</p><p>The developers getting used to traditional RPC interfaces might feel uncomfortable while working on restful RPC interfaces. On the one hand, this is not good for rebuilding new interfaces. On the other hand, restful style might make these interfaces incompatible with the other protocols used by old interfaces. Of course, if there is no old system problems, using Rest protocol is the easiest implementation of cross-language calls, since most of the languages support it.</p><p>Even if Dubbo has tried on restful interface, the difference between rest architecture and RPC architecture should not be ignored. Rest architecture defines each resources, and it needs basic operations of http protocols such as GET, POST, DELETE, PUT. In my opinion, a Rest protocol is more for calls between different systems on the internet, while RPC is suitable for inner system calls. Similar to Rest protocol, json-rpc is also implemented by text sequence and http protocol. Using json-rpc can also solve the cross-language problems, meanwhile, it makes our solution compatible with old interfaces and there is no need to adapt to the restful style.</p><p>Json-rpc is Qianmiwang&rsquo;s early solution for cross-language protocol. They open-sourced their <a href=https://github.com/dubbo/dubbo-client-py>dubbo-client-py</a> and <a href=https://github.com/QianmiOpen/dubbo-node-client>dubbo-node-client</a>, two clients based on json-rpc protocol. With these tools, we can easily call the rpc services provided by dubbo-provider-java with while using python or node.js. The inner system calls for java services are still mainly implemented by Dubbo protocol. In addition, in order to adapt the old system, two protocols could be configured.</p><div class=highlight><pre tabindex=0 style=color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-xml data-lang=xml><span style=display:flex><span><span style=color:#268bd2>&lt;dubbo:protocol</span> name=<span style=color:#2aa198>&#34;dubbo&#34;</span> port=<span style=color:#2aa198>&#34;20880&#34;</span> <span style=color:#268bd2>/&gt;</span>
</span></span><span style=display:flex><span><span style=color:#268bd2>&lt;dubbo:protocol</span> name=<span style=color:#2aa198>&#34;jsonrpc&#34;</span> port=<span style=color:#2aa198>&#34;8080&#34;</span> <span style=color:#268bd2>/&gt;</span>
</span></span></code></pre></div><h3 id=customized-protocols-for-cross-language-support>Customized Protocols for Cross-language Support</h3><p>The so-called protocol of the microservice framework can be simply interpreted as: message format and serialization scheme. Generally, the service governance framework would provide numbers of protocol configuration items for users to choose from. In addition to the above two common protocols,there exists some other customized protocols like the dubbo protocol, the default protocol for the dubbo framework, and Motan2, a cross-language protocol provided by the motan framework.</p><h4 id=motan2-for-cross-language-support>Motan2 for cross-language support</h4><p><img src=/imgs/blog/motan-protocol-en.png alt=motan2></p><p>In the original Motan protocol, the protocol message consisted only of the Header and the Body, making deserialization indispensable for acquiring data stored in the Body, like path, param and group, which is terribly unfriendly for cross-language support. Therefore, the content of the protocol was modifiedin Motan2, Weibo released the open-source projects, <a href=https://github.com/weibocom/motan-go/>motan-go</a>, <a href=https://github.com/weibocom/motan-php>motan-php</a> and <a href=https://github.com/weibocom/motan-openresty>motan-openresty</a>. It used motan-go as an interpreter and the Simple serialization scheme to serialize the Body of protocol message. (Simple is a comparably weaker serialization scheme)</p><p><img src=/imgs/blog/motan-agent.png alt=agent></p><p>After observation we find out that there is no big difference between the configuration of Motan2 and the dual protocol. It’s just that the agent here is implicit, and it co-exists with the main service. The most obvious difference is that different languages do not interact directly in agent scheme.</p><h4 id=dubbo-for-cross-language-support>Dubbo for cross-language support</h4><p>Instead of cross-language support, the dubbo protocol was originally designed only for common rpc requests. However, it’s not always the case that we can only choose to support it or not. We can always choose to offer different levels of support. It may be hard to offer cross-language support based on the dubbo protocol, but not impossible. Actually, Qianmiwang succeeded. It conquered the front-end cross-language business field built by nodejs with dubbo2.js. It builds the bridge between Nodejs and the native dubbo protocol. Next, we will focus on what we can do with dubbo2.js.</p><h5 id=dubbo-protocol-message-format>Dubbo protocol message format:</h5><p><img src=/imgs/blog/dubbo-protocol.png alt=dubbo协议></p><p>Details in dubbo protocol header message:</p><ul><li>Magic: similar to magic number in Java bytes code files, which is used to determine whether it is a data pack of dubbo protocol. The magic number is the constant, 0xdabb.</li><li>Flag: contains 8 bits. The lower four bits are used to indicate the type of serialization tool used for message body data (default hessian). Among the upper four bits, the 1 at first bit indicates request, the 1 at second bit indicates dual transfer, 1 at third bits indicates the heartbeat.</li><li>Status: used toset response status. Dubbo defines some types for response. Details can be found in <span data-type=color style=color:#24292e><span data-type=background style=background-color:rgba(27,31,35,5%)>com.alibaba.dubbo.remoting.exchange.Response</span></span></li><li>Invoke id: Message id,Type long, Unique indentifier for each request (Due to asynchronous communication, it is used to match the request to the corresponding returned response)</li><li>Body length: message body length, type int,record bytes of body content.</li><li>Body content: request param, where serializedresponse parameters are stored.</li></ul><p>Protocol messages will eventually become bytes and be transmitted using TCP. Any language that supports network modules and has a socket will be able to be communicatedwith. Then, why cross-language support is difficult? There are two main obstaclesin calling service in Java using other languages:</p><ol><li><span data-type=color style=color:#24292e>How </span><span data-type=color style=color:#212121>can different languages ​​represent data types in java, especially dynamiclanguages with possible non-strict data types</span>?</li><li><span data-type=color style=color:#24292e>How to serialize string across language?</span></li></ol><h2 id=how-does-dubbo2js-solve-problems>How does dubbo2.js solve problems?</h2><p>We have analyzed two obstacles above. The key to dubbo2.js in solving these two problems depends on two class libraries: <a href=https://github.com/node-modules/js-to-java>js-to-java</a><a href=https://github.com/node-modules/hessian.js>hessian.js</a>. js-to-java, which makes nodejs have the ability to express Java objects. Hessian.js provides serialization capabilities. With the help of nodejs socket, and a duplicate set of dubbo protocol message format, we can finally achieve nodejs call to java-dubbo-provider.</p><h2 id=quick-start>Quick Start</h2><p>To give an intuitive feeling to readers interested in dubbo2.js, this section presents a quick start example that shows how easy it is to call dubbo service using dubbo2.js.</p><h3 id=1-initiate-dubbo-java-provider>1. Initiate dubbo-java-provider</h3><p>Java provides the backend dubbo service. Firstly, let’s define the service interface:</p><div class=highlight><pre tabindex=0 style=color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-java data-lang=java><span style=display:flex><span><span style=color:#268bd2>public</span> <span style=color:#268bd2>interface</span> <span style=color:#268bd2>DemoProvider</span> {
</span></span><span style=display:flex><span> String <span style=color:#268bd2>sayHello</span>(String name);
</span></span><span style=display:flex><span> String <span style=color:#268bd2>echo</span>() ;
</span></span><span style=display:flex><span> <span style=color:#dc322f>void</span> <span style=color:#268bd2>test</span>();
</span></span><span style=display:flex><span> UserResponse <span style=color:#268bd2>getUserInfo</span>(UserRequest request);
</span></span><span style=display:flex><span>}
</span></span></code></pre></div><p>Then we implement the interface:</p><div class=highlight><pre tabindex=0 style=color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-java data-lang=java><span style=display:flex><span><span style=color:#268bd2>public</span> <span style=color:#268bd2>class</span> <span style=color:#268bd2>DemoProviderImpl</span> <span style=color:#268bd2>implements</span> DemoProvider {
</span></span><span style=display:flex><span> <span style=color:#268bd2>public</span> String <span style=color:#268bd2>sayHello</span>(String name) {
</span></span><span style=display:flex><span> System.out.println(<span style=color:#2aa198>&#34;[&#34;</span> <span style=color:#719e07>+</span> <span style=color:#719e07>new</span> SimpleDateFormat(<span style=color:#2aa198>&#34;HH:mm:ss&#34;</span>).format(<span style=color:#719e07>new</span> Date()) <span style=color:#719e07>+</span> <span style=color:#2aa198>&#34;] Hello &#34;</span> <span style=color:#719e07>+</span> name <span style=color:#719e07>+</span> <span style=color:#2aa198>&#34;, request from consumer: &#34;</span> <span style=color:#719e07>+</span> RpcContext.getContext().getRemoteAddress());
</span></span><span style=display:flex><span> <span style=color:#719e07>return</span> <span style=color:#2aa198>&#34;Hello &#34;</span> <span style=color:#719e07>+</span> name <span style=color:#719e07>+</span> <span style=color:#2aa198>&#34;, response form provider: &#34;</span> <span style=color:#719e07>+</span> RpcContext.getContext().getLocalAddress();
</span></span><span style=display:flex><span> }
</span></span><span style=display:flex><span> <span style=color:#268bd2>@Override</span>
</span></span><span style=display:flex><span> <span style=color:#268bd2>public</span> String <span style=color:#268bd2>echo</span>() {
</span></span><span style=display:flex><span> System.out.println(<span style=color:#2aa198>&#34;receive....&#34;</span>);
</span></span><span style=display:flex><span> <span style=color:#719e07>return</span> <span style=color:#2aa198>&#34;pang&#34;</span>;
</span></span><span style=display:flex><span> }
</span></span><span style=display:flex><span> <span style=color:#268bd2>@Override</span>
</span></span><span style=display:flex><span> <span style=color:#268bd2>public</span> <span style=color:#dc322f>void</span> <span style=color:#268bd2>test</span>() {
</span></span><span style=display:flex><span> System.out.println(<span style=color:#2aa198>&#34;test&#34;</span>);
</span></span><span style=display:flex><span> }
</span></span><span style=display:flex><span> <span style=color:#268bd2>@Override</span>
</span></span><span style=display:flex><span> <span style=color:#268bd2>public</span> UserResponse <span style=color:#268bd2>getUserInfo</span>(UserRequest request) {
</span></span><span style=display:flex><span> System.out.println(request);
</span></span><span style=display:flex><span> UserResponse response <span style=color:#719e07>=</span> <span style=color:#719e07>new</span> UserResponse();
</span></span><span style=display:flex><span> response.setStatus(<span style=color:#2aa198>&#34;ok&#34;</span>);
</span></span><span style=display:flex><span> Map<span style=color:#719e07>&lt;</span>String, String<span style=color:#719e07>&gt;</span> map <span style=color:#719e07>=</span> <span style=color:#719e07>new</span> HashMap<span style=color:#719e07>&lt;</span>String, String<span style=color:#719e07>&gt;</span>();
</span></span><span style=display:flex><span> map.put(<span style=color:#2aa198>&#34;id&#34;</span>, <span style=color:#2aa198>&#34;1&#34;</span>);
</span></span><span style=display:flex><span> map.put(<span style=color:#2aa198>&#34;name&#34;</span>, <span style=color:#2aa198>&#34;test&#34;</span>);
</span></span><span style=display:flex><span> response.setInfo(map);
</span></span><span style=display:flex><span> <span style=color:#719e07>return</span> response;
</span></span><span style=display:flex><span> }
</span></span><span style=display:flex><span>}
</span></span></code></pre></div><p>After that,<span data-type=color style=color:#24292e> we expose the dubbo service with xml files:</span></p><div class=highlight><pre tabindex=0 style=color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-xml data-lang=xml><span style=display:flex><span><span style=color:#719e07>&lt;?xml version=&#34;1.0&#34; encoding=&#34;UTF-8&#34;?&gt;</span>
</span></span><span style=display:flex><span><span style=color:#268bd2>&lt;beans</span> xmlns:xsi=<span style=color:#2aa198>&#34;http://www.w3.org/2001/XMLSchema-instance&#34;</span>
</span></span><span style=display:flex><span> xmlns:dubbo=<span style=color:#2aa198>&#34;http://code.alibabatech.com/schema/dubbo&#34;</span>
</span></span><span style=display:flex><span> xmlns=<span style=color:#2aa198>&#34;http://www.springframework.org/schema/beans&#34;</span>
</span></span><span style=display:flex><span> xsi:schemaLocation=<span style=color:#2aa198>&#34;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
</span></span></span><span style=display:flex><span><span style=color:#2aa198> http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd&#34;</span><span style=color:#268bd2>&gt;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#586e75>&lt;!-- dubbo provider info, used to compute dependency --&gt;</span>
</span></span><span style=display:flex><span> <span style=color:#268bd2>&lt;dubbo:application</span> name=<span style=color:#2aa198>&#34;demo-provider&#34;</span><span style=color:#268bd2>/&gt;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#268bd2>&lt;dubbo:registry</span> protocol=<span style=color:#2aa198>&#34;zookeeper&#34;</span> address=<span style=color:#2aa198>&#34;localhost:2181&#34;</span><span style=color:#268bd2>/&gt;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#586e75>&lt;!-- dubbo protocol, used to expose service at port 20880 --&gt;</span>
</span></span><span style=display:flex><span> <span style=color:#268bd2>&lt;dubbo:protocol</span> name=<span style=color:#2aa198>&#34;dubbo&#34;</span> port=<span style=color:#2aa198>&#34;20880&#34;</span><span style=color:#268bd2>/&gt;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#586e75>&lt;!-- realize a service as a local bean --&gt;</span>
</span></span><span style=display:flex><span> <span style=color:#268bd2>&lt;bean</span> id=<span style=color:#2aa198>&#34;demoProvider&#34;</span> class=<span style=color:#2aa198>&#34;com.alibaba.dubbo.demo.provider.DemoProviderImpl&#34;</span><span style=color:#268bd2>/&gt;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> <span style=color:#586e75>&lt;!-- claim for service interfaces to expose --&gt;</span>
</span></span><span style=display:flex><span> <span style=color:#268bd2>&lt;dubbo:service</span> interface=<span style=color:#2aa198>&#34;com.alibaba.dubbo.demo.DemoProvider&#34;</span> ref=<span style=color:#2aa198>&#34;demoProvider&#34;</span> version=<span style=color:#2aa198>&#34;1.0.0&#34;</span><span style=color:#268bd2>/&gt;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#268bd2>&lt;/beans&gt;</span>
</span></span></code></pre></div><p>After we implemented all the configurations on server side, initiate an object initiater to register a dubbo service locally:</p><div class=highlight><pre tabindex=0 style=color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-java data-lang=java><span style=display:flex><span><span style=color:#268bd2>public</span> <span style=color:#268bd2>class</span> <span style=color:#268bd2>Provider</span> {
</span></span><span style=display:flex><span> <span style=color:#268bd2>public</span> <span style=color:#268bd2>static</span> <span style=color:#dc322f>void</span> <span style=color:#268bd2>main</span>(String<span style=color:#719e07>[]</span> args) <span style=color:#268bd2>throws</span> Exception {
</span></span><span style=display:flex><span> ClassPathXmlApplicationContext context <span style=color:#719e07>=</span> <span style=color:#719e07>new</span> ClassPathXmlApplicationContext(<span style=color:#719e07>new</span> String<span style=color:#719e07>[]</span>{<span style=color:#2aa198>&#34;META-INF/spring/dubbo-demo-provider.xml&#34;</span>});
</span></span><span style=display:flex><span> context.start();
</span></span><span style=display:flex><span> System.in.read();
</span></span><span style=display:flex><span> }
</span></span><span style=display:flex><span>}
</span></span></code></pre></div><h3 id=2-implement-dubbo-client-side-for-nodejs>2. Implement dubbo client-side for nodejs</h3><p>Install dubbo2.js using npm:</p><div class=highlight><pre tabindex=0 style=color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-sh data-lang=sh><span style=display:flex><span>npm install dubbo2.js --save
</span></span></code></pre></div><p>Configure dubboConfig.ts:</p><div class=highlight><pre tabindex=0 style=color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-typescript data-lang=typescript><span style=display:flex><span><span style=color:#268bd2>import</span> { Dubbo, java, TDubboCallResult } <span style=color:#268bd2>from</span> <span style=color:#2aa198>&#39;dubbo2.js&#39;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#268bd2>const</span> dubbo <span style=color:#719e07>=</span> <span style=color:#719e07>new</span> Dubbo({
</span></span><span style=display:flex><span> application<span style=color:#719e07>:</span> {name<span style=color:#719e07>:</span> <span style=color:#2aa198>&#39;demo-provider&#39;</span>},
</span></span><span style=display:flex><span> register<span style=color:#719e07>:</span> <span style=color:#2aa198>&#39;localhost:2181&#39;</span>,
</span></span><span style=display:flex><span> dubboVersion<span style=color:#719e07>:</span> <span style=color:#2aa198>&#39;2.0.0&#39;</span>,
</span></span><span style=display:flex><span> interfaces<span style=color:#719e07>:</span> [
</span></span><span style=display:flex><span> <span style=color:#2aa198>&#39;com.alibaba.dubbo.demo.DemoProvider&#39;</span>,
</span></span><span style=display:flex><span> ],
</span></span><span style=display:flex><span>});
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#268bd2>interface</span> IDemoService {
</span></span><span style=display:flex><span> sayHello(name: <span style=color:#dc322f>string</span>)<span style=color:#719e07>:</span> TDubboCallResult&lt;<span style=color:#268bd2>string</span>&gt;;
</span></span><span style=display:flex><span>}
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#268bd2>export</span> <span style=color:#268bd2>const</span> demoService <span style=color:#719e07>=</span> dubbo.proxyService&lt;<span style=color:#268bd2>IDemoService</span>&gt;({
</span></span><span style=display:flex><span> dubboInterface<span style=color:#719e07>:</span> <span style=color:#2aa198>&#39;com.alibaba.dubbo.demo.DemoProvider&#39;</span>,
</span></span><span style=display:flex><span> version<span style=color:#719e07>:</span> <span style=color:#2aa198>&#39;1.0.0&#39;</span>,
</span></span><span style=display:flex><span> methods<span style=color:#719e07>:</span> {
</span></span><span style=display:flex><span> sayHello(name: <span style=color:#dc322f>string</span>) {
</span></span><span style=display:flex><span> <span style=color:#719e07>return</span> [java.<span style=color:#b58900>String</span>(name)];
</span></span><span style=display:flex><span> },
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> echo() {},
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> test() {},
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span> getUserInfo() {
</span></span><span style=display:flex><span> <span style=color:#719e07>return</span> [
</span></span><span style=display:flex><span> java.combine(<span style=color:#2aa198>&#39;com.alibaba.dubbo.demo.UserRequest&#39;</span>, {
</span></span><span style=display:flex><span> id: <span style=color:#dc322f>1</span>,
</span></span><span style=display:flex><span> name<span style=color:#719e07>:</span> <span style=color:#2aa198>&#39;nodejs&#39;</span>,
</span></span><span style=display:flex><span> email<span style=color:#719e07>:</span> <span style=color:#2aa198>&#39;node@qianmi.com&#39;</span>,
</span></span><span style=display:flex><span> }),
</span></span><span style=display:flex><span> ];
</span></span><span style=display:flex><span> },
</span></span><span style=display:flex><span> },
</span></span><span style=display:flex><span>});
</span></span></code></pre></div><blockquote><p>Using typescript brings better coding experience.</p></blockquote><p>Implement caller class main.ts:</p><div class=highlight><pre tabindex=0 style=color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-typescript data-lang=typescript><span style=display:flex><span><span style=color:#268bd2>import</span> {demoService} <span style=color:#268bd2>from</span> <span style=color:#2aa198>&#39;./dubboConfig&#39;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>demoService.sayHello(<span style=color:#2aa198>&#39;kirito&#39;</span>).then(({res,err})<span style=color:#719e07>=&gt;</span>{
</span></span><span style=display:flex><span> console.log(res)
</span></span><span style=display:flex><span>});
</span></span></code></pre></div><h3 id=3-call-maints>3. Call main.ts:</h3><p>Run nodejs client in Debug mode:</p><div class=highlight><pre tabindex=0 style=color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-sh data-lang=sh><span style=display:flex><span><span style=color:#268bd2>DEBUG</span><span style=color:#719e07>=</span>dubbo* ts-node main.ts
</span></span></code></pre></div><p>Checkout running results:</p><div class=highlight><pre tabindex=0 style=color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-sh data-lang=sh><span style=display:flex><span>Hello kirito, response form provider: 172.19.6.151:20880
</span></span></code></pre></div><p>Congratulations!</p><h2 id=features>Features</h2><ul><li>Support zookeeper as register center</li><li>Support TCP Dubbo Native protocol</li><li>Support directly Dubbo connection</li><li>Support link tracing</li><li>Generate dubbo interface Automatically</li></ul><h2 id=more-details>More details</h2><p>The sample code in this article is available here, <a href=https://github.com/dubbo/dubbo2.js>https://github.com/dubbo/dubbo2.js</a>.
If you don't know much about the dubbo protocol and want to understand how it works, the project provides a sub-moudle: java-socket-consumer, which is implemented in a process-oriented approach, realizing a process of sending dubbo protocal message with native socket and making function calls, and then get response.</p><ul class="list-unstyled d-flex justify-content-between align-items-center mb-0 pt-5"><li><a href=/en/blog/2018/08/14/generic-invoke-of-dubbo/ aria-label="Previous - Generic invoke of Dubbo" class="btn btn-primary"><span class=mr-1></span>Previous</a></li><li><a href=/en/blog/2018/08/14/source-code-analysis-of-spring-boot-dubbo-app-start-and-stop/ aria-label="Next - Source code analysis of spring-boot+Dubbo App start and stop" class="btn btn-primary">Next<span class=ml-1></span></a></li></ul></div><div id=pre-footer><h2>Feedback</h2><p class=feedback--prompt>Was this page helpful?</p><button class="btn btn-primary mb-4 feedback--yes">Yes</button>
<button class="btn btn-primary mb-4 feedback--no">No</button></div><script>const yes=document.querySelector(".feedback--yes"),no=document.querySelector(".feedback--no");document.querySelectorAll(".feedback--link").forEach(e=>{e.href=e.href+window.location.pathname});const sendFeedback=e=>{gtag||console.log("!gtag"),gtag("event","click",{event_category:"Helpful",event_label:window.location.pathname,value:e})},disableButtons=()=>{yes.disabled=!0,yes.classList.add("feedback--button__disabled"),no.disabled=!0,no.classList.add("feedback--button__disabled")};yes.addEventListener("click",()=>{sendFeedback(1),disableButtons(),document.querySelector(".feedback--response").classList.remove("feedback--response__hidden")}),no.addEventListener("click",()=>{sendFeedback(0),disableButtons(),document.querySelector(".feedback--response").classList.remove("feedback--response__hidden")})</script></main><div class="d-none d-xl-block col-xl-2 td-toc d-print-none"><div class="td-page-meta ml-2 pb-1 pt-2 mb-0"><a href=https://github.com/apache/dubbo-website/edit/master/content/en/blog/news/dubbo2-js.md target=_blank><i class="fa fa-edit fa-fw"></i> Edit this page</a>
<a href="https://github.com/apache/dubbo-website/new/master/content/en/blog/news/dubbo2-js.md?filename=change-me.md&amp;value=---%0Atitle%3A+%22Long+Page+Title%22%0AlinkTitle%3A+%22Short+Nav+Title%22%0Aweight%3A+100%0Adescription%3A+%3E-%0A+++++Page+description+for+heading+and+indexes.%0A---%0A%0A%23%23+Heading%0A%0AEdit+this+template+to+create+your+new+page.%0A%0A%2A+Give+it+a+good+name%2C+ending+in+%60.md%60+-+e.g.+%60getting-started.md%60%0A%2A+Edit+the+%22front+matter%22+section+at+the+top+of+the+page+%28weight+controls+how+its+ordered+amongst+other+pages+in+the+same+directory%3B+lowest+number+first%29.%0A%2A+Add+a+good+commit+message+at+the+bottom+of+the+page+%28%3C80+characters%3B+use+the+extended+description+field+for+more+detail%29.%0A%2A+Create+a+new+branch+so+you+can+preview+your+new+file+and+request+a+review+via+Pull+Request.%0A" target=_blank><i class="fa fa-edit fa-fw"></i> Create child page</a>
<a href="https://github.com/apache/dubbo-website/issues/new?title=Implementation%20of%20cross-language%20calls%20by%20Dubbo2.js" target=_blank><i class="fab fa-github fa-fw"></i> Create an issue</a>
<a href=https://github.com/apache/dubbo/issues/new target=_blank><i class="fas fa-tasks fa-fw"></i> Create project issue</a></div><nav id=TableOfContents><ul><li><a href=#cross-language-calls-for-micro-service>Cross-language calls for micro service</a></li><li><a href=#cross-language-calls-by-a-common-protocol>Cross-language calls by a common protocol</a><ul><li><a href=#springmvc>SpringMVC</a></li><li><a href=#we-support-some-common-protocols>We support some common protocols</a></li><li><a href=#customized-protocols-for-cross-language-support>Customized Protocols for Cross-language Support</a></li></ul></li><li><a href=#how-does-dubbo2js-solve-problems>How does dubbo2.js solve problems?</a></li><li><a href=#quick-start>Quick Start</a><ul><li><a href=#1-initiate-dubbo-java-provider>1. Initiate dubbo-java-provider</a></li><li><a href=#2-implement-dubbo-client-side-for-nodejs>2. Implement dubbo client-side for nodejs</a></li><li><a href=#3-call-maints>3. Call main.ts:</a></li></ul></li><li><a href=#features>Features</a></li><li><a href=#more-details>More details</a></li></ul></nav><div class="taxonomy taxonomy-terms-cloud taxo-tags"><h5 class=taxonomy-title>Tags</h5><ul class=taxonomy-terms><li><a class=taxonomy-term href=https://cn.dubbo.apache.org/en/tags/ecosystem/ data-taxonomy-term=ecosystem><span class=taxonomy-label>ecosystem</span><span class=taxonomy-count>1</span></a></li><li><a class=taxonomy-term href=https://cn.dubbo.apache.org/en/tags/news/ data-taxonomy-term=news><span class=taxonomy-label>news</span><span class=taxonomy-count>1</span></a></li><li><a class=taxonomy-term href=https://cn.dubbo.apache.org/en/tags/opentelemetry/ data-taxonomy-term=opentelemetry><span class=taxonomy-label>OpenTelemetry</span><span class=taxonomy-count>1</span></a></li><li><a class=taxonomy-term href=https://cn.dubbo.apache.org/en/tags/tracing/ data-taxonomy-term=tracing><span class=taxonomy-label>tracing</span><span class=taxonomy-count>1</span></a></li></ul></div></div></div></div></div><footer class="bg-dark py-5 row d-print-none footer-margin-0"><div class="container-fluid mx-sm-5"><div class=row><div class="col-6 col-sm-4 text-xs-center order-sm-2"><ul class="list-inline mb-0"><li class="list-inline-item mx-2 h3" data-toggle=tooltip data-placement=top title="Dubbo mailing list archive" aria-label="Dubbo mailing list archive"><a class=text-white target=_blank rel="noopener noreferrer" href=https://lists.apache.org/list.html?dev@dubbo.apache.org><i class="fa fa-envelope"></i></a></li></ul></div><div class="col-6 col-sm-4 text-right text-xs-center order-sm-3"><ul class="list-inline mb-0"><li class="list-inline-item mx-2 h3" data-toggle=tooltip data-placement=top title=GitHub aria-label=GitHub><a class=text-white target=_blank rel="noopener noreferrer" href=https://github.com/apache/dubbo><i class="fab fa-github"></i></a></li><li class="list-inline-item mx-2 h3" data-toggle=tooltip data-placement=top title="Subscribe to mailing list" aria-label="Subscribe to mailing list"><a class=text-white target=_blank rel="noopener noreferrer" href=mailto:dev-subscribe@dubbo.apache.org><i class="fa fa-envelope"></i></a></li></ul></div><div class="col-12 col-sm-4 text-center py-2 order-sm-2"><small class=text-white>&copy; 2024 The Apache Software Foundation. Apache and the Apache feather logo are trademarks of The Apache Software Foundation. All Rights Reserved</small></div></div></div></footer><div class="row pt-2 pb-2 footer-margin-0"><div class="container-fluid mx-sm-5"><div class=text-center id=my-footer><img alt=apache_logo src=/imgs/apache_logo.png><ul><li><a href=https://www.apache.org>Foundation</a></li><li><a href=https://www.apache.org/licenses/>License</a></li><li><a href=https://dubbo.apache.org/en/overview/notices/>Security</a></li><li><a href=https://www.apache.org/events/current-event>Events</a></li><li><a href=https://www.apache.org/foundation/sponsorship.html>Sponsorship</a></li><li><a href=https://privacy.apache.org/policies/privacy-policy-public.html>Privacy</a></li><li><a href=https://www.apache.org/foundation/thanks.html>Thanks</a></li></ul></div></div></div><script src=/js/popper.min.js integrity=sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49 crossorigin=anonymous></script><script src=/js/bootstrap.min.js integrity=sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy crossorigin=anonymous></script><script src=/js/main.min.b075178d232d3b0039b3cb6af2fc2e9d90071820167a60f4eea3a79169975ee8.js integrity="sha256-sHUXjSMtOwA5s8tq8vwunZAHGCAWemD07qOnkWmXXug=" crossorigin=anonymous></script><script async src=https://widget.kapa.ai/kapa-widget.bundle.js data-website-id=d763c4f2-f871-400b-aeca-d986c4af73c2 data-project-name="Apache Dubbo" data-project-color=#E8442E data-button-text="Ask AI" data-search-mode-enabled=true data-modal-open-on-command-k=true data-modal-disclaimer="The AI supports multiple languages, but it may not be accessible in China due to recaptcha, a proxy is required." data-project-logo=https://pbs.twimg.com/profile_images/1011849068283191302/FJbH5vbF_400x400.jpg data-modal-example-questions="What is Apache Dubbo?,How to run Apache Dubbo?" data-button-position-top data-button-position-right=20px data-button-position-bottom=200px data-button-position-left></script><script>(function(e,t,n,s){e[s]=e[s]||[];var a=t.getElementsByTagName(n)[0],i=t.createElement(n);i.async=!0,i.id="beacon-aplus",i.setAttribute("exparams","userid=&aplus&sidx=aplusSidex&ckx=aplusCkx"),i.src="//g.alicdn.com/alilog/mlog/aplus_v2.js",i.crossorigin="anonymous",a.parentNode.insertBefore(i,a)})(window,document,"script","aplus_queue"),function(e){var t=e.createElement("script");t.type="text/javascript",t.async=!0,t.src="//g.alicdn.com/aes/??tracker/3.3.4/index.js,tracker-plugin-pv/3.0.5/index.js,tracker-plugin-event/3.0.0/index.js,tracker-plugin-autolog/3.0.3/index.js,tracker-plugin-survey/3.0.3/index.js,tracker-plugin-jserror/3.0.3/index.js,tracker-plugin-resourceError/3.0.3/index.js",t.onload=function(){window.AES_CONFIG=window.AES_CONFIG||{env:"prod"},window.aes=new AES({pid:"zN245h",user_type:6}),window.AESPluginAutologConfig={exposure:"auto"},window.AEMPluginInstances=[aes.use(AESPluginPV,window.AESPluginPVConfig||{enableHistory:!0}),aes.use(AESPluginEvent,window.AESPluginEventConfig||{}),aes.use(AESPluginSurvey,window.AESPluginEventConfig||{}),aes.use(AESPluginAutolog,window.AESPluginAutologConfig||{}),aes.use(AESPluginJSError,window.AESPluginJSError||{}),aes.use(AESPluginResourceError,window.AESPluginResourceError||{})]},setTimeout(function(){e.getElementsByTagName("body")[0].appendChild(t)},800)}(document)</script></body></html>