Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2010-2024 60East Technologies Inc., All Rights Reserved.
//
// This computer software is owned by 60East Technologies Inc. and is
// protected by U.S. copyright laws and other laws and by international
// treaties. This computer software is furnished by 60East Technologies
// Inc. pursuant to a written license agreement and may be used, copied,
// transmitted, and stored only in accordance with the terms of such
// license agreement and with the inclusion of the above copyright notice.
// This computer software or any other copies thereof may not be provided
// or otherwise made available to any other person.
//
// U.S. Government Restricted Rights. This computer software: (a) was
// developed at private expense and is in all respects the proprietary
// information of 60East Technologies Inc.; (b) was not developed with
// government funds; (c) is a trade secret of 60East Technologies Inc.
// for all purposes of the Freedom of Information Act; and (d) is a
// commercial item and thus, pursuant to Section 12.212 of the Federal
// Acquisition Regulations (FAR) and DFAR Supplement Section 227.7202,
// Government's use, duplication or disclosure of the computer software
// is subject to the restrictions set forth by 60East Technologies Inc..
//
////////////////////////////////////////////////////////////////////////////
package com.crankuptheamps.client;
import java.net.Socket;
import java.net.URI;
import java.nio.ByteBuffer;
import java.beans.ExceptionListener;
import java.util.Properties;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import com.crankuptheamps.client.Message.SerializationResult;
import com.crankuptheamps.client.exception.AlreadyConnectedException;
import com.crankuptheamps.client.exception.ConnectionRefusedException;
import com.crankuptheamps.client.exception.DisconnectedException;
import com.crankuptheamps.client.exception.InvalidURIException;
import com.crankuptheamps.client.exception.RetryOperationException;
/**
* Implements an AMPS transport over standard TCP/IP.
* Use this transport by connecting to URIs beginning with {@code tcp://}.
*/
public class TCPTransport implements Transport
{
protected TCPTransportImpl _impl = null;
private Protocol _protocol = null;
private final Lock _sendLock = new ReentrantLock();
private ByteBuffer _sendBuffer = ByteBuffer.allocate(4096);
private static int _defaultReadTimeout = 0;
private static int _defaultConnectTimeout = 0;
// Other clients use daemon threads by default, but
// we have customer that depends on non-daemon threads (i.e. they
// want the program to continue running even once main() exits.)
private static boolean _useDaemonThreads = false;
/**
* Constructs a new TCPTransport instance with the specified protocol and properties.
* @param protocol The protocol used by the transport.
* @param properties The properties to configure the transport.
* @return A new TCPTransportImpl instance.
*/
protected TCPTransportImpl constructTransportImpl(Protocol protocol, Properties properties)
{
return new TCPTransportImpl(protocol, properties, new DefaultTransportFilter());
}
/**
* Constructs a new TCPTransport instance with the specified protocol and properties.
* @param protocol The protocol used by the transport.
* @param properties The properties to configure the transport.
*/
public TCPTransport(Protocol protocol, Properties properties)
{
this._protocol = protocol;
this._impl = constructTransportImpl(protocol,properties);
}
/**
* Constructs a new TCPTransport instance with the specified message type.
* @param msgType The protocol message type.
*/
public TCPTransport(Protocol msgType)
{
this(msgType, new Properties());
}
public TCPTransport(Protocol msgType, TCPTransportImpl impl)
{
this(msgType, new Properties());
this._impl = impl;
}
/**
* Sets whether daemon threads should be used by default.
* @param daemonThreads True to use daemon threads; false otherwise.
*/
public static void setDaemon(boolean daemonThreads)
{
TCPTransport._useDaemonThreads = daemonThreads;
}
/**
* Checks if daemon threads are being used by default.
* @return True if daemon threads are used; false otherwise.
*/
public static boolean isDaemon()
{
return TCPTransport._useDaemonThreads;
}
/**
* Sets the default read timeout used for socket reads. This value is
* used for new connections, but not applied to existing connections. A 0
* value means to wait forever for incoming data, or until an error occurs.
*
* @param defaultReadTimeoutMillis_ The default read timeout in milliseconds.
*/
public static void setDefaultReadTimeout(int defaultReadTimeoutMillis_)
{
TCPTransport._defaultReadTimeout = defaultReadTimeoutMillis_;
}
/**
* Returns the default read timeout used for socket reads. A 0 value
* means to wait forever for incoming data, or until an error occurs.
*
* @return The current default read timeout, in milliseconds.
*/
public static int getDefaultReadTimeout()
{
return TCPTransport._defaultReadTimeout;
}
/**
* Returns the default connect timeout used for new connections.
*
* @param defaultConnectTimeoutMillis_ The default connect timeout,
* in milliseconds. A 0 value means no timeout is specified, i.e. wait
* until the OS returns an error.
*/
public static void setDefaultConnectTimeout(int defaultConnectTimeoutMillis_)
{
TCPTransport._defaultConnectTimeout = defaultConnectTimeoutMillis_;
}
/**
* Returns the default connect timeout used for new connections.
*
* @return The default connect timeout in milliseconds. A 0 value means
* no timeout is specified, i.e. wait until the OS returns an error.
*/
public static int getDefaultConnectTimeout()
{
return TCPTransport._defaultConnectTimeout;
}
/**
* Factory method for creating a new instance of {@link TCPTransport}.
* @param messageType The protocol message type for the transport.
* @return A new instance of TCPTransport with the specified protocol message type.
*/
public static TCPTransport createTransport(Protocol messageType)
{
return new TCPTransport(messageType);
}
/**
* Factory method for creating a new instance of {@link TCPTransport}.
* @param messageType The protocol message type for the transport.
* @param impl The underlying implementation for the new transport.
* @return A new instance of TCPTransport with the specified protocol message type.
*/
public static TCPTransport createTransport(Protocol messageType, TCPTransportImpl impl)
{
return new TCPTransport(messageType, impl);
}
/**
* Sets the message handler for this transport.
* @param ml The message handler to set.
*/
public void setMessageHandler(MessageHandler ml)
{
this._impl.setMessageHandler(ml);
}
/**
* Sets the handler for newly created threads.
* @param tch_ The thread created handler to set.
*/
public void setThreadCreatedHandler(ThreadCreatedHandler tch_)
{
this._impl.setThreadCreatedHandler(tch_);
}
/**
* Sets the handler for disconnect events.
* @param dh The disconnect handler to set.
*/
public void setDisconnectHandler(TransportDisconnectHandler dh)
{
this._impl.setDisconnectHandler(dh);
}
/**
* Sets the listener for exception events.
* @param exceptionListener The exception listener to set.
*/
public void setExceptionListener(ExceptionListener exceptionListener)
{
this._impl.setExceptionListener(exceptionListener);
}
/**
* Sets the transport filter.
* @param filter The transport filter to set.
*/
public void setTransportFilter(TransportFilter filter)
{
_impl.setTransportFilter(filter);
}
/**
* Connects to the specified URI using the underlying implementation.
* @param uri The URI to connect to.
* @throws ConnectionRefusedException If the connection is refused.
* @throws AlreadyConnectedException If the transport is already connected.
* @throws InvalidURIException If the URI is invalid.
*/
public void connect(URI uri) throws ConnectionRefusedException, AlreadyConnectedException, InvalidURIException
{
this._impl.connect(uri);
}
/**
* Closes the transport, disconnecting it from the server.
* @throws Exception If an error occurs during the disconnect process.
*/
public void close() throws Exception
{
this._impl.disconnect();
}
/**
* Disconnects the transport from the server.
*/
public void disconnect()
{
this._impl.disconnect();
}
/**
* Handles a close event, notifying the underlying implementation.
* @param failedVersion_ The failed version.
* @param message The message associated with the close event.
* @param e The exception associated with the close event.
* @throws DisconnectedException If the transport is disconnected.
* @throws RetryOperationException If a retry operation is needed.
*/
public void handleCloseEvent(int failedVersion_, String message, Exception e) throws DisconnectedException, RetryOperationException
{
this._impl.handleCloseEvent(failedVersion_, message, e);
}
/**
* Sends a message without retrying, handling the serialization process.
* @param message The message to send.
* @throws DisconnectedException If the transport is disconnected.
*/
public void sendWithoutRetry(Message message) throws DisconnectedException
{
this._sendLock.lock();
try
{
_sendBuffer.clear();
// Reserve space for a 4-byte int at the
// beginning for the size of the message
_sendBuffer.position(4);
SerializationResult sr = message.serialize(_sendBuffer);
if(sr == Message.SerializationResult.BufferTooSmall)
{
// Buffer was too small, let's resize and retry
_sendBuffer = ByteBuffer.allocate(2 * _sendBuffer.capacity());
sendWithoutRetry(message);
return;
}
else if(sr == SerializationResult.OK)
{
// Write size integer now that we know the size
_sendBuffer.putInt(0, _sendBuffer.position() - 4);
// Flip buffer for reading
_sendBuffer.flip();
// Write buffer to socket
this._impl.send(_sendBuffer);
}
}
finally
{
this._sendLock.unlock();
}
}
/**
* Sends the specified message. This method handles synchronization, retries, and exception handling.
* @param message The message to send.
* @throws DisconnectedException If the transport is disconnected.
*/
public void send(Message message) throws DisconnectedException
{
this._sendLock.lock();
try
{
int currentVersion = getVersion();
try
{
sendWithoutRetry(message);
}
catch(DisconnectedException ex)
{
try
{
this.handleCloseEvent(currentVersion, "Exception occurred while sending", ex);
}
catch(RetryOperationException r)
{
; // retry
}
throw ex;
}
}
finally
{
this._sendLock.unlock();
}
}
/**
* Allocates a new message using the underlying protocol.
* @return The allocated message.
*/
public Message allocateMessage()
{
return this._protocol.allocateMessage();
}
/**
* Returns the size of the write queue.
* @return The size of the write queue.
* @throws DisconnectedException If the transport is disconnected.
*/
public long writeQueueSize() throws DisconnectedException
{
try
{
return this._impl.writeQueueSize();
}
catch(NullPointerException e)
{
throw new DisconnectedException("not connected", e);
}
}
/**
* Returns the size of the read queue.
* @return The size of the read queue.
* @throws DisconnectedException If the transport is disconnected.
*/
public long readQueueSize() throws DisconnectedException
{
try
{
return this._impl.writeQueueSize();
}
catch(NullPointerException e)
{
throw new DisconnectedException("not connected", e);
}
}
/**
* Flushes the transport's write queue.
* @return The number of messages flushed.
* @throws DisconnectedException If the transport is disconnected.
*/
public long flush() throws DisconnectedException
{
try
{
return this._impl.flush();
}
catch(NullPointerException e)
{
throw new DisconnectedException("not connected", e);
}
}
/**
* Flushes the transport's write queue with a specified timeout.
* @param timeout The maximum time to wait for flushing, in milliseconds.
* @return The number of messages flushed.
* @throws DisconnectedException If the transport is disconnected.
*/
public long flush(long timeout) throws DisconnectedException
{
try
{
return this._impl.flush(timeout);
}
catch(NullPointerException e)
{
throw new DisconnectedException("not connected", e);
}
}
/**
* Returns the underlying socket of the transport.
* @return The underlying socket.
*/
public Socket socket()
{
try
{
return this._impl.socket();
}
catch(Exception e)
{
return null;
}
}
/**
* Returns the version of the transport.
* @return The version of the transport.
*/
public int getVersion()
{
return this._impl._connectionVersion;
}
/**
* Sets the read timeout for the transport.
* @param readTimeout_ The read timeout in milliseconds.
*/
public void setReadTimeout(int readTimeout_)
{
this._impl.setReadTimeout(readTimeout_);
}
/**
* Gets the transport's currently registered idle task, or null
* if there is none.
*
* @return The currently registered idle runnable or null.
*/
public AMPSRunnable getIdleRunnable() {
return this._impl.getIdleRunnable();
}
/**
* Sets the idle runnable for the transport.
* @param runnable The idle runnable to set.
*/
public void setIdleRunnable(AMPSRunnable runnable)
{
this._impl.setIdleRunnable(runnable);
}
public void initFromClient(Client client) {
this._impl.initFromClient(client);
}
}