Java tutorial
/* * Copyright (c) 2015 The Jupiter Project * * Licensed 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 org.jupiter.transport.netty.channel; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFutureListener; import io.netty.util.Attribute; import io.netty.util.AttributeKey; import org.jupiter.transport.channel.JChannel; import org.jupiter.transport.channel.JFutureListener; import org.jupiter.transport.netty.handler.connector.ConnectionWatchdog; import java.net.SocketAddress; /** * Netty {@link Channel} , ?? {@link #attachChannel(Channel)} ?, * {@link NettyChannel} ?attach {@link Channel} , ???. * * jupiter * org.jupiter.transport.netty.channel * * @author jiachun.fjc */ public class NettyChannel implements JChannel { private static final AttributeKey<NettyChannel> NETTY_CHANNEL_KEY = AttributeKey.valueOf("netty.channel"); /** * Returns the {@link NettyChannel} for given {@link Channel}, this method never return null. */ public static NettyChannel attachChannel(Channel channel) { Attribute<NettyChannel> attr = channel.attr(NETTY_CHANNEL_KEY); NettyChannel nChannel = attr.get(); if (nChannel == null) { NettyChannel newNChannel = new NettyChannel(channel); nChannel = attr.setIfAbsent(newNChannel); if (nChannel == null) { nChannel = newNChannel; } } return nChannel; } private final Channel channel; private NettyChannel(Channel channel) { this.channel = channel; } public Channel channel() { return channel; } @Override public String id() { return channel.id().asShortText(); // ?id?, ? } @Override public boolean isActive() { return channel.isActive(); } @Override public boolean inIoThread() { return channel.eventLoop().inEventLoop(); } @Override public SocketAddress localAddress() { return channel.localAddress(); } @Override public SocketAddress remoteAddress() { return channel.remoteAddress(); } @Override public boolean isWritable() { return channel.isWritable(); } @Override public boolean isMarkedReconnect() { ConnectionWatchdog watchdog = channel.pipeline().get(ConnectionWatchdog.class); return watchdog != null && watchdog.isStarted(); } @Override public boolean isAutoRead() { return channel.config().isAutoRead(); } @Override public void setAutoRead(boolean autoRead) { channel.config().setAutoRead(autoRead); } @Override public JChannel close() { channel.close(); return this; } @Override public JChannel close(final JFutureListener<JChannel> listener) { final JChannel jChannel = this; channel.close().addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { if (future.isSuccess()) { listener.operationSuccess(jChannel); } else { listener.operationFailure(jChannel, future.cause()); } } }); return jChannel; } @Override public JChannel write(Object msg) { channel.writeAndFlush(msg, channel.voidPromise()); return this; } @Override public JChannel write(Object msg, final JFutureListener<JChannel> listener) { final JChannel jChannel = this; channel.writeAndFlush(msg).addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { if (future.isSuccess()) { listener.operationSuccess(jChannel); } else { listener.operationFailure(jChannel, future.cause()); } } }); return jChannel; } @Override public boolean equals(Object obj) { return this == obj || (obj instanceof NettyChannel && channel.equals(((NettyChannel) obj).channel)); } @Override public int hashCode() { return channel.hashCode(); } @Override public String toString() { return channel.toString(); } }