Netty实现的一个异步Socket代码
本人写的一个使用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代码的更多相关文章
- Netty接收到一个请求但是代码段执行了两次
这是因为HttpRequestDecoder把请求拆分成HttpRequest和HttpContent两部分, 所以在建立连接的时候建立了两次.
- 一个高性能异步socket封装库的实现思路 (c#)
前言 socket是软件之间通讯最常用的一种方式.c#实现socket通讯有很多中方法,其中效率最高就是异步通讯. 异步通讯实际是利用windows完成端口(IOCP)来处理的,关于完成端口实现原理, ...
- ES transport client底层是netty实现,netty本质上是异步方式,但是netty自身可以使用sync或者await(future超时机制)来实现类似同步调用!因此,ES transport client可以同步调用也可以异步(不过底层的socket必然是异步实现)
ES transport client底层是netty实现,netty本质上是异步方式,但是netty自身可以使用sync或者await(future超时机制)来实现类似同步调用! 因此,ES tra ...
- Netty(1):第一个netty程序
为什么选择Netty netty是业界最流行的NIO框架之一,它的健壮型,功能,性能,可定制性和可扩展性都是首屈一指的,Hadoop的RPC框架Avro就使用了netty作为底层的通信框架,此外net ...
- 简单的异步Socket实现——SimpleSocket_V1.1
简单的异步Socket实现——SimpleSocket_V1.1 笔者在前段时间的博客中分享了一段简单的异步.net的Socket实现.由于是笔者自己测试使用的.写的很粗糙.很简陋.于是花了点时间自己 ...
- Python简易聊天工具-基于异步Socket通信
继续学习Python中,最近看书<Python基础教程>中的虚拟茶话会项目,觉得很有意思,自己敲了一遍,受益匪浅,同时记录一下. 主要用到异步socket服务客户端和服务器模块asynco ...
- 项目笔记---C#异步Socket示例
概要 在C#领域或者说.net通信领域中有着众多的解决方案,WCF,HttpRequest,WebAPI,Remoting,socket等技术.这些技术都有着自己擅长的领域,或者被合并或者仍然应用于某 ...
- 深入理解Tornado——一个异步web服务器
本人的第一次翻译,转载请注明出处:http://www.cnblogs.com/yiwenshengmei/archive/2011/06/08/understanding_tornado.html原 ...
- 可扩展多线程异步Socket服务器框架EMTASS 2.0 续
转载自Csdn:http://blog.csdn.net/hulihui/article/details/3158613 (原创文章,转载请注明来源:http://blog.csdn.net/huli ...
随机推荐
- Python class NameError name "xxx" is not defined
Python class NameError name "xxx" is not defined 这是因为在 class 中调用了带双下划线 "__" 的函数对 ...
- 练习八 spool导出
sqlplus -s username/password@sid set trimspool on; set linesize 120; set pagesize 2000; set newpage ...
- Maven设置utf8编码格式
在pom.xml添加如下配置即可 <properties> <project.build.sourceEncoding>UTF-8</project.build.sour ...
- [python]Flask-migrate简单入门
Flask-Migrate是用于处理SQLAlchemy 数据库迁移的扩展工具.当Model出现变更的时候,通过migrate去管理数据库变更. Migrate主要有3个动作,init.migrate ...
- [ZJOI2012]波浪
Description: L = | P2 – P1 | + | P3 – P2 | + - + | PN – PN-1 | 给你一个N和M,问:随机一个1-N的排列,它的波动强度(L)不小于M的概率 ...
- [P2058][NOIP2015]海港 (模拟)
%%%ADMAN #include<cstdio> using namespace std; int n,tot,now,ans,h; ],k[],a[],sum[]; int main( ...
- 安装 VS2017 的正确姿势
自从装了长城带宽,我的肠子就变成青色的了. 国内的网络环境,真的是有很大的不同,有的人装 VS 的时候,号称满速,有的人(其实就是我)要等它下载很久,还告诉我有个组件没有安装成功.很久很久以前,VS ...
- 【搜索】传感器 @upcexam6023
时间限制: 1 Sec 内存限制: 128 MB 题目描述 SR最近新买了一款电子桌游 这个玩具内部是M个围成一圈的传感器.每个传感器都有开和关两种工作状态,分别用1和0表示.显然,从不同的位置触发沿 ...
- Listener(1)—基础知识
一.监听器 1.概念: 专门用于对其他对象身上发生的事件或状态改变进行监听和相应处理的对象,当被监听的对象状态发生情况时,立即采取相应的 行动.Servlet规范为每种事件监听器都定义了相应的接口,w ...
- flask之信号和mateclass元类
本篇导航: flask实例化参数 信号 metaclass元类解析 一.flask实例化参数 instance_path和instance_relative_config是配合来用的:这两个参数是用来 ...