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

Posted alf_cee

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了dubbo源码实践-transport 网络传输层的例子相关的知识,希望对你有一定的参考价值。

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等通用框架。

以上是关于dubbo源码实践-transport 网络传输层的例子的主要内容,如果未能解决你的问题,请参考以下文章

dubbo源码实践-protocol层例子

dubbo源码实践-protocol层例子

源码解读Dubbo分层设计思想

dubbo源码实践-config层例子

dubbo源码实践-config层例子

dubbo源码实践-Exchange 信息交换层例子