dubbo源码实践-transport 网络传输层的例子

news2024/11/16 16:51:26

1 Transporter层概述

Transporter层位于第2层,已经实现了完整的TCP通信,定义了一套Dubbo自己的API接口,支持Netty、Mina等框架。

官方定义:

transport 网络传输层:抽象 mina 和 netty 为统一接口,以 Message 为中心,扩展接口为 Channel, Transporter, Client, Server, Codec

个人理解:这里说的Message其实就是指java的任意对象(Object类)。

如:ChannelHandler类中的void sent(Channel channel, Object message) throws RemotingException;方法,负责接收一个对象。

如:Client类的void send(Object message, boolean sent) throws RemotingException;方法,负责发送一个对象。

通过查看Transporter扩展点,可以知道目前dubbo支持的TCP框架。

2 实践例子

2.1 项目结构

由于是TCP框架,所以有服务端和客户端,两端的代码。

服务端:

  • NettyTransporterServerTest类是服务端的执行入口

  • ServerChannelHandler类是一个回调了,当事件发生时,dubbo内部会回调相应的方法。类似Netty中的ChannelHandler。

客户端:

  • NettyTransporterClientTest类是客户端的执行入口

  • ClientChannelHandler类是一个回调了,当事件发生时,dubbo内部会回调相应的方法。类似Netty中的ChannelHandler。

2.2 服务端代码

NettyTransporterServerTest代码

Transporter接口是核心类,通过调用bind方法可以在指定端口上监听,等待客户端连接。

URL用来指定ip和端口。

package org.example.dubbo.transport;

import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.URLBuilder;
import org.apache.dubbo.remoting.ChannelHandler;
import org.apache.dubbo.remoting.RemotingException;
import org.apache.dubbo.remoting.RemotingServer;
import org.apache.dubbo.remoting.Transporter;
import org.apache.dubbo.remoting.transport.netty4.NettyTransporter;

import java.io.IOException;

/** 启动netty 服务器 .  使用命令行 netstat -ano | findstr 8888 查看端口是否监听*/
public class NettyTransporterServerTest {
    public static void main(String[] args) throws RemotingException, IOException {
        Transporter transporter = new NettyTransporter();
        ChannelHandler channelHandler = new ServerChannelHandler();

        URLBuilder urlBuilder = new URLBuilder();
        urlBuilder.setHost("localhost");
        urlBuilder.setPort(8888);

        URL url = urlBuilder.build();
        RemotingServer remotingServer = transporter.bind(url, channelHandler);
        System.in.read();
    }
}

ServerChannelHandler代码

该类完成具体的出逻辑,目前为了方便调试都是打印了基本日志信息。

package org.example.dubbo.transport;

import org.apache.dubbo.remoting.Channel;
import org.apache.dubbo.remoting.ChannelHandler;
import org.apache.dubbo.remoting.RemotingException;

public class ServerChannelHandler implements ChannelHandler{
    @Override
    public void connected(Channel channel) throws RemotingException {
        System.out.println("server-XXX connected");
    }
    @Override
    public void disconnected(Channel channel) throws RemotingException {
        System.out.println("server-XXX disconnected");
    }
    @Override
    public void sent(Channel channel, Object message) throws RemotingException {
        System.out.println("server-XXX sent="+message);
    }
    @Override
    public void received(Channel channel, Object message) throws RemotingException {
        System.out.println("server-XXX received=" + message);
    }
    @Override
    public void caught(Channel channel, Throwable exception) throws RemotingException {
        System.out.println("server-XXX caught");
        exception.printStackTrace();
    }
}

2.3 客户端代码

NettyTransporterClientTest代码

Transporter接口是核心类,通过调用connect方法连接到指定的服务端。

URL用来指定ip和端口。

连接完成后,客户端调用了client.send("abc", true) 来发送了一条信息。

package org.example.dubbo.transport;

import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.URLBuilder;
import org.apache.dubbo.remoting.ChannelHandler;
import org.apache.dubbo.remoting.Client;
import org.apache.dubbo.remoting.RemotingException;
import org.apache.dubbo.remoting.Transporter;
import org.apache.dubbo.remoting.transport.netty4.NettyTransporter;

public class NettyTransporterClientTest {
    public static void main(String[] args) throws RemotingException {
        Transporter transporter = new NettyTransporter();
        ChannelHandler channelHandler = new ClientChannelHandler();
        URLBuilder urlBuilder = new URLBuilder();
        urlBuilder.setHost("localhost");
        urlBuilder.setPort(8888);
        URL url = urlBuilder.build();
        Client client = transporter.connect(url, channelHandler);
        client.send("abc", true);
        client.close();
    }
}

ClientChannelHandler代码

package org.example.dubbo.transport;

import org.apache.dubbo.remoting.Channel;
import org.apache.dubbo.remoting.ChannelHandler;
import org.apache.dubbo.remoting.RemotingException;
public class ClientChannelHandler implements ChannelHandler{
    @Override
    public void connected(Channel channel) throws RemotingException {
        System.out.println("Client-XXX connected");
    }
    @Override
    public void disconnected(Channel channel) throws RemotingException {
        System.out.println("Client-XXX disconnected");
    }
    @Override
    public void sent(Channel channel, Object message) throws RemotingException {
        System.out.println("Client-XXX sent="+message);
    }
    @Override
    public void received(Channel channel, Object message) throws RemotingException {
        System.out.println("Client-XXX received=" + message);
    }
    @Override
    public void caught(Channel channel, Throwable exception) throws RemotingException {
        System.out.println("Client-XXX caught");
        exception.printStackTrace();
    }
}

2.4 执行结果

2.4.1 启动Server端

通过netstat -ano | findstr 8888 命令查看一下是否启动成功。

启动客户端后,可以在服务端看到日志

  1. server-XXX connected : 表示客户端已经连接成功。

  1. server-XXX received=abc :表示服务端已经接收到了abc数据。

  1. server-XXX caught : 因为客户端发送完数据就关闭了,所以执行了caugth方法。

  1. server-XXX disconnected:服务端关闭了连接。

2.4.2 启动客户端

  1. Client-XXX connected : 客户端连接服务端成功。

  1. Client-XXX sent=abc :发送了abc数据。

2.5 总结

通过dubbo的封装,几行代码就可以实现服务端和客户端的代码,并且可以随时切换Netty、Mina等通用框架。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/136725.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

剑指 Offer 09. 用两个栈实现队列

用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 ) 示例 1: 输入: ["…

自然语言处理 第11章 问答系统 复习

问答系统问答系统概述问答系统定义问答(QA)系统发展历程问答系统分类:问答系统框架:内容提要专家系统检索式问答系统1.问题分析主要功能:问题分类 和 关键词提取问题分类实现方法2.关键词提取检索模块相关文档检索句段检索3. 答案抽取模块检索…

回顾2022年,展望2023年

这里写目录标题回顾2022年博客之星你参加了吗?学习方面写博客方面在涨粉丝方面展望2023回顾2022年 时间如梭,转眼间已经2023年了。 你开始做总结了吗? 博客之星你参加了吗? 这是 2022 博客之星 的竞选帖子, 请你在这…

【从零开始学习深度学习】36. 门控循环神经网络之长短期记忆网络(LSTM)介绍、Pytorch实现LSTM并进行训练预测

上一篇文章介绍了一种门控循环神经网络门控循环单元GRU,本文将介绍另一种常用的门控循环神经网络:长短期记忆(long short-term memory,LSTM),它比GRU稍复杂一点。 本文将介绍其实现方法,并使用其…

leetcode 221. 最大正方形-java题解

题目所属分类 动态规划 前面写过一个面积最大的长方形 传送门 f[i, j]表示:所有以(i,j)为右下角的且只包含 1 的正方形的边长最大值 原题链接 在一个由 ‘0’ 和 ‘1’ 组成的二维矩阵内,找到只包含 ‘1’ 的最大正方形,并返回其面积。 代…

最邻近方法和最邻近插入法求TSP问题近似解(可视化+代码)

摘要:本文总体内容为介绍用最邻近方法(Nearest Neighbor Algorithm) 和最邻近插入法求解旅行商问题(Traveling Saleman Problem,TSP)。同时使用python实现算法,并调用networkx库实现可视化。此文为本人图论课下作业的成品,含金量:…

【若依】前后端分离版本

一、何为框架?若依框架又是什么?具备什么功能? 框架的英文为Framework,带有骨骼,支架的含义。在软件工程中,框架往往被定义为整个或部分系统的可重用设计,是一个可重复使用的设计构件。类似于一…

leetcode1801:积压订单中的订单总数(1.2日每日一题)

迟来的元旦快乐!!! 题目表述: 给你一个二维整数数组 orders ,其中每个 orders[i] [pricei, amounti, orderTypei] 表示有 amounti 笔类型为 orderTypei 、价格为 pricei 的订单。 订单类型 orderTypei 可以分为两种…

电子档案利用安全控制的办法与实现

这篇文章是笔者2015年发表在《保密科学技术》第2期的一篇文章,时隔7年半温习了一遍之后感觉还有一定的可取之处,所以在结合当前档案法律法规相关要求并修改完善其中部分内容之后分享给大家。 引言 INTRODUCTION 21世纪是一个信息化高度发展的时代&#…

网站漏洞与漏洞靶场(DVWA)

数据来源 本文仅用于信息安全学习,请遵守相关法律法规,严禁用于非法途径。若观众因此作出任何危害网络安全的行为,后果自负,与本人无关。 为什么要攻击网站?常见的网站漏洞有哪些? 在互联网中,…

Java安装详细步骤(win10)

一、下载JDK JDK下载地址:Java Archive | Oracle,下图为win10版本 二、安装过程 2.1 以管理员方式运行exe 2.2 更改JDK安装目录和目标文件夹的位置 2.3 安装完成 三、配置环境变量 3.1 快速打开环境变量设置 WinR打开运行对话框,输入…

【计组】CPU并行方案--《深入浅出计算机组成原理》(四)

课程链接:深入浅出计算机组成原理_组成原理_计算机基础-极客时间 一、Superscalar和VLIW 程序的 CPU 执行时间 指令数 CPI Clock Cycle Time CPI 的倒数,又叫作 IPC(Instruction Per Clock),也就是一个时钟周期…

软件测试新手入门必看

随着软件开发行业的日益成熟,软件测试岗位的需求也越来越大。众所周知,IT技术行业一直以来都是高薪岗位的代名词,零基础想要转业的朋友想要进入这个行业,入门软件测试是最佳的途径之一。考虑到大多数软件测试小白对这个行业的一片…

动态规划——树形dp

树形dp 文章目录树形dp概述树形dp 路径问题树的最长路径思路代码树的中心换根DP思路代码数字转换思路代码树形dp 有依赖的背包二叉苹果树思路代码树形dp 状态机没有上司的舞会思路代码战略游戏思路代码皇宫看守思路代码总结概述 树形 DP,即在树上进行的 DP。由于…

springboot常用启动初始化方法

在日常开发时,我们常常需要 在SpringBoot 应用启动时执行某一些逻辑,如下面的场景: 1、获取一些当前环境的配置或变量; 2、连接某些外部系统,读取相关配置和交互; 3、启动初始化多线程(线程池…

Linux 网络编程套接字

目录 一.网络知识 1.网络通信 2.端口号 (1)介绍 (2)端口号和进程ID 3.TCP协议 4.UDP协议 5.网络字节序 二. socket编程接口 1.socket常见API 2.sockaddr结构 (1)sockaddr结构 (2&a…

JavaScript 语句

文章目录JavaScript 语句JavaScript 语句分号 ;JavaScript 代码JavaScript 代码块JavaScript 语句标识符JavaScript 语句 JavaScript 语句向浏览器发出的命令。语句的作用是告诉浏览器该做什么。 JavaScript 语句 JavaScript 语句是发给浏览器的命令。 这些命令的作用是告诉浏…

顶象入选信通院“数字政府建设赋能计划”成员单位

为进一步推动数字政府建设提质增效,由中国信息通信研究院(以下简称“中国信通院”)联合数字政府相关企业、科研机构共同成立“数字政府建设赋能计划”,旨在凝聚各方力量,整合优质资源,开展技术攻关&#xf…

FlinkSQL基本语法和概念

Flink Sql1、简介2、网址3、SQL客户端4、Queries5、Create6、Drop7、Alter8、Insert9、ANALYZE10、Describe11、Explain12、Use13、Show14、Load15、Unload16、Set17、Reset18、Jar19、Windowing TVF19.1、TUMBLE(滚动窗口)19.2、HOP(滑动窗口…

rabbitmq+netcore6 【2】Work Queues:一个生产者两个消费者

文章目录1)准备工作2)新建消费者13)新建消费者24)生产者5)知识点解读1、autoAck: true2、重复声明/前后不一致3、Message durability 消息持久化4、Fair Dispatch 公平调度5、综合以上知识点的代码:官网参考…