/** * 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.portal.kernel.nio.intraband.welder.socket; import com.liferay.portal.kernel.nio.intraband.Intraband; import com.liferay.portal.kernel.nio.intraband.RegistrationReference; import com.liferay.portal.kernel.nio.intraband.welder.BaseWelder; import com.liferay.portal.kernel.util.GetterUtil; import com.liferay.portal.kernel.util.InetAddressUtil; import com.liferay.portal.kernel.util.PropsKeys; import com.liferay.portal.kernel.util.PropsUtil; import com.liferay.portal.kernel.util.SocketUtil; import com.liferay.portal.kernel.util.SocketUtil.ServerSocketConfigurator; import java.io.IOException; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketException; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; /** * @author Shuyang Zhou */ public class SocketWelder extends BaseWelder { public SocketWelder() throws IOException { // Assignments have to stay in the constructor because we need to // differentiate between a constructor created object and a // deserialization created object. Only the constructor created object // needs to assign values. The deserialization created object gets its // values from the original object. bufferSize = Configuration.bufferSize; keepAlive = Configuration.keepAlive; reuseAddress = Configuration.reuseAddress; soLinger = Configuration.soLinger; soTimeout = Configuration.soTimeout; tcpNoDelay = Configuration.tcpNoDelay; serverSocketChannel = SocketUtil.createServerSocketChannel( InetAddressUtil.getLoopbackInetAddress(), Configuration.serverStartPort, new SocketWelderServerSocketConfigurator()); ServerSocket serverSocket = serverSocketChannel.socket(); serverPort = serverSocket.getLocalPort(); } @Override protected void doDestroy() throws IOException { socketChannel.close(); } @Override protected RegistrationReference weldClient(Intraband intraband) throws IOException { socketChannel = SocketChannel.open(); _configureSocket(socketChannel.socket()); socketChannel.connect( new InetSocketAddress( InetAddressUtil.getLoopbackInetAddress(), serverPort)); return intraband.registerChannel(socketChannel); } @Override protected RegistrationReference weldServer(Intraband intraband) throws IOException { socketChannel = serverSocketChannel.accept(); serverSocketChannel.close(); _configureSocket(socketChannel.socket()); return intraband.registerChannel(socketChannel); } protected final int bufferSize; protected final boolean keepAlive; protected final boolean reuseAddress; protected final int serverPort; protected final transient ServerSocketChannel serverSocketChannel; protected transient SocketChannel socketChannel; protected final int soLinger; protected final int soTimeout; protected final boolean tcpNoDelay; protected static class Configuration { protected static final int bufferSize = GetterUtil.getInteger( PropsUtil.get(PropsKeys.INTRABAND_WELDER_SOCKET_BUFFER_SIZE)); protected static final boolean keepAlive = GetterUtil.getBoolean( PropsUtil.get(PropsKeys.INTRABAND_WELDER_SOCKET_KEEP_ALIVE)); protected static final boolean reuseAddress = GetterUtil.getBoolean( PropsUtil.get(PropsKeys.INTRABAND_WELDER_SOCKET_REUSE_ADDRESS)); protected static final int serverStartPort = GetterUtil.getInteger( PropsUtil.get(PropsKeys.INTRABAND_WELDER_SOCKET_SERVER_START_PORT)); protected static final int soLinger = GetterUtil.getInteger( PropsUtil.get(PropsKeys.INTRABAND_WELDER_SOCKET_SO_LINGER)); protected static final int soTimeout = GetterUtil.getInteger( PropsUtil.get(PropsKeys.INTRABAND_WELDER_SOCKET_SO_TIMEOUT)); protected static final boolean tcpNoDelay = GetterUtil.getBoolean( PropsUtil.get(PropsKeys.INTRABAND_WELDER_SOCKET_TCP_NO_DELAY)); } protected class SocketWelderServerSocketConfigurator implements ServerSocketConfigurator { @Override public void configure(ServerSocket serverSocket) throws SocketException { serverSocket.setReceiveBufferSize(bufferSize); serverSocket.setReuseAddress(reuseAddress); serverSocket.setSoTimeout(soTimeout); } } private void _configureSocket(Socket socket) throws SocketException { socket.setKeepAlive(keepAlive); socket.setReceiveBufferSize(bufferSize); socket.setReuseAddress(reuseAddress); socket.setSendBufferSize(bufferSize); if (soLinger <= 0) { socket.setSoLinger(false, soLinger); } else { socket.setSoLinger(true, soLinger); } socket.setSoTimeout(soTimeout); socket.setTcpNoDelay(tcpNoDelay); } }