[Netty] 서버 시작
27644 단어 Netty
1. 서버 부팅 코드
public static void main(String[] args) throws Exception {
// .
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
// .
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childOption(ChannelOption.TCP_NODELAY, true)
.childAttr(AttributeKey.newInstance("childAttr"), "childAttrValue")
.handler(new ServerHandler())
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new AuthHandler());
//..
}
});
// .
ChannelFuture f = b.bind(8888).sync();
f.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
Bind 메서드에 들어가면 다음과 같은 이점을 얻을 수 있습니다.
private ChannelFuture doBind(final SocketAddress localAddress) {
// .
final ChannelFuture regFuture = this.initAndRegister();
// .
ChannelPromise promise = channel.newPromise();
doBind0(regFuture, channel, localAddress, promise);
}
2. 초기화 및 등록
final ChannelFuture initAndRegister() {```
...
// 1: channel.
channel = this.channelFactory.newChannel();
// 2: channel
this.init(channel);
// 3: .
ChannelFuture regFuture = this.config().group().register(channel);
}
(1) 채널 만들기
public NioServerSocketChannel() {
this(newSocket(DEFAULT_SELECTOR_PROVIDER));
}
private static java.nio.channels.ServerSocketChannel newSocket(SelectorProvider provider) {
try {
return provider.openServerSocketChannel();
} catch (IOException var2) {
throw new ChannelException("Failed to open a server socket.", var2);
}
}
public NioServerSocketChannel(java.nio.channels.ServerSocketChannel channel) {
// .
super((Channel)null, channel, 16);
this.config = new NioServerSocketChannel.NioServerSocketChannelConfig(this, this.javaChannel().socket());
}
채널 초기화
주로 채널 관련 속성을 설정하고 pipeline을 설정하며 ServerBootstrapAcceptor를 추가합니다
void init(Channel channel) throws Exception {
// options
channel.config().setOptions(options);
...
//
channel.config().setOptions(options);
...
//
currentChildOptions = (Entry[])this.childOptions.entrySet().toArray(newOptionArray(this.childOptions.size()));
...
//
currentChildAttrs = (Entry[])this.childAttrs.entrySet().toArray(newAttrArray(this.childAttrs.size()));
...
// ServerBootstrapAcceptor.
pipeline.addLast(new ChannelHandler[]{new ServerBootstrap.ServerBootstrapAcceptor(currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs)});
...
}
(3) 등록
3. 포트 바인딩
private static void doBind0(final ChannelFuture regFuture, final Channel channel, final SocketAddress localAddress, final ChannelPromise promise) {
channel.eventLoop().execute(new Runnable() {
public void run() {
if (regFuture.isSuccess()) {
//
channel.bind(localAddress, promise).addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
} else {
promise.setFailure(regFuture.cause());
}
}
});
}
//서버 channel 만들기//서버 channel 초기화//등록selector//포트 귀속
```java
ChannelFuture regFuture = this.config().group().register(channel);
//실제 등록, 중요this.register0(promise); …
}
실제 등록
private void register0(ChannelPromise promise) {
...
AbstractChannel.this.doRegister();
AbstractChannel.this.pipeline.invokeHandlerAddedIfNeeded();
AbstractChannel.this.pipeline.fireChannelRegistered();
...
}
protected void doRegister() throws Exception {
boolean selected = false;
while(true) {
try {
// jdk . 0 .this channel attachment, selector , select , this ,4、44s
this.selectionKey = this.javaChannel().register(this.eventLoop().selector, 0, this);
return;
} catch (CancelledKeyException var3) {
if (selected) {
throw var3;
}
this.eventLoop().selectNow();
selected = true;
}
}
}
포트 바인딩:
dobindjavachannel을 연결해서 채널을 건드리도록 전파합니다.read 이벤트, 서버에서 새로운 연결을 읽을 수 있습니다
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[ 네티 인 액션 ] 7. EventLoop와 스레딩 모델또한 애플리케이션의 동시성 요건이나 전반적인 복잡성 때문에 프로젝트의 수명주기 동안 다른 스레드 관련 문제가 발생할 수 있다. 1. io.netty.util.concurrent 패키지는 JDK 패키지인 java.ut...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.