本人写的一个使用Netty实现的一个异步Socket代码

package test.core.nio;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.net.InetSocketAddress;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.math.NumberUtils;
import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory; /**
* @author xfyou
* @date 2019/3/21
*/
@Slf4j
public class AsyncSocket { private final ClientBootstrap clientBootstrap; private final InetSocketAddress address; private int timeout; private static final byte CONNECTORS_POOL_SIZE = 1; private static final byte WORKERS_POOL_SIZE = 30; public AsyncSocket(String hostIp, String port, int timeout, String name) {
final ThreadFactory threadFactory = new ThreadFactoryBuilder().setDaemon(true).setNameFormat(name + "-pool-%d").setPriority(Thread.NORM_PRIORITY).build();
final ExecutorService connectors = new ThreadPoolExecutor(CONNECTORS_POOL_SIZE, CONNECTORS_POOL_SIZE, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), threadFactory);
final ExecutorService workers = new ThreadPoolExecutor(WORKERS_POOL_SIZE, WORKERS_POOL_SIZE, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), threadFactory);
clientBootstrap = new ClientBootstrap(new NioClientSocketChannelFactory(connectors, workers, CONNECTORS_POOL_SIZE, WORKERS_POOL_SIZE));
address = new InetSocketAddress(hostIp, NumberUtils.toInt(port));
clientBootstrap.setOption("remoteAddress", address);
clientBootstrap.setOption("connectTimeoutMillis", timeout);
this.timeout = timeout;
addShutdownHook();
} @SneakyThrows
public byte[] send(final byte[] data) {
final SocketEventHandler socketEventHandler = new SocketEventHandler(timeout);
final Channel channel = clientBootstrap.getFactory().newChannel(Channels.pipeline(socketEventHandler));
final ChannelFuture future = channel.connect(address);
future.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
if (future.isSuccess()) {
channel.write(ChannelBuffers.wrappedBuffer(data));
} else {
log.error("I/O operation has failed.", future.getCause());
throw (Exception) future.getCause();
}
}
});
return socketEventHandler.getMessage();
} private void addShutdownHook() {
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
clientBootstrap.releaseExternalResources();
}
});
} private class SocketEventHandler extends SimpleChannelUpstreamHandler { private byte[] message; private int timeout; private final CountDownLatch latch = new CountDownLatch(1); SocketEventHandler(int timeout) {
this.timeout = timeout;
} @SneakyThrows
byte[] getMessage() {
latch.await(timeout, TimeUnit.MILLISECONDS);
return message;
} @Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
if (null != e.getMessage()) {
message = ((ChannelBuffer) e.getMessage()).array();
latch.countDown();
}
if (null != ctx.getChannel()) {
ctx.getChannel().close();
}
} @Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
if (null != ctx.getChannel()) {
ctx.getChannel().close();
}
log.error("An exception was raised by an I/O thread.", e.getCause());
} } }

Netty实现的一个异步Socket代码的更多相关文章

  1. Netty接收到一个请求但是代码段执行了两次

    这是因为HttpRequestDecoder把请求拆分成HttpRequest和HttpContent两部分, 所以在建立连接的时候建立了两次.

  2. 一个高性能异步socket封装库的实现思路 (c#)

    前言 socket是软件之间通讯最常用的一种方式.c#实现socket通讯有很多中方法,其中效率最高就是异步通讯. 异步通讯实际是利用windows完成端口(IOCP)来处理的,关于完成端口实现原理, ...

  3. ES transport client底层是netty实现,netty本质上是异步方式,但是netty自身可以使用sync或者await(future超时机制)来实现类似同步调用!因此,ES transport client可以同步调用也可以异步(不过底层的socket必然是异步实现)

    ES transport client底层是netty实现,netty本质上是异步方式,但是netty自身可以使用sync或者await(future超时机制)来实现类似同步调用! 因此,ES tra ...

  4. Netty(1):第一个netty程序

    为什么选择Netty netty是业界最流行的NIO框架之一,它的健壮型,功能,性能,可定制性和可扩展性都是首屈一指的,Hadoop的RPC框架Avro就使用了netty作为底层的通信框架,此外net ...

  5. 简单的异步Socket实现——SimpleSocket_V1.1

    简单的异步Socket实现——SimpleSocket_V1.1 笔者在前段时间的博客中分享了一段简单的异步.net的Socket实现.由于是笔者自己测试使用的.写的很粗糙.很简陋.于是花了点时间自己 ...

  6. Python简易聊天工具-基于异步Socket通信

    继续学习Python中,最近看书<Python基础教程>中的虚拟茶话会项目,觉得很有意思,自己敲了一遍,受益匪浅,同时记录一下. 主要用到异步socket服务客户端和服务器模块asynco ...

  7. 项目笔记---C#异步Socket示例

    概要 在C#领域或者说.net通信领域中有着众多的解决方案,WCF,HttpRequest,WebAPI,Remoting,socket等技术.这些技术都有着自己擅长的领域,或者被合并或者仍然应用于某 ...

  8. 深入理解Tornado——一个异步web服务器

    本人的第一次翻译,转载请注明出处:http://www.cnblogs.com/yiwenshengmei/archive/2011/06/08/understanding_tornado.html原 ...

  9. 可扩展多线程异步Socket服务器框架EMTASS 2.0 续

    转载自Csdn:http://blog.csdn.net/hulihui/article/details/3158613 (原创文章,转载请注明来源:http://blog.csdn.net/huli ...

随机推荐

  1. SpringBoot统一错误处理

    1.处理错误请求页面 import org.springframework.stereotype.Controller; import org.springframework.web.bind.ann ...

  2. webstorm 2017 激活破解方法大全

    webstorm 作为最近最火的前端开发工具,也确实对得起那个价格,但是秉着勤俭节约的传统美德,我们肯定是能省则省啊. 方法一:(更新时间:2018/4/8)v3.3 注册时,在打开的License ...

  3. 【python】进程与线程

    No1: 多进程 from multiprocessing import Process import os # 子进程要执行的代码 def run_proc(name): print('Run ch ...

  4. IO流巧记图

    本文特意将各种IO流的类总结到一起,作成图,方便记忆 1.流的写入和读取 2.字符输入流 3.字符输出流 4.字节输入流 5.字节输出流 6.概念杂记 * Buffered;带缓冲区的字符读取流,高效 ...

  5. Tree Reconstruction Gym - 101911G(构造)

    ---恢复内容开始--- Monocarp has drawn a tree (an undirected connected acyclic graph) and then has given ea ...

  6. jupyter notebook不能选择虚拟环境的解决方法

    今天使用dlib没有py37版本,因此创建了Version_36虚拟环境.但jupyter notebook默认的内核找不到新建的虚拟环境,解决方法是需要安装两个包: × ipykernel × nb ...

  7. Hystrix快速入门

    祝大家国庆快乐! 对大部分电商和快递公司来说,每年年底(Q4季度)由于双11等大促活动的存在,将面对大量的用户流量,尤其是属于大促的那几天,无论是用户的商品订单还是物流订单,都将是平时的3倍以上.对于 ...

  8. 持续集成时 travis 和 codecov 等 yaml 文件的配置

    最近在项目中在配置CodeCov 以及Travis 和 AppVeyor做持续集成时,遇到了一些问题,也解决了一些问题.顺便拿来分享一下. 首先时Travis,这个主要是来跑基于 Linux 环境下的 ...

  9. angular7一周学习

    ng new xxx 创建一个项目 ng serve --open 执行一个项目 angular 使用socket.io 报错 找到polyfills.ts添加 (window as any).glo ...

  10. the secrets

    prime time productions: my life had collepes arround me? i have worked myselft into exhaustion. my f ...