1.
1.Netty OpenSSL:
/*
* Copyright 2014 The Netty Project
*
* The Netty Project licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package io.netty.handler.ssl;
import io.netty.util.internal.NativeLibraryLoader;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
import org.apache.tomcat.jni.Library;
import org.apache.tomcat.jni.SSL;
/**
* Tells if <a href="http://netty.io/wiki/forked-tomcat-native.html">{@code netty-tcnative}</a> and its OpenSSL support
* are available.
*/
public final class OpenSsl {
private static final InternalLogger logger = InternalLoggerFactory.getInstance(OpenSsl.class);
private static final Throwable UNAVAILABILITY_CAUSE;
static final String IGNORABLE_ERROR_PREFIX = "error:00000000:";
static {
Throwable cause = null;
try {
NativeLibraryLoader.load("netty-tcnative", SSL.class.getClassLoader());
Library.initialize("provided");
SSL.initialize(null);
} catch (Throwable t) {
cause = t;
logger.debug(
"Failed to load netty-tcnative; " +
OpenSslEngine.class.getSimpleName() + " will be unavailable.", t);
}
UNAVAILABILITY_CAUSE = cause;
}
/**
* Returns {@code true} if and only if
* <a href="http://netty.io/wiki/forked-tomcat-native.html">{@code netty-tcnative}</a> and its OpenSSL support
* are available.
*/
public static boolean isAvailable() {
return UNAVAILABILITY_CAUSE == null;
}
/**
* Ensure that <a href="http://netty.io/wiki/forked-tomcat-native.html">{@code netty-tcnative}</a> and
* its OpenSSL support are available.
*
* @throws UnsatisfiedLinkError if unavailable
*/
public static void ensureAvailability() {
if (UNAVAILABILITY_CAUSE != null) {
throw (Error) new UnsatisfiedLinkError(
"failed to load the required native library").initCause(UNAVAILABILITY_CAUSE);
}
}
/**
* Returns the cause of unavailability of
* <a href="http://netty.io/wiki/forked-tomcat-native.html">{@code netty-tcnative}</a> and its OpenSSL support.
*
* @return the cause if unavailable. {@code null} if available.
*/
public static Throwable unavailabilityCause() {
return UNAVAILABILITY_CAUSE;
}
private OpenSsl() { }
}
java.lang.System.mapLibraryName() 方法映射库名称为表示本机库的平台特定的字符串。
作用:
它们都可以用来装载库文件,不论是JNI库文件还是非JNI库文件。在任何本地方法被调用之前必须先用这个两个方法之一把相应的JNI库文件装载。
其实JDK提供给用户了两个方法用于载入文件,一个是System.load(String filename)方法,另外一个是System.loadLibrary(String libname)方法。
2,应用
Channel 读写
ChannelHandler 处理数据 --> ChannelInboundHandler ChannelOutboundHandler->ChannelHandlerAdapter ChannelInboundHandlerAdapter ChannelOutboundHandlerAdapter ->ChannelInitializer ByteToMessageDecoder MessageToByteEncoder
Pipeline 管线,管理ChannelHander
Bootstrap ServerBootstrap 启动类
EventLoopGroup-> NioEventLoopGroup 处理线程组
ChannelFuture 返回结果 ChannelFutureListener 监听
3.Bootstrap ServerBootstrap 门面设计模式
4.EventLoopGroup EventLoop线程池 EventLoop 用于处理注册到本线程多路复用器Selector上的Channel ,包括用户自定义的task
final EventLoopGroup bossEventLoopGroup = new NioEventLoopGroup();
bootStrip.group(bossEventLoopGroup).channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
// 责任链
ch.pipeline().addLast(new RpcEncoder(RpcRequest.class));
ch.pipeline().addLast(new RpcDecoder(RpcResponse.class));
ch.pipeline().addLast(new ClientHandler());
}
});
ChannelFuture channleFuture = bootStrip.connect(host, port).sync();
// channleFuture.addListener(new ChannelFutureListener() {
//
// @Override
// public void operationComplete(ChannelFuture future) throws Exception
// {
//
// if (future.isSuccess()) {
// System.out.println("connect server succefully");
// } else {
// System.out.println("connect server failed");
// bossEventLoopGroup.shutdownGracefully();
//
// }
// }
// });
ChannelFutureListener channelFutureListener = (future) -> {
if (future.isSuccess()) {
System.out.println("connect server succefully");
} else {
System.out.println("connect server failed");
bossEventLoopGroup.shutdownGracefully();
}
};
channleFuture.addListener(channelFutureListener);
channel = channleFuture.channel();
NioEventLoopGroup继承于MultithreadEventLoopGroup,MultithreadEventLoopGroup是公共父类,子类包括:
用于管理EventLoopGroup
EventLoop:
/**
* The {@link EventExecutorGroup} is responsible to provide {@link EventExecutor}'s to use via its
* {@link #next()} method. Beside this it also is responsible to handle their live-cycle and allows
* to shut them down in a global fashion.
*
*/
public interface EventExecutorGroup extends ScheduledExecutorService, Iterable<EventExecutor> {
Future也是继承了java 的Future
EventExecutorGroup 继承于ScheduledExecutorService,实现了可以调度的线程池模型。
在Netty中,netty对线程模型进行了重新封装,它们分别是EventExecutorGroup和EventExecutor.每个EventExecutor是一个单独的线程,可以执行Runnable任务。EventExecutorGroup相当于一个线程组,用于管理和分配一组EventExecutor.我们知道Netty是基于事件驱动的。这样的封装给我们的开发带来了非常好的顺序。而且它还封装了定时任务,更加方便我们在一个线程中执行一些定时任务。
EventExecutorGroup的next()方法可以方便的获取在同一个组里面的EventExecutor