【Java万花筒】通往高效通信的道路:揭秘Java网络库的奥秘

网络通信艺术:深入探索Java网络通信

前言

Java网络通信是构建分布式系统和构想强大网络应用的核心要素。本文将深入探讨几个重要的Java网络通信库,从基础的Socket到高性能的Netty、灵活的Apache MINA、现代的gRPC,以及通用的OkHttp。通过对每个库的介绍和简单示例,读者将能够更好地理解它们的特性、适用场景和如何在实际项目中应用。

欢迎订阅专栏:Java万花筒

文章目录

  • 网络通信艺术:深入探索Java网络通信
    • 前言
    • 1. Socket
      • 1.1 基础概念
      • 1.2 使用场景
      • 1.3 示例应用
      • 1.4 非阻塞IO与多线程
        • 1.4.1 非阻塞IO
        • 1.4.2 多线程
    • 2. Netty
      • 2.1 概述
      • 2.2 特点与优势
      • 2.3 核心组件
        • 2.3.1 Channel
        • 2.3.2 EventLoop
        • 2.3.3 Handler
      • 2.4 异步通信模型
      • 2.5 应用案例
      • 2.6 高级特性
        • 2.6.1 ByteBuf
        • 2.6.2 ChannelPipeline
        • 2.6.3 WebSocket支持
      • 2.7 应用案例 - 实现简单的聊天室
    • 3. Apache MINA
      • 3.1 概述
      • 3.2 主要特性
      • 3.3 组件与架构
        • 3.3.1 IoFilter
        • 3.3.2 IoHandler
      • 3.4 事件驱动模型
      • 3.5 实际应用场景
      • 3.6 过滤器链与自定义过滤器
        • 3.6.1 过滤器链
        • 3.6.2 自定义过滤器
      • 3.7 MINA与Spring集成
      • 3.8 应用案例 - 实现简单的文件传输
    • 4. gRPC
      • 4.1 简介
      • 4.2 框架特点
      • 4.3 通信模型
      • 4.4 Protocol Buffers
        • 4.4.1 定义服务
        • 4.4.2 生成代码
      • 4.5 应用场景
      • 4.6 高级特性
        • 4.6.1 双向流
        • 4.6.2 拦截器
        • 4.6.3 使用TLS加密
      • 4.7 gRPC与Spring集成
      • 4.8 应用案例 - 实现分布式系统通信
    • 5. OkHttp
      • 5.1 简述
      • 5.2 异步与同步请求
      • 5.3 拦截器
      • 5.4 缓存机制
      • 5.5 连接池管理
      • 5.6 实际应用案例
      • 5.7 高级特性
        • 5.7.1 请求和响应拦截器
        • 5.7.2 WebSocket支持
        • 5.7.3 可取消的请求
      • 5.8 OkHttp与Spring集成
    • 总结

1. Socket

1.1 基础概念

Socket(套接字)是网络通信的基础,提供了一种在网络上进行数据交换的机制。它使用IP地址和端口号来定位网络上的进程,并通过输入流和输出流实现数据传输。

1.2 使用场景

Socket常用于客户端-服务器应用程序,通过TCP或UDP协议进行通信。它可以用于实现各种网络应用,如聊天程序、文件传输等。

1.3 示例应用

以下是一个简单的Java Socket服务器和客户端示例:

Server端代码:

import java.io.*;
import java.net.*;public class Server {public static void main(String[] args) {try {ServerSocket serverSocket = new ServerSocket(8080);System.out.println("Server listening on port 8080...");Socket clientSocket = serverSocket.accept();BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));String clientMessage = in.readLine();System.out.println("Received from client: " + clientMessage);serverSocket.close();} catch (IOException e) {e.printStackTrace();}}
}

Client端代码:

import java.io.*;
import java.net.*;public class Client {public static void main(String[] args) {try {Socket socket = new Socket("localhost", 8080);PrintWriter out = new PrintWriter(socket.getOutputStream(), true);out.println("Hello, Server!");socket.close();} catch (IOException e) {e.printStackTrace();}}
}

这个例子中,Server端监听8080端口,Client端连接到Server并发送消息,Server接收并输出消息。

1.4 非阻塞IO与多线程

在基础的Socket通信中,IO操作是阻塞的,这意味着当一个线程在执行IO操作时,它将被阻塞,无法执行其他任务。为了提高效率,可以使用非阻塞IO和多线程。

1.4.1 非阻塞IO

非阻塞IO允许一个线程处理多个通道,提高了IO操作的效率。通过Selector类可以实现非阻塞IO,允许单个线程管理多个通道。

示例代码:

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;public class NonBlockingServer {public static void main(String[] args) {try {ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();serverSocketChannel.socket().bind(new InetSocketAddress(8080));serverSocketChannel.configureBlocking(false);Selector selector = Selector.open();serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);while (true) {if (selector.selectNow() > 0) {Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();while (iterator.hasNext()) {SelectionKey key = iterator.next();if (key.isAcceptable()) {SocketChannel clientChannel = serverSocketChannel.accept();clientChannel.configureBlocking(false);clientChannel.register(selector, SelectionKey.OP_READ);} else if (key.isReadable()) {SocketChannel clientChannel = (SocketChannel) key.channel();ByteBuffer buffer = ByteBuffer.allocate(1024);clientChannel.read(buffer);buffer.flip();System.out.println("Received from client: " + new String(buffer.array()));}iterator.remove();}}}} catch (IOException e) {e.printStackTrace();}}
}
1.4.2 多线程

另一种提高Socket通信效率的方式是使用多线程。每个连接可以由一个独立的线程处理,允许同时处理多个请求。

示例代码:

import java.io.*;
import java.net.*;public class MultiThreadedServer {public static void main(String[] args) {try {ServerSocket serverSocket = new ServerSocket(8080);System.out.println("Server listening on port 8080...");while (true) {Socket clientSocket = serverSocket.accept();new Thread(() -> handleClient(clientSocket)).start();}} catch (IOException e) {e.printStackTrace();}}private static void handleClient(Socket clientSocket) {try {BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));String clientMessage = in.readLine();System.out.println("Received from client: " + clientMessage);clientSocket.close();} catch (IOException e) {e.printStackTrace();}}
}

在这两个示例中,非阻塞IO通过Selector实现,而多线程通过为每个连接启动一个新线程实现。这些方法可以根据实际需求选择,提高Socket通信的并发处理能力。

2. Netty

2.1 概述

Netty是一个高性能的异步事件驱动网络应用框架,基于Java NIO。它提供了简单易用的API,用于快速开发可维护的网络通信应用。

2.2 特点与优势

  • 高性能:采用异步、基于事件驱动的模型,支持高并发。
  • 灵活性:提供丰富的组件和可扩展性,适用于各种网络应用。
  • 容错性:具备健壮的错误处理机制和可靠性保证。
  • 社区活跃:得到广泛应用和社区支持。

2.3 核心组件

2.3.1 Channel

Channel是Netty中数据的载体,代表了一个开放的连接,可以进行数据的读写。

2.3.2 EventLoop

EventLoop是Netty的核心组件之一,处理连接的生命周期事件和IO事件。

2.3.3 Handler

Handler用于处理入站和出站数据,可以自定义业务逻辑。

2.4 异步通信模型

Netty采用异步非阻塞的通信模型,通过事件驱动机制实现高效的IO操作。

2.5 应用案例

以下是一个简单的Netty服务器和客户端示例:

Server端代码:

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;public class NettyServer {public static void main(String[] args) {NioEventLoopGroup bossGroup = new NioEventLoopGroup();NioEventLoopGroup workerGroup = new NioEventLoopGroup();try {ServerBootstrap serverBootstrap = new ServerBootstrap();serverBootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<NioServerSocketChannel>() {@Overrideprotected void initChannel(NioServerSocketChannel ch) {ch.pipeline().addLast(new ServerHandler());}}).option(ChannelOption.SO_BACKLOG, 128).childOption(ChannelOption.SO_KEEPALIVE, true);serverBootstrap.bind(8080).sync().channel().closeFuture().sync();} catch (InterruptedException e) {e.printStackTrace();} finally {bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();}}
}

Client端代码:

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;public class NettyClient {public static void main(String[] args) {NioEventLoopGroup group = new NioEventLoopGroup();try {Bootstrap bootstrap = new Bootstrap();bootstrap.group(group).channel(NioSocketChannel.class).handler(new ChannelInitializer<NioSocketChannel>() {@Overrideprotected void initChannel(NioSocketChannel ch) {ch.pipeline().addLast(new ClientHandler());}});bootstrap.connect("localhost", 8080).sync().channel().closeFuture().sync();} catch (InterruptedException e) {e.printStackTrace();} finally {group.shutdownGracefully();}}
}

在这个例子中,Server端监听8080端口,Client端连接到Server并进行简单的数据交互。

2.6 高级特性

2.6.1 ByteBuf

ByteBuf是Netty中用于处理字节数据的高级缓冲区,相比Java原生的ByteBuffer更加灵活,提供了更多的操作方法。

示例代码:

ByteBuf buffer = Unpooled.buffer(10);
buffer.writeBytes("Hello".getBytes());
System.out.println("Readable bytes: " + buffer.readableBytes());
2.6.2 ChannelPipeline

ChannelPipeline是Netty中的事件处理机制,允许用户自定义处理器并按顺序组织,实现复杂的业务逻辑。

示例代码:

ChannelPipeline pipeline = channel.pipeline();
pipeline.addLast("handler1", new CustomHandler1());
pipeline.addLast("handler2", new CustomHandler2());
2.6.3 WebSocket支持

Netty提供了对WebSocket的原生支持,可以轻松实现WebSocket通信。

示例代码:

WebSocketServerHandshakerFactory handshakerFactory = new WebSocketServerHandshakerFactory("ws://localhost:8080/websocket", null, false
);WebSocketServerHandshaker handshaker = handshakerFactory.newHandshaker(request);if (handshaker == null) {WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(channel);
} else {handshaker.handshake(channel, request);
}

2.7 应用案例 - 实现简单的聊天室

通过Netty,我们可以轻松实现一个简单的聊天室,实现多客户端之间的实时通信。以下是一个简单的示例:

Server端代码:

// 略...
pipeline.addLast("chatHandler", new ChatServerHandler());

Client端代码:

// 略...
pipeline.addLast("chatHandler", new ChatClientHandler());

在这个聊天室示例中,通过Netty的ChannelPipeline和自定义的Handler实现了多客户端之间的消息交互。这展示了Netty强大的灵活性和适用性,使得复杂的应用也能轻松构建。

3. Apache MINA

3.1 概述

Apache MINA(Multipurpose Infrastructure for Network Applications)是一个灵活的、高性能的网络应用框架,它简化了网络应用的开发过程。

3.2 主要特性

  • 面向事件的编程模型:基于事件驱动,易于处理异步操作。
  • 可扩展性:提供可扩展的过滤器链,允许自定义处理逻辑。
  • 高性能:采用NIO机制,支持高并发处理。

3.3 组件与架构

3.3.1 IoFilter

IoFilter是MINA的核心组件之一,用于处理输入和输出的数据流,可通过过滤器链进行组合和定制。

3.3.2 IoHandler

IoHandler用于处理I/O事件,可以自定义业务逻辑。

3.4 事件驱动模型

MINA采用事件驱动的模型,通过触发不同类型的事件来处理网络应用的各个阶段。

3.5 实际应用场景

以下是一个简单的MINA服务器和客户端示例:

Server端代码:

import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;import java.net.InetSocketAddress;
import java.nio.charset.Charset;public class MinaServer {public static void main(String[] args) {IoAcceptor acceptor = new NioSocketAcceptor();acceptor.getSessionConfig().setReadBufferSize(2048);acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);acceptor.setHandler(new IoHandlerAdapter() {@Overridepublic void messageReceived(IoSession session, Object message) {String msg = message.toString();System.out.println("Received from client: " + msg);}});acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));try {acceptor.bind(new InetSocketAddress(8080));} catch (IOException e) {e.printStackTrace();}}
}

Client端代码:

import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.service.IoConnector;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketConnector;import java.net.InetSocketAddress;
import java.nio.charset.Charset;public class MinaClient {public static void main(String[] args) {IoConnector connector = new NioSocketConnector();connector.getSessionConfig().setReadBufferSize(2048);connector.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);connector.setHandler(new IoHandlerAdapter() {@Overridepublic void sessionOpened(IoSession session) {session.write("Hello, Server!");}});connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));ConnectFuture future = connector.connect(new InetSocketAddress("localhost", 8080));future.awaitUninterruptibly();IoSession session = future.getSession();session.getCloseFuture().awaitUninterruptibly();connector.dispose();}
}

在这个例子中,Server端监听8080端口,Client端连接到Server并进行简单的数据交互。 MINA的过滤器链和事件处理机制可根据具体需求进行灵活配置。

3.6 过滤器链与自定义过滤器

3.6.1 过滤器链

MINA的过滤器链是由多个IoFilter组成的,每个IoFilter负责特定的功能。过滤器链通过IoSession的write和read事件依次调用过滤器,实现对数据的处理和转换。

示例代码:

DefaultIoFilterChainBuilder chainBuilder = acceptor.getFilterChain();
chainBuilder.addLast("logger", new LoggingFilter());
chainBuilder.addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));
3.6.2 自定义过滤器

可以通过实现IoFilter接口自定义过滤器,实现特定的数据处理逻辑。

示例代码:

public class MyFilter extends IoFilterAdapter {@Overridepublic void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception {// 自定义处理逻辑super.messageReceived(nextFilter, session, message);}
}

3.7 MINA与Spring集成

MINA可以与Spring框架集成,通过Spring的IoC容器管理MINA的组件。这样可以更好地利用Spring的依赖注入和配置管理功能。

示例代码:

@Configuration
public class MinaConfig {@Beanpublic IoAcceptor ioAcceptor() {// 配置IoAcceptor// ...return acceptor;}@Beanpublic MyHandler myHandler() {// 配置自定义IoHandlerreturn new MyHandler();}
}

3.8 应用案例 - 实现简单的文件传输

通过MINA,我们可以轻松实现文件传输功能,以下是一个简单的示例:

Server端代码:

// 略...
chainBuilder.addLast("fileHandler", new FileTransferServerHandler());

Client端代码:

// 略...
chainBuilder.addLast("fileHandler", new FileTransferClientHandler());

在这个文件传输示例中,通过自定义过滤器和IoHandler实现了文件的传输。 MINA的灵活性和可扩展性使得实现各种网络应用变得相对简单。

4. gRPC

4.1 简介

gRPC是由Google开发的高性能开源RPC(Remote Procedure Call)框架,基于HTTP/2协议传输,使用Protocol Buffers进行序列化。

4.2 框架特点

  • 强大的IDL(Interface Definition Language):使用ProtoBuf定义服务和消息格式。
  • 多语言支持:支持多种编程语言,如Java、C++、Python等。
  • 支持双向流:可以在同一个连接上同时进行双向流通信。
  • 高性能:基于HTTP/2和ProtoBuf,提供高效的网络通信。

4.3 通信模型

gRPC使用基于HTTP/2的双向流通信模型,客户端和服务端可以异步发送消息。

4.4 Protocol Buffers

4.4.1 定义服务

使用ProtoBuf定义gRPC服务,包括服务接口和消息格式。

4.4.2 生成代码

通过ProtoBuf编译器生成对应语言的客户端和服务端代码。

4.5 应用场景

以下是一个简单的gRPC服务和客户端示例:

Proto文件定义:

syntax = "proto3";service Greeter {rpc SayHello (HelloRequest) returns (HelloResponse);
}message HelloRequest {string name = 1;
}message HelloResponse {string greeting = 1;
}

Server端代码:

import io.grpc.Server;
import io.grpc.ServerBuilder;
import io.grpc.stub.StreamObserver;public class GreeterServer {public static void main(String[] args) throws IOException, InterruptedException {Server server = ServerBuilder.forPort(8080).addService(new GreeterImpl()).build();server.start();System.out.println("Server started on port 8080");server.awaitTermination();}static class GreeterImpl extends GreeterGrpc.GreeterImplBase {@Overridepublic void sayHello(HelloRequest request, StreamObserver<HelloResponse> responseObserver) {String greeting = "Hello, " + request.getName() + "!";HelloResponse response = HelloResponse.newBuilder().setGreeting(greeting).build();responseObserver.onNext(response);responseObserver.onCompleted();}}
}

Client端代码:

import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;public class GreeterClient {public static void main(String[] args) {ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 8080).usePlaintext().build();GreeterGrpc.GreeterBlockingStub blockingStub = GreeterGrpc.newBlockingStub(channel);HelloRequest request = HelloRequest.newBuilder().setName("John").build();HelloResponse response = blockingStub.sayHello(request);System.out.println("Received from server: " + response.getGreeting());channel.shutdown();}
}

在这个例子中,Server端监听8080端口,Client端连接到Server并发送消息。通过ProtoBuf定义了简单的服务和消息格式,gRPC框架负责处理通信和序列化。

4.6 高级特性

4.6.1 双向流

gRPC支持双向流通信,允许客户端和服务端在同一个连接上异步发送消息。

示例代码:

service Chat {rpc JoinChat (stream ChatMessage) returns (stream ChatMessage);
}message ChatMessage {string user = 1;string message = 2;
}
4.6.2 拦截器

gRPC拦截器允许在请求和响应的不同阶段添加逻辑处理,例如身份验证、日志记录等。

示例代码:

public class AuthenticationInterceptor implements ServerInterceptor {@Overridepublic <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next) {// 添加身份验证逻辑return next.startCall(call, headers);}
}
4.6.3 使用TLS加密

gRPC支持使用TLS(Transport Layer Security)对通信进行加密,提供更安全的通信方式。

示例代码:

Server server = ServerBuilder.forPort(8443).useTransportSecurity(certChainFile, privateKeyFile).addService(new GreeterImpl()).build();

4.7 gRPC与Spring集成

gRPC可以与Spring框架集成,通过Spring Boot提供的@GrpcService注解方便地将gRPC服务整合到Spring应用中。

示例代码:

@GrpcService
public class GreeterGrpcService extends GreeterGrpc.GreeterImplBase {@Overridepublic void sayHello(HelloRequest request, StreamObserver<HelloResponse> responseObserver) {String greeting = "Hello, " + request.getName() + "!";HelloResponse response = HelloResponse.newBuilder().setGreeting(greeting).build();responseObserver.onNext(response);responseObserver.onCompleted();}
}

4.8 应用案例 - 实现分布式系统通信

通过gRPC,可以轻松实现分布式系统中各个服务之间的通信,以下是一个简单的示例:

Proto文件定义:

syntax = "proto3";service OrderService {rpc PlaceOrder (OrderRequest) returns (OrderResponse);
}message OrderRequest {string product = 1;int32 quantity = 2;
}message OrderResponse {string status = 1;
}

Server端代码:

@GrpcService
public class OrderServiceGrpcImpl extends OrderServiceGrpc.OrderServiceImplBase {@Overridepublic void placeOrder(OrderRequest request, StreamObserver<OrderResponse> responseObserver) {// 处理订单逻辑OrderResponse response = OrderResponse.newBuilder().setStatus("Order placed successfully").build();responseObserver.onNext(response);responseObserver.onCompleted();}
}

Client端代码:

public class OrderServiceClient {public static void main(String[] args) {ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 8080).usePlaintext().build();OrderServiceGrpc.OrderServiceBlockingStub blockingStub = OrderServiceGrpc.newBlockingStub(channel);OrderRequest request = OrderRequest.newBuilder().setProduct("Laptop").setQuantity(2).build();OrderResponse response = blockingStub.placeOrder(request);System.out.println("Order status: " + response.getStatus());channel.shutdown();}
}

在这个例子中,通过gRPC实现了一个简单的订单服务和客户端,展示了gRPC在分布式系统中的应用。

5. OkHttp

5.1 简述

OkHttp是Square公司开发的一款高性能、可扩展的HTTP客户端,基于Java实现。它简化了HTTP通信,提供了丰富的功能,包括同步和异步请求、连接池管理、拦截器等。

5.2 异步与同步请求

OkHttp支持同步和异步的HTTP请求。同步请求在当前线程执行,而异步请求则在后台线程执行,通过回调通知结果。

5.3 拦截器

OkHttp使用拦截器来实现功能扩展和自定义操作,可以在请求和响应的过程中添加、修改、重试等。

5.4 缓存机制

OkHttp提供了强大的缓存支持,包括对请求和响应的缓存控制、本地缓存等。

5.5 连接池管理

OkHttp通过连接池管理HTTP连接,提高性能并减少延迟,支持连接的复用和保持。

5.6 实际应用案例

以下是一个简单的OkHttp异步请求示例:

import okhttp3.*;import java.io.IOException;public class OkHttpExample {public static void main(String[] args) {OkHttpClient client = new OkHttpClient();String url = "https://jsonplaceholder.typicode.com/posts/1";Request request = new Request.Builder().url(url).build();client.newCall(request).enqueue(new Callback() {@Overridepublic void onResponse(Call call, Response response) throws IOException {if (response.isSuccessful()) {String responseBody = response.body().string();System.out.println("Response from server:\n" + responseBody);} else {System.out.println("Request failed. Code: " + response.code());}}@Overridepublic void onFailure(Call call, IOException e) {e.printStackTrace();}});}
}

在这个例子中,使用OkHttp发起异步GET请求,通过回调处理响应结果。 OkHttp的简洁API和丰富功能使得处理HTTP通信变得更加方便。

5.7 高级特性

5.7.1 请求和响应拦截器

OkHttp的请求和响应拦截器允许开发者在请求发起前和响应返回前进行处理,可以用于添加公共参数、修改请求头等操作。

示例代码:

public class LoggingInterceptor implements Interceptor {@Overridepublic Response intercept(Chain chain) throws IOException {Request request = chain.request();long startTime = System.nanoTime();System.out.println("Sending request: " + request.url());Response response = chain.proceed(request);long endTime = System.nanoTime();System.out.println("Received response for " + response.request().url() +" in " + (endTime - startTime) / 1e6 + "ms");return response;}
}
5.7.2 WebSocket支持

OkHttp提供了对WebSocket的原生支持,可以方便地实现WebSocket通信。

示例代码:

Request request = new Request.Builder().url("wss://example.com/socket").build();WebSocket webSocket = client.newWebSocket(request, new WebSocketListener() {@Overridepublic void onOpen(WebSocket webSocket, Response response) {webSocket.send("Hello, Server!");}@Overridepublic void onMessage(WebSocket webSocket, String text) {System.out.println("Received from server: " + text);}@Overridepublic void onClosed(WebSocket webSocket, int code, String reason) {System.out.println("Connection closed: " + code + ", " + reason);}@Overridepublic void onFailure(WebSocket webSocket, Throwable t, Response response) {t.printStackTrace();}
});
5.7.3 可取消的请求

OkHttp允许通过取消请求来提高性能和资源利用率,避免不必要的网络请求。

示例代码:

Call call = client.newCall(request);
call.enqueue(new Callback() {// 省略回调方法实现
});// 取消请求
call.cancel();

5.8 OkHttp与Spring集成

OkHttp可以与Spring框架集成,通过Spring Boot提供的RestTemplate或自定义ClientHttpRequestFactory使用OkHttp作为HTTP客户端。

示例代码:

@Configuration
public class OkHttpConfig {@Beanpublic OkHttpClient okHttpClient() {return new OkHttpClient.Builder().addInterceptor(new LoggingInterceptor()).build();}@Beanpublic RestTemplate restTemplate(OkHttpClient okHttpClient) {return new RestTemplate(new OkHttp3ClientHttpRequestFactory(okHttpClient));}
}

在这个配置中,通过自定义OkHttpClientRestTemplate,实现了OkHttp与Spring的集成。这使得在Spring应用中使用OkHttp变得更加灵活和方便。

总结

通过学习本文,读者将获得关于Java网络通信的全面认识。Socket作为基础,为我们提供了最简单的网络通信方式。Netty和Apache MINA则提供了更高级的异步事件驱动模型,适用于高性能和大规模的网络应用。gRPC作为现代RPC框架,通过HTTP/2和ProtoBuf提供了强大的功能和性能。最后,OkHttp作为通用的HTTP客户端,简化了HTTP通信的复杂性,提供了丰富的功能。

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

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

相关文章

Java 实现单链表

文章目录 节点类定义单链表类总结 单链表是一种常用的数据结构&#xff0c;它由若干个节点&#xff08;Node&#xff09;组成&#xff0c;每个节点包含两部分&#xff1a;一部分是数据域&#xff0c;用于存储数据&#xff1b;另一部分是指针域&#xff0c;用于指向下一个节点。…

Mybatis实现映射,一次查询和嵌套查询

1.实现映射 Mybatis的最大魅力就在于它的语句映射。实现映射一般有一下三种方法&#xff1a; 当我们在数据库的列名和java中的属性名完全相同时&#xff0c;mybatis会自动映射并将查询结果封装。 对于由多个单词组成的名字时&#xff08;例如studentgender&#xff09;&…

时序预测 | Matlab基于灰色隐马尔可夫模型(HMMP-GM11)的时间序列预测

时序预测 | Matlab基于灰色隐马尔可夫模型(HMMP-GM11)的时间序列预测 目录 时序预测 | Matlab基于灰色隐马尔可夫模型(HMMP-GM11)的时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 灰色HMMP-GM11改进模型,通过引入隐马尔可夫模型(HMM)来对原始数据进行状态分…

单调栈练习(五)— 子数组的最小值之和

题目 同样的LeetCode原题&#xff1a;题目链接 给定一个整数数组 arr&#xff0c;找到 min(b) 的总和&#xff0c;其中 b 的范围为 arr 的每个&#xff08;连续&#xff09;子数组。 由于答案可能很大&#xff0c;因此 返回答案模 10^9 7 。 思路 暴力解 先来说暴力解的思路…

OpenssH 漏洞修复

文章目录 OpenSSH 漏洞修复需求&#xff1a;准备环境配置阿里云yum源关闭防火墙 && SELinux安装 telnet-server安装 zlib 软件包安装OpenssL安装 OpenssH报错信息 OpenSSH 漏洞修复 场景&#xff1a; CentOS Stream 9 系统ssh默认版本一般是OpenSSH_8.7p1 &#xff0c;…

【国内访问github不稳定】可以尝试fastgithub解决这个问题

1、下载 https://github.com/dotnetcore/FastGithub https://github.com/dotnetcore/FastGithub/releases 官网下载即可&#xff0c;比如&#xff0c;我用的是这个&#xff1a;fastgithub_osx-x64.zip&#xff08;点这里下载&#xff09; 2、安装 如下图双击启动即可 3、…

科研绘图(二)气泡图

气泡矩阵图&#xff08;Bubble Matrix Plot&#xff09;&#xff0c;通常用于显示三个变量之间的关系。这种图表类型将数据点表示为气泡的形式&#xff0c;其中气泡的大小通常表示第三个数值变量的大小。图表的X轴和Y轴代表两个分类或定量变量。颜色可能代表另一个分类变量或是…

CAN总线通信详解 (超详细配34张高清图)

CAN总线通信详解 (超详细配34张高清图) 1. CAN总线历史 CAN 是 Controller Area Network 的缩写&#xff08;以下称为 CAN&#xff09;&#xff0c;是 ISO国际标准化的串行通信协议。 在当前的汽车产业中&#xff0c;出于对安全性、舒适性、方便性、低公害、低成本的要求&#…

Python爬虫---scrapy shell 调试

Scrapy shell是Scrapy提供的一个交互式shell工具&#xff0c;它可以帮助我们进行爬虫的开发和调试。可以使用它来测试xpath或css表达式&#xff0c;查看它们是如何工作的&#xff0c;以及它们从你试图抓取的网页中提取的数据。它允许你在编写spider时交互地测试表达式&#xff…

ipad协议滑块讲解-3(2000038登录滑块)

请使用python进行编译失调&#xff0c;切勿用于非法用途&#xff01;&#xff01; 创建main.js脚本 代码如下 const {VM,VMScript} require("vm2"); const fs require("fs"); const {read} require("./env/main"); const {readJsCode} re…

图像异或加密及唯密文攻击

异或加密 第一种加密方式为异或加密&#xff0c;异或加密的原理是利用异或的可逆性质&#xff0c;原始图像的像素八位bit分别与伪随机二进制序列异或&#xff0c;得到的图像就为加密图像。如下图对lena图像进行加密。 伪随机序列为一系列二进制代码&#xff0c;它受加密秘钥控…

【重点!!!】【DP】354. 俄罗斯套娃信封问题

题目 法1&#xff1a;DP&#xff0c;LIS问题 基本方法&#xff0c;必须掌握&#xff01;&#xff01;&#xff01; class Solution {public int maxEnvelopes(int[][] envelopes) {int n envelopes.length;if (n < 2) {return n;}Arrays.sort(envelopes, (a1, a2) ->…

php文件实战分析

1.php文件分析如下 这段代码是一个简单的 PHP 文件上传处理脚本。让我来为你进行分析&#xff1a; 首先&#xff0c;通过检查 $_FILES["file"]["error"] 的值来确定是否发生了错误。如果 $_FILES["file"]["error"] 大于 0&#xff0c…

CSS样式学习

html超文本传输标签&#xff0c;属性等权重 outline 标签轮廓 <input type"text"> <textarea cols"30" rows"10"></textarea> outline: none; 表示无轮廓 &#xff08;开发时用的比较多&#xff09; CSS 轮廓&#xff…

数据结构入门到入土——栈(Stack)和队列(Queue)

目录 一&#xff0c;栈&#xff08;Stack&#xff09; 1.1 概念 1.2 栈的使用 1.3 栈的模拟实现 1.4 栈的应用场景 1.5 栈&#xff0c;虚拟机栈&#xff0c;栈帧有什么区别&#xff1f; 二&#xff0c;队列&#xff08;Queue&#xff09; 2.1 概念 2.2 队列的使用 2.3 …

H3C在交换机上查找一个IP

一、案例背景&#xff1a; 一台wifi&#xff0c;在防火墙上有此IP的安全告警&#xff0c;需要查找到这个端口&#xff0c;并改到其他的隔离网段上网 二、排查过程&#xff1a; 自上向下查&#xff1a;在汇聚交换机上ping了一下&#xff0c;通的&#xff0c;然后查了下mac&…

前端js调用Lodop实现云打印

一、下载Lodop控件 官网&#xff1a;下载中心 - Lodop和C-Lodop官网主站 二、解压后安装 双击进行安装&#xff0c;里面有些页面文件是一些教程案例 勾选云服务工作模式 安装成功会自动启动 浏览器访问地址&#xff1a;http://localhost:8000/ 首页最下面有个教程案例跳转地址&…

DNS 域名解析

一 、名字解析介绍和DNS 当前TCP/IP网络中的设备之间进行通信&#xff0c;是利用和依赖于IP地址实现的。但数字形式的IP地址是很难记忆的。当网络设备众多&#xff0c;想要记住每个设备的IP地址&#xff0c;可以说是"不可能完成的任务"。那么如何解决这一难题呢&…

独孤思维:​凌驾于所有赚钱项目的副业

01 混群&#xff0c;尤其是混付费群。 在群里不要爆fen&#xff0c;不要广告。 真诚分享你的副业心得&#xff0c;经验&#xff0c; 自然能吸引到别人&#xff0c;主动加你。 这样&#xff0c;你就多了一个精准获客的方法。 02 不要在乎眼前的成绩。 没有意义。 独孤写…

蓝桥杯单片机进阶教程4——需要分配进程的模块

前言&#xff1a; 【蓝桥杯单片机保姆级教学】 https://www.bilibili.com/video/BV1h3411m7Aw/?p117&share_sourcecopy_web&vd_sourcec4fc67867c5218768e783d04475bc5a2 P117-118 比赛的时候也按照这个顺序来写 一、数码管显示 分析考题 &#xff08;1&#xff09;…