上一节说到用到这个来创建服务,其实到最后就是new NettyServer(url, listener)
Transporters.bind(url, new DecodeHandler(new HeaderExchangeHandler(handler))
protected void doOpen() throws Throwable {
NettyHelper.setNettyLoggerFactory();
//创建boss线程池
ExecutorService boss = Executors.newCachedThreadPool(
new NamedThreadFactory("NettyServerBoss", true));
//创建worker线程池
ExecutorService worker = Executors.newCachedThreadPool(new
NamedThreadFactory("NettyServerWorker", true));
ChannelFactory channelFactory = new NioServerSocketChannelFactory(boss,
worker, getUrl().getPositiveParameter("iothreads",
Runtime.getRuntime().availableProcessors() + 1));
bootstrap = new ServerBootstrap(channelFactory);
//处理handler
final NettyHandler nettyHandler = new NettyHandler(getUrl(), this);
//将所有的channel保存下来
channels = nettyHandler.getChannels();
bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
public ChannelPipeline getPipeline() {
NettyCodecAdapter adapter = new NettyCodecAdapter(getCodec()
,getUrl(), NettyServer.this);
ChannelPipeline pipeline = Channels.pipeline();
pipeline.addLast("decoder", adapter.getDecoder());
pipeline.addLast("encoder", adapter.getEncoder());
pipeline.addLast("handler", nettyHandler);
return pipeline;
}
});
// bind
channel = bootstrap.bind(getBindAddress());
}
//关闭服务
protected void doClose() throws Throwable {
if (channel != null)
channel.close();
//目前客户端连接的channel全部断开
Collection channels = getChannels();
if (channels != null && channels.size() > 0) {
for (com.alibaba.dubbo.remoting.Channel channel : channels) {
channel.close();
}
}
if (bootstrap != null)
bootstrap.releaseExternalResources();
if (channels != null)
channels.clear();
}
//创建
protected void doOpen() throws Throwable {
NettyHelper.setNettyLoggerFactory();
bootstrap = new ClientBootstrap(channelFactory);
bootstrap.setOption("keepAlive", true);
bootstrap.setOption("tcpNoDelay", true);
bootstrap.setOption("connectTimeoutMillis", getTimeout());
final NettyHandler nettyHandler = new NettyHandler(getUrl(), this);
bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
public ChannelPipeline getPipeline() {
NettyCodecAdapter adapter = new NettyCodecAdapter(getCodec(),
getUrl(), NettyClient.this);
ChannelPipeline pipeline = Channels.pipeline();
pipeline.addLast("decoder", adapter.getDecoder());
pipeline.addLast("encoder", adapter.getEncoder());
pipeline.addLast("handler", nettyHandler);
return pipeline;
}
});
}
//连接服务端
protected void doConnect() throws Throwable {
long start = System.currentTimeMillis();
ChannelFuture future = bootstrap.connect(getConnectAddress());
try{
boolean ret = future.awaitUninterruptibly(getConnectTimeout(),
TimeUnit.MILLISECONDS);
if (ret && future.isSuccess()) {
Channel newChannel = future.getChannel();
newChannel.setInterestOps(Channel.OP_READ_WRITE);
try {
// 关闭旧的连接
Channel oldChannel = NettyClient.this.channel;
if (oldChannel != null) {
try {
oldChannel.close();
} finally {
NettyChannel.removeChannelIfDisconnected(oldChannel);
}
}
} finally {
if (NettyClient.this.isClosed()) {
try {
newChannel.close();
} finally {
NettyClient.this.channel = null;
NettyChannel.removeChannelIfDisconnected(newChannel);
}
} else {
NettyClient.this.channel = newChannel;
}
}
}
}finally{
if (! isConnected()) {
future.cancel();
}
}
}
用来处理netty中的请求。(客户端连接、客户端关闭、接收消息、发送消息以及出现异常)
而在duubo中使用的handler是采用了装饰者模式
public class NettyHandler extends SimpleChannelHandler {
//在客户端连接服务端,或者断开连接。保存channel
private final Map channels =
new ConcurrentHashMap();
private final URL url;
private final ChannelHandler handler;
public NettyHandler(URL url, ChannelHandler handler){
this.url = url;
this.handler = handler;
}
public Map getChannels() {
return channels;
}
//客户端连接
public void channelConnected(ChannelHandlerContext ctx,
ChannelStateEvent e) throws Exception {
NettyChannel channel = NettyChannel.getOrAddChannel(ctx.getChannel(),
url, handler);
try {
if (channel != null) {
channels.put(NetUtils.toAddressString((InetSocketAddress)
ctx.getChannel().getRemoteAddress()), channel);
}
handler.connected(channel);
} finally {
NettyChannel.removeChannelIfDisconnected(ctx.getChannel());
}
}
//客户端断开
public void channelDisconnected(ChannelHandlerContext ctx,
ChannelStateEvent e)
throws Exception {
NettyChannel channel = NettyChannel.getOrAddChannel(ctx.getChannel(),
url, handler);
try {
channels.remove(NetUtils.toAddressString((InetSocketAddress)
ctx.getChannel().getRemoteAddress()));
handler.disconnected(channel);
} finally {
NettyChannel.removeChannelIfDisconnected(ctx.getChannel());
}
}
//接收客户端的请求,向客户端发送消息,异常处理都是交给handler处理
}
AbstractPeer
这里全部交给下一级的handler处理
MultiMessageHandler
在接收消息时,如果message是MultiMessage类型,那么就循环遍历
public void received(Channel channel, Object message) {
if (message instanceof MultiMessage) {
MultiMessage list = (MultiMessage)message;
for(Object obj : list) {
handler.received(channel, obj);
}
} else {
handler.received(channel, message);
}
}
//初始化读写时间
public void connected(Channel channel) {
hannel.setAttribute("READ_TIMESTAMP", System.currentTimeMillis());
channel.setAttribute("WRITE_TIMESTAMP", System.currentTimeMillis());
handler.connected(channel);
}
//清除读写时间
public void disconnected(Channel channel) {
channel.removeAttribute("READ_TIMESTAMP");
channel.removeAttribute("WRITE_TIMESTAMP");
handler.disconnected(channel);
}
//重设写时间
public void sent(Channel channel, Object message) {
channel.setAttribute("WRITE_TIMESTAMP", System.currentTimeMillis());
handler.sent(channel, message);
}
//重设读时间,如果是心跳请求,那么就发送消息
public void received(Channel channel, Object message) {
hannel.setAttribute("READ_TIMESTAMP", System.currentTimeMillis());
//如果消息是心跳请求,那么就发送消息
if (isHeartbeatRequest(message)) {
Request req = (Request) message;
if (req.isTwoWay()) {
Response res = new Response(req.getId(), req.getVersion());
res.setEvent(Response.HEARTBEAT_EVENT);
channel.send(res);
}
return;
}
//接收消息
handler.received(channel, message);
}
public void connected(Channel channel) {
ExecutorService cexecutor = getExecutorService();
cexecutor.execute(new ChannelEventRunnable(channel, handler ,
ChannelState.CONNECTED));
}
public void disconnected(Channel channel) throws RemotingException {
ExecutorService cexecutor = getExecutorService();
cexecutor.execute(new ChannelEventRunnable(channel, handler ,
ChannelState.DISCONNECTED));
}
public void received(Channel channel, Object message) {
ExecutorService cexecutor = getExecutorService();
cexecutor.execute(new ChannelEventRunnable(channel, handler,
ChannelState.RECEIVED, message));
}
public void caught(Channel channel, Throwable exception) {
ExecutorService cexecutor = getExecutorService();
cexecutor.execute(new ChannelEventRunnable(channel, handler ,
ChannelState.CAUGHT, exception));
}
//创建线程池
public Executor getExecutor(URL url) {
String name = url.getParameter(Constants.THREAD_NAME_KEY, "Dubbo");
int threads = url.getParameter(Constants.THREADS_KEY, 200);
int queues = url.getParameter(Constants.QUEUES_KEY, 0);
return new ThreadPoolExecutor(threads, threads, 0,
TimeUnit.MILLISECONDS,
queues == 0 ? new SynchronousQueue() :
(queues < 0 ? new LinkedBlockingQueue()
: new LinkedBlockingQueue(queues)),
new NamedThreadFactory(name, true), new
AbortPolicyWithReport(name, url));
}
public void received(Channel channel, Object message) {
if (message instanceof Decodeable)
decode(message);
if (message instanceof Request)
decode(((Request)message).getData());
if (message instanceof Response)
decode( ((Response)message).getResult());
handler.received(channel, message);
}
private void decode(Object message) {
if (message != null && message instanceof Decodeable)
((Decodeable)message).decode();
}
HeaderExchangeHandler
主要对头部做一些处理
ExchangeHandler
private ExchangeHandler requestHandler = new ExchangeHandlerAdapter() {
//连接
public void connected(Channel channel) throws RemotingException {
invoke(channel, "onconnect");
}
//关闭连接
public void disconnected(Channel channel) throws RemotingException {
invoke(channel, "ondisconnect");
}
//接收消息
public void received(Channel channel, Object message) t {
if (message instanceof Invocation) {
reply((ExchangeChannel) channel, message);
} else {
super.received(channel, message);
}
}
//执行
private void invoke(Channel channel, String methodKey) {
Invocation invocation = createInvocation(channel, channel.getUrl(),
methodKey);
if (invocation != null)
received(channel, invocation);
}
//专门处理Invocation的消息
public Object reply(ExchangeChannel channel, Object message) {
if (message instanceof Invocation) {
Invocation inv = (Invocation) message;
Invoker> invoker = getInvoker(channel, inv);
//如果是callback 需要检查当前的方法是否在url中的methods中...
RpcContext.getContext().setRemoteAddress(
channel.getRemoteAddress());
//直接调用
return invoker.invoke(inv);
}
throw new RemotingException(".....");
}
//创建Invocation
private Invocation createInvocation(Channel channel,
URL url, String methodKey) {
String method = url.getParameter(methodKey);
if (method == null || method.length() == 0) {
return null;
}
RpcInvocation invocation =
new RpcInvocation(method, new Class>[0], new Object[0]);
// ..
return invocation;
}
}
//从缓存中获取Invoker
Invoker> getInvoker(Channel channel, Invocation inv) {
boolean isCallBackServiceInvoke = false;
boolean isStubServiceInvoke = false;
int port = channel.getLocalAddress().getPort();
String path = inv.getAttachments().get(Constants.PATH_KEY);
//如果是客户端的回调服务.
isStubServiceInvoke = Boolean.TRUE.toString().equals(
inv.getAttachments().get(Constants.STUB_EVENT_KEY));
if (isStubServiceInvoke){
port = channel.getRemoteAddress().getPort();
}
//拼接key
String serviceKey = serviceKey(port, path,
inv.getAttachments().get(Constants.VERSION_KEY),
inv.getAttachments().get(Constants.GROUP_KEY));
//从缓存中获取Exporter,在export中创建并exporterMap
DubboExporter> exporter = (DubboExporter>)
exporterMap.get(serviceKey);
return exporter.getInvoker();
}
这里对客户端传过来的channel进行了封装
final class NettyChannel extends AbstractChannel {
private NettyChannel(org.jboss.netty.channel.Channel channel,
URL url, ChannelHandler handler){
super(url, handler);
this.channel = channel;
}
//对原有的channel进行封装
static NettyChannel getOrAddChannel(org.jboss.netty.channel.Channel ch,
URL url, ChannelHandler handler) {
//new NettyChannel然后放进map
return ret;
}
//发送消息
public void send(Object message, boolean sent)
throws RemotingException {
super.send(message, sent);
boolean success = true;
int timeout = 0;
ChannelFuture future = channel.write(message);
//是否等待
if (sent) {
timeout = getUrl().getPositiveParameter("timeout",1000);
success = future.await(timeout);
}
Throwable cause = future.getCause();
if (cause != null) {
throw cause;
}
if(! success) {
throw new RemotingException("");
}
}
//...
}