/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library 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 Lesser General Public License for more * details. */ package com.liferay.sync.engine.lan.server.file; import com.liferay.sync.engine.lan.server.LanEngine; import com.liferay.sync.engine.model.ModelListener; import com.liferay.sync.engine.model.SyncAccount; import com.liferay.sync.engine.model.SyncFile; import com.liferay.sync.engine.service.SyncFileService; import com.liferay.sync.engine.util.PropsValues; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; import java.net.BindException; import java.net.InetSocketAddress; import java.util.Map; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; /** * @author Dennis Ju */ public class LanFileServer { public int getPort() { return _port; } public ModelListener<SyncAccount> getSyncAccountListener() { if (syncAccountListener != null) { return syncAccountListener; } syncAccountListener = new ModelListener<SyncAccount>() { @Override public void onCreate(SyncAccount syncAccount) { updateDomainNameMapping(syncAccount); } @Override public void onRemove(SyncAccount syncAccount) { updateDomainNameMapping(syncAccount); } @Override public void onUpdate( SyncAccount syncAccount, Map<String, Object> originalValues) { if (originalValues.containsKey("active") || originalValues.containsKey("lanCertificate") || originalValues.containsKey("lanKey")) { updateDomainNameMapping(syncAccount); } } protected void updateDomainNameMapping(SyncAccount syncAccount) { if ((_lanFileServerInitializer != null) && syncAccount.isLanEnabled()) { _lanFileServerInitializer.updateDomainNameMapping(); } } }; return syncAccountListener; } public void start() throws Exception { _childEventLoopGroup = new NioEventLoopGroup(); _parentEventLoopGroup = new NioEventLoopGroup(1); ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(_parentEventLoopGroup, _childEventLoopGroup); serverBootstrap.channel(NioServerSocketChannel.class); _syncTrafficShapingHandler = new SyncTrafficShapingHandler( _childEventLoopGroup); _lanFileServerInitializer = new LanFileServerInitializer( _syncTrafficShapingHandler); serverBootstrap.childHandler(_lanFileServerInitializer); serverBootstrap.childOption(ChannelOption.SO_KEEPALIVE, true); ChannelFuture channelFuture = serverBootstrap.bind( PropsValues.SYNC_LAN_SERVER_PORT); try { channelFuture.sync(); } catch (Exception e) { // Compiling fails when directly catching BindException. Netty seems // to throw an undeclared exception. if (e instanceof BindException) { channelFuture = serverBootstrap.bind(0); channelFuture.sync(); } else { throw e; } } Channel channel = channelFuture.channel(); InetSocketAddress inetSocketAddress = (InetSocketAddress)channel.localAddress(); _port = inetSocketAddress.getPort(); channelFuture.sync(); Runnable runnable = new Runnable() { @Override public void run() { long count = SyncFileService.getSyncFilesCount( SyncFile.UI_EVENT_DOWNLOADING, SyncFile.UI_EVENT_UPLOADING); long writeDelay = 0; if (count > 0) { _syncTrafficShapingHandler.setWriteDelay( PropsValues.SYNC_LAN_SERVER_WRITE_DELAY); } _syncTrafficShapingHandler.setWriteDelay(writeDelay); } }; ScheduledExecutorService scheduledExecutorService = LanEngine.getScheduledExecutorService(); scheduledExecutorService.scheduleWithFixedDelay( runnable, 0, 500, TimeUnit.MILLISECONDS); } public void stop() { if (_syncTrafficShapingHandler != null) { _syncTrafficShapingHandler.release(); } if (_childEventLoopGroup != null) { _childEventLoopGroup.shutdownGracefully(); } if (_parentEventLoopGroup != null) { _parentEventLoopGroup.shutdownGracefully(); } } protected ModelListener<SyncAccount> syncAccountListener; private EventLoopGroup _childEventLoopGroup; private LanFileServerInitializer _lanFileServerInitializer; private EventLoopGroup _parentEventLoopGroup; private int _port; private SyncTrafficShapingHandler _syncTrafficShapingHandler; }