Java tutorial
/* * Copyright (C) 2015 An Honest Effort LLC, coping. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.anhonesteffort.chnlbrkr; import com.lambdaworks.redis.RedisClient; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.timeout.IdleStateHandler; import org.anhonesteffort.chnlbrkr.chnlzr.IdleChnlzrConnectionFactory; import org.anhonesteffort.chnlbrkr.stream.ChannelStreamerFactory; import org.anhonesteffort.chnlzr.CapnpUtil; import org.anhonesteffort.chnlbrkr.chnlzr.IdleChnlzrController; import org.anhonesteffort.chnlzr.pipeline.BaseMessageDecoder; import org.anhonesteffort.chnlzr.pipeline.BaseMessageEncoder; import org.anhonesteffort.chnlzr.pipeline.IdleStateHeartbeatWriter; import java.util.Optional; import java.util.concurrent.TimeUnit; import static org.anhonesteffort.chnlzr.Proto.HostId; public class ChnlBrkrServer { private final ChnlBrkrConfig config; private final int listenPort; private final HostId.Reader hostId; private final Optional<String> redisUri; public ChnlBrkrServer(ChnlBrkrConfig config, String hostname, int listenPort, Optional<String> redisUri) { this.config = config; this.listenPort = listenPort; this.redisUri = redisUri; hostId = CapnpUtil.hostId(hostname, listenPort); } public void run() throws InterruptedException { EventLoopGroup workerGroup = new NioEventLoopGroup(); EventLoopGroup bossGroup = new NioEventLoopGroup(); ServerBootstrap bootstrap = new ServerBootstrap(); IdleChnlzrConnectionFactory idleFactory = new IdleChnlzrConnectionFactory(config); IdleChnlzrController idleController = new IdleChnlzrController(idleFactory); ChannelStreamerFactory streamFactory = new ChannelStreamerFactory(config); Optional<RedisClient> redisClient = (redisUri.isPresent()) ? Optional.of(RedisClient.create(redisUri.get())) : Optional.<RedisClient>empty(); BrkrList brkrList = new BrkrList(config, hostId, workerGroup, redisClient); Optional<ChnlzrIdPubSub> chnlzrPubSub = (redisClient.isPresent()) ? Optional.of(new ChnlzrIdPubSub(config, redisClient.get(), idleController)) : Optional.empty(); try { bootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class) .option(ChannelOption.SO_BACKLOG, 128).childOption(ChannelOption.SO_KEEPALIVE, true) .childOption(ChannelOption.WRITE_BUFFER_HIGH_WATER_MARK, config.bufferHighWaterMark()) .childOption(ChannelOption.WRITE_BUFFER_LOW_WATER_MARK, config.bufferLowWaterMark()) .childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) { ch.pipeline().addLast("idle state", new IdleStateHandler(0, 0, config.idleStateThresholdMs(), TimeUnit.MILLISECONDS)); ch.pipeline().addLast("heartbeat", IdleStateHeartbeatWriter.INSTANCE); ch.pipeline().addLast("encoder", BaseMessageEncoder.INSTANCE); ch.pipeline().addLast("decoder", new BaseMessageDecoder()); ch.pipeline().addLast("brkrlist", brkrList); ch.pipeline().addLast("handler", new ServerHandler(config, idleController, streamFactory, chnlzrPubSub)); } }); ChannelFuture channelFuture = bootstrap.bind(listenPort).sync(); channelFuture.channel().closeFuture().sync(); } finally { workerGroup.shutdownGracefully(); bossGroup.shutdownGracefully(); if (redisClient.isPresent()) { redisClient.get().shutdown(); } } } public static void main(String[] args) throws Exception { new ChnlBrkrServer(new ChnlBrkrConfig(), (args.length > 0) ? args[0] : "localhost", (args.length > 1) ? Integer.parseInt(args[1]) : 9090, (args.length > 2) ? Optional.of(args[2]) : Optional.<String>empty()).run(); } }