Java tutorial
/* * Copyright 2015 the original author or authors. * * 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 com.qc.you.socket.server; import com.qc.you.socket.server.netty.handler.BroadCastChannelHandler; import com.qc.you.socket.server.netty.ChannelRepository; import com.qc.you.socket.server.netty.TCPServer; import com.qc.you.socket.server.netty.handler.SomethingServerHandler; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; import io.netty.channel.ChannelPipeline; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.codec.DelimiterBasedFrameDecoder; import io.netty.handler.codec.Delimiters; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import org.springframework.context.annotation.PropertySource; import java.net.InetSocketAddress; import java.nio.charset.Charset; import java.util.HashMap; import java.util.Map; import java.util.Set; /** * Created by youxiaojia on 2017/10/31. */ @SpringBootApplication @PropertySource(value = "classpath:/properties/local/nettyserver.properties") public class Application { @Value("${tcp.port}") private int tcpPort; @Value("${boss.thread.count}") private int bossCount; @Value("${worker.thread.count}") private int workerCount; @Value("${so.keepalive}") private boolean keepAlive; @Value("${so.backlog}") private int backlog; @Autowired @Qualifier("somethingServerHandler") private SomethingServerHandler somethingServerHandler; @Autowired @Qualifier("broadCastChannelHandler") private BroadCastChannelHandler broadCastChannelHandler; public static void main(String[] args) throws Exception { ConfigurableApplicationContext context = SpringApplication.run(Application.class, args); TCPServer tcpServer = context.getBean(TCPServer.class); tcpServer.start(); } private static final StringDecoder DECODER = new StringDecoder(Charset.forName("GBK")); private static final StringEncoder ENCODER = new StringEncoder(Charset.forName("GBK")); @SuppressWarnings("unchecked") @Bean(name = "serverBootstrap") public ServerBootstrap bootstrap() { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup(), workerGroup()).channel(NioServerSocketChannel.class) .handler(new LoggingHandler(LogLevel.DEBUG)).childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); // Add the text line codec combination first, pipeline.addLast(new DelimiterBasedFrameDecoder(1024 * 1024, Delimiters.lineDelimiter())); // the encoder and decoder are static as these are sharable pipeline.addLast(DECODER); pipeline.addLast(ENCODER); pipeline.addLast(somethingServerHandler); pipeline.addLast(broadCastChannelHandler); } }); Map<ChannelOption<?>, Object> tcpChannelOptions = tcpChannelOptions(); Set<ChannelOption<?>> keySet = tcpChannelOptions.keySet(); for (@SuppressWarnings("rawtypes") ChannelOption option : keySet) { b.option(option, tcpChannelOptions.get(option)); } return b; } @Configuration @Profile("production") @PropertySource("classpath:/properties/production/nettyserver.properties") static class Production { } @Configuration @Profile("local") @PropertySource({ "classpath:/properties/local/nettyserver.properties" }) static class Local { } @Bean(name = "tcpChannelOptions") public Map<ChannelOption<?>, Object> tcpChannelOptions() { Map<ChannelOption<?>, Object> options = new HashMap<ChannelOption<?>, Object>(); options.put(ChannelOption.SO_KEEPALIVE, keepAlive); options.put(ChannelOption.SO_BACKLOG, backlog); return options; } @Bean(name = "bossGroup", destroyMethod = "shutdownGracefully") public NioEventLoopGroup bossGroup() { return new NioEventLoopGroup(bossCount); } @Bean(name = "workerGroup", destroyMethod = "shutdownGracefully") public NioEventLoopGroup workerGroup() { return new NioEventLoopGroup(workerCount); } @Bean(name = "tcpSocketAddress") public InetSocketAddress tcpPort() { return new InetSocketAddress(tcpPort); } @Bean(name = "channelRepository") public ChannelRepository channelRepository() { return new ChannelRepository(); } }