在使用场景中会遇到 需要netty socket的域名解析到指定IP地址,怎么做到呢,在我们的netty 中,提供了DNS域名解析(DefaultNameResolver)。
一、自定义类MyDefaultNameResolver继承 DefaultNameResolver,实现doResolve方法,解析的相关逻辑在这里面处理
public class MyDefaultNameResolver extends DefaultNameResolver {
private Map<String, Map<String, String>> hostMap;
public MyDefaultNameResolver(EventExecutor executor, Map<String, Map<String, String>> hostMap) {
super(executor);
this.hostMap = hostMap;
}
@Override
protected void doResolve(String inetHost, Promise<InetAddress> promise) throws Exception {
try {
if (TextUtils.equals(inetHost,SystemManager.ctrlServerAddress().split(":")[0])){
if (!TextUtils.isEmpty(SystemManager.ctrlIpAddress())){
String [] ipAddress = SystemManager.ctrlIpAddress().split("\\.");
Inet4Address inet4Address = (Inet4Address) Inet4Address.getByAddress(inetHost, new byte[]{(byte) Integer.parseInt(ipAddress[0]), (byte) Integer.parseInt(ipAddress[1]), (byte)Integer.parseInt(ipAddress[2]), (byte) Integer.parseInt(ipAddress[3])});
promise.setSuccess(inet4Address);
return;
}
return;
}
if (!checkHostNameIsIp()) {
promise.setSuccess(SocketUtils.addressByName(inetHost));
return;
}
if (checkCtrlIsIp()) {
Map<String, String> ctrlMap = hostMap.get("ctrlMap");
setResolverIpAddress(ctrlMap,promise,inetHost);
return;
}
if (checkGatewayIsIp()){
Map<String, String> gatewayMap = hostMap.get("gatewayMap");
setResolverIpAddress(gatewayMap,promise,inetHost);
return;
}
promise.setSuccess(SocketUtils.addressByName(inetHost));
} catch (UnknownHostException e) {
promise.setFailure(e);
}
}
private void setResolverIpAddress(Map<String, String> dataMap,Promise<InetAddress> promise,String inetHost) throws UnknownHostException {
if (TextUtils.equals(dataMap.get("host"), inetHost)) {
String [] ipAddress = dataMap.get("ipAddress").split("\\.");
Inet4Address inet4Address = (Inet4Address) Inet4Address.getByAddress(inetHost, new byte[]{(byte) Integer.parseInt(ipAddress[0]), (byte) Integer.parseInt(ipAddress[1]), (byte)Integer.parseInt(ipAddress[2]), (byte) Integer.parseInt(ipAddress[3])});
promise.setSuccess(inet4Address);
return;
}
promise.setSuccess(SocketUtils.addressByName(inetHost));
}
private boolean checkHostNameIsIp() {
if (hostMap == null) {
return false;
}
if (hostMap.size() == 0) {
return false;
}
return true;
}
private boolean checkCtrlIsIp() {
try {
if (!hostMap.containsKey("ctrlMap")) {
return false;
}
Map<String, String> ctrlMap = hostMap.get("ctrlMap");
if (ctrlMap.containsKey("host") && ctrlMap.containsKey("ipAddress") && ctrlMap.get("ipAddress").contains(".")) {
return true;
}
return false;
}catch (Exception e){
return false;
}
}
private boolean checkGatewayIsIp() {
try {
if (!hostMap.containsKey("ctrlMap")) {
return false;
}
Map<String, String> ctrlMap = hostMap.get("ctrlMap");
if (ctrlMap.containsKey("host") && ctrlMap.containsKey("ipAddress") && ctrlMap.get("ipAddress").contains(".")) {
return true;
}
return false;
}catch (Exception e){
return false;
}
}
@Override
protected void doResolveAll(String inetHost, Promise<List<InetAddress>> promise) throws Exception {
try {
promise.setSuccess(Arrays.asList(SocketUtils.allAddressesByName(inetHost)));
} catch (UnknownHostException e) {
promise.setFailure(e);
}
}
}
二、需要解析组来进行管理MyDefaultNameResolver,新增解析组 MyAddressResolverGroup 继承AddressResolverGroup<InetSocketAddress> 在newResolver 方法绑MyDefaultNameResolver
public class MyAddressResolverGroup extends AddressResolverGroup<InetSocketAddress> {
private static MyAddressResolverGroup INSTANCE;
private Map<String, Map<String,String>> hostMap;
public static MyAddressResolverGroup getInstance(Map<String, Map<String,String>> hostMap) {
if (INSTANCE==null){
INSTANCE = new MyAddressResolverGroup(hostMap);
}
return INSTANCE;
}
private MyAddressResolverGroup(Map<String, Map<String,String>> hostMap) {
this.hostMap = hostMap;
}
protected AddressResolver<InetSocketAddress> newResolver(EventExecutor executor) throws Exception {
return (new MyDefaultNameResolver(executor,this.hostMap)).asAddressResolver();
}
}
三、在创建netty 中绑定这个域名解析器 即MyAddressResolverGroup
bootstrap.group(eventLoopGroup).channel(NioSocketChannel.class)
.resolver(MyAddressResolverGroup.getInstance(hostMap))
.option(ChannelOption.TCP_NODELAY, true)
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 3000)
.option(ChannelOption.ALLOCATOR, ByteBufAllocator.DEFAULT)
.option(ChannelOption.RCVBUF_ALLOCATOR, new AdaptiveRecvByteBufAllocator(5000, 5000, 80000))
.option(ChannelOption.SO_KEEPALIVE, true)
.handler(new SdpNettyHandler(sslContext, readQueue, writeQueue));