基于Netty的长连接客户端
来源:互联网 发布:什么叫seo营销 编辑:程序博客网 时间:2024/05/21 14:52
客户端工厂
import java.util.List;/** * 接口描述:长连接客户端工厂类 * * @author ruipeng.lrp * @since 2017/11/26 * **/public interface ClientFactory { // ------------ 查询和新增 ------------ Client get(final RemotingUrl url) throws Exception; // ------------ 查询 ------------ List<Client> getAllClients() throws Exception; // ------------ 删除 ------------ void remove(final RemotingUrl url) throws Exception;}
import java.util.ArrayList;import java.util.List;import java.util.concurrent.Callable;import java.util.concurrent.TimeUnit;import com.google.common.cache.Cache;import com.google.common.cache.CacheBuilder;import com.google.common.cache.RemovalListener;import com.google.common.cache.RemovalNotification;public abstract class AbstractClientFactory implements ClientFactory { // 长连接缓存,一个域名对应一个长连接 private final Cache<RemotingUrl, Client> cacherClients = CacheBuilder.newBuilder()// .maximumSize(65535) // 单机长连接上限,超过上限采用LRU淘汰 .expireAfterAccess(27, TimeUnit.MINUTES)// 连接长时间没有读写则删除 .removalListener(new RemovalListener<RemotingUrl, Client>() { @Override public void onRemoval(RemovalNotification<RemotingUrl, Client> notification) { // 关闭连接 } })// .build(); protected abstract Client createClient(RemotingUrl domain) throws Exception; @Override public Client get(RemotingUrl url) throws Exception { Client client = cacherClients.get(url, new Callable<Client>() { @Override public Client call() throws Exception { Client client = createClient(url); if (null != client) { client.startHeartBeat(); } return client; } }); return client; } @Override public List<Client> getAllClients() throws Exception { List<Client> result = new ArrayList<Client>((int) cacherClients.size()); result.addAll(cacherClients.asMap().values()); return result; } @Override public void remove(RemotingUrl url) throws Exception { cacherClients.invalidate(url); }}
import java.net.InetSocketAddress;import io.netty.bootstrap.Bootstrap;import io.netty.buffer.ByteBufAllocator;import io.netty.buffer.PooledByteBufAllocator;import io.netty.buffer.UnpooledByteBufAllocator;import io.netty.channel.Channel;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelInitializer;import io.netty.channel.ChannelOption;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.nio.NioSocketChannel;import io.netty.util.internal.SystemPropertyUtil;public class NettyClientFactory extends AbstractClientFactory { /** * 共享IO线程 **/ public static final NioEventLoopGroup workerGroup = new NioEventLoopGroup(); public static final ByteBufAllocator byteBufAllocator; static { workerGroup.setIoRatio(SystemPropertyUtil.getInt("ioratio", 100)); if (SystemPropertyUtil.getBoolean("bytebuf.pool", false)) { byteBufAllocator = PooledByteBufAllocator.DEFAULT; } else { byteBufAllocator = UnpooledByteBufAllocator.DEFAULT; } } @Override protected Client createClient(RemotingUrl url) throws Exception { final Bootstrap bootstrap = new Bootstrap(); bootstrap.group(NettyClientFactory.workerGroup)// .option(ChannelOption.TCP_NODELAY, true)// .option(ChannelOption.SO_REUSEADDR, true)// .option(ChannelOption.SO_KEEPALIVE, false)// .option(ChannelOption.ALLOCATOR, NettyClientFactory.byteBufAllocator)// .channel(NioSocketChannel.class)// .handler(new ChannelInitializer<NioSocketChannel>(){ @Override protected void initChannel(NioSocketChannel ch) throws Exception { ch.pipeline().addLast("decoder", null)// .addLast("encoder", null)// .addLast("handler", null); } }); int connectTimeout = url.getConnectionTimeout(); if (connectTimeout < 1000) { bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 3000); } else { bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, connectTimeout); } String targetIP = url.getDomain(); int targetPort = url.getPort(); ChannelFuture future = bootstrap.connect(new InetSocketAddress(targetIP, targetPort)); if (future.awaitUninterruptibly(connectTimeout) && future.isSuccess() && future.channel().isActive()) { Channel channel = future.channel(); Client client = new NettyClient(url, channel); return client; } else { future.cancel(true); future.channel().close(); throw new Exception(targetIP); } }}
客户端
public interface Client { //启动心跳检测 public void startHeartBeat() throws Exception; //发送请求 public void sendRequest(Object msg) throws Exception; public String getDomain(); public boolean isConnected();}
import java.util.concurrent.TimeUnit;import io.netty.channel.Channel;import io.netty.util.HashedWheelTimer;import io.netty.util.Timeout;import io.netty.util.Timer;import io.netty.util.TimerTask;public class NettyClient implements Client { /** * 共享定时器 **/ public static final Timer timer = new HashedWheelTimer(); public static final int DEFAULT_HEARTBEAT_PERIOD = 3000; private Channel ch; private RemotingUrl url; public NettyClient(RemotingUrl url, Channel ch) { this.ch = ch; this.url = url; } @Override public void startHeartBeat() throws Exception { timer.newTimeout(new TimerTask() { @Override public void run(Timeout timeout) throws Exception { try { // 发送心跳请求 } catch (Throwable t) { } finally { timer.newTimeout(this, DEFAULT_HEARTBEAT_PERIOD, TimeUnit.SECONDS); } } }, DEFAULT_HEARTBEAT_PERIOD, TimeUnit.SECONDS); } @Override public String getDomain() { return url.getDomain(); } @Override public boolean isConnected() { return ch.isActive(); } @Override public void sendRequest(Object msg) throws Exception { ch.writeAndFlush(msg); }}
URL信息
public class RemotingUrl { /** * 域名 **/ private String domain; /** * 端口 **/ private int port; /** * 超时时间,默认3s **/ private int connectionTimeout = 3000; public String getDomain() { return domain; } public void setDomain(String domain) { this.domain = domain; } public int getPort() { return port; } public void setPort(int port) { this.port = port; } public int getConnectionTimeout() { return connectionTimeout; } public void setConnectionTimeout(int connectionTimeout) { this.connectionTimeout = connectionTimeout; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((domain == null) ? 0 : domain.hashCode()); return result; } @Override public boolean equals(Object obj) { return this.domain.equalsIgnoreCase((String) obj); }}
阅读全文
0 0
- 基于Netty的长连接客户端
- netty开发基于长连接的http客户端
- 基于Netty的服务端长连接
- 基于Apache mina 的android 客户端tcp长连接实现
- 通过netty实现服务端与客户端的长连接通讯,及心跳检测。
- Netty实现服务端客户端长连接通讯及心跳检测
- Netty实现服务端客户端长连接通讯及心跳检测
- Netty实现服务端客户端长连接通讯及心跳检测
- Netty 长连接服务
- Netty 长连接服务
- netty长连接实例
- Netty 长连接服务
- Netty 长连接服务
- Netty 长连接服务
- 支持并发的http客户端(基于tcp连接池以及netty)
- 基于Netty的Redis客户端-Nedis
- 基于netty 的android Socket 聊天室客户端
- 基于Ajax的长连接
- html表单 select多选下拉箭头的问题
- linux结构化命令:if-then
- 【Aizu-ALDS1_7_B】Binary Trees 树 (4/1000)
- Java8简明指南
- C++ 中vector的使用方法
- 基于Netty的长连接客户端
- wireshark混杂模式
- content字符编码
- mongodb的介绍、原理以及使用场景
- abstract class与interface的区别
- FAE 通过 python 抓log
- Android Transition——提高一点点篇
- 贪心算法--雷达安装(poj 1328)
- Session 'app': Error Installing APKs