Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
This file is part of Niowire. Niowire is free software: you can redistribute it and/or modify it under the terms of the Lesser GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Niowire 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 Lesser GNU General Public License for more details. You should have received a copy of the Lesser GNU General Public License along with Niowire. If not, see <http://www.gnu.org/licenses/>.
 
 package io.niowire.server;
 
 import java.util.List;
This Class is responsible for passing the data from a client between the various components, and for returning data to the client. It holds an io.niowire.inspection.NioInspector, io.niowire.serializer.NioSerializer and several io.niowire.service.NioService objects. It will read data in from the client, send it through the parser, then through the inspector then to each of the services. Data on the return trip will also be collected from the serializer.

Author(s):
Trent Houliston
 
 {
 
 	private static final Logger LOG = LoggerFactory.getLogger(NioConnection.class);
 	//Initial Configuration Objects
 	//Shared context
 	private Context context;
 	//Parses the binary stream into objects
The inspector, (packets are run through this first before being sent to servers) it can be used for modification of packets, filtering of packets, or authentication of packets
 
 	private NioInspector inspect;
 	//The services that this connection sends to
 	private List<NioServiceservices;
 	//If this connection is open
 	private boolean open = true;

This creates a new NioConnection for a particular server. it handles all of the data which comes in through a byte buffer. It then uses the serializer to convert this byte stream into an object stream. This object stream is then sent through the inspector (for filtering, modification and authentication of packets) and is then sent through to all of the services.

Parameters:
key the selection key that is being used by the Selector to select this channel
serverConfig the configuration of the server which contains all the service definitions as well as meta data about the server.
Throws:
NioConnectionException if there is a problem setting up the services
 
 	{
 		//Store our variables
 		this. = key;
 		this. = serverConfig;
 		this. = new ArrayList<NioService>(serverConfig.getServiceFactories().size());
 		this. = new Context();
 
 		try
 		{
 			//Create our serializer from the definition and pass in our context
			//Create our inspector from the definition and pass in our context
			//Create all our services
			{
				try
				{
					//Create this service
					NioService service = factory.create();
					//Set the context to the service
					.add(service);
				}
				{
					.warn("A service threw an error while attempting to create it"ex);
				}
			}
		}
		//Explicitly catch runtime exception (we want to wrap all exceptions)
		catch (RuntimeException ex)
		{
			//Wrap it in a connection exception and throw it
			throw new NioConnectionException(ex);
		}
		//Catch any exception that might occur
		catch (Exception ex)
		{
			//Wrap it in a connection exception and throw it
			throw new NioConnectionException(ex);
		}
	}

Updates the interest operations on the SelectionKey, it checks if the serializer has data to write. And if it does then it updates the selection key to listen for Write operations as well

	public void updateInterestOps() throws IOException
	{
		if (!)
		{
		}
		//Start with the Read operation and add in the write operation if we need to
	}

This method occurs when data is retrieved from the client and is then sent to this NioConnection for processing. The buffer is deserialized into an object then filtered and sent to the services.

Parameters:
src the byte buffer source containing the data to be read
Returns:
the number of bytes written
Throws:
java.nio.channels.ClosedChannelException if the channel is closed
java.io.IOException if the serializer has an IOException on trying to deserialize
	public int write(ByteBuffer srcthrows ClosedChannelExceptionIOException
	{
		//Check if the connection is open
		if (!)
		{
		}
		//Get the number of remaining bytes (that's how many we will read)
		int bytes = src.remaining();
		//Deserialize the data
		//Loop through all the packets
		for (NioPacket packet : packets)
		{
			try
			{
				NioPacket p = .inspect(packet);
				//Loop through all the services sending the mangled packet
				for (NioService service : )
				{
					service.send(p);
				}
			}
			//This exception can be thrown by any of the services or the mangler
			{
				try
				{
					//Close ourselves as we failed authentication
					this.close();
				}
				catch (IOException ex1)
				{
					//Log that a connection failed authentication
					.trace("The connection {} failed authentication"this);
				}
			}
		}
		//Return the number of bytes remaining as the serializer should have absorbed them all
		return bytes;
	}

This method is used to read as much of the data out of our serializer as possible into the buffer. This buffer should then be used to send data to the client.

Parameters:
dst the destination buffer
Returns:
the number of bytes read
Throws:
java.io.IOException if the connection has been closed or the serializer has closed
	public int read(ByteBuffer dstthrows IOException
	{
		//Check that we are open
		if (!)
		{
		}
		//Read from the serializer into the destination buffer
		int read = .read(dst);
		//Update our interest ops (we might no longer need to write)
		return read;
	}

This method is used to send data which was not yet used by the client (too much for the socket) back to the connection to be buffered in the serializer.

Parameters:
buffer the buffer to be re-buffered
Throws:
java.io.IOException if the serializer is closed
	public void rebuffer(ByteBuffer bufferthrows IOException
	{
		//Check that we are open
		if (!)
		{
		}
	}

Returns if this NioConnection is open.

Returns:
true if the connection is open, false otherwise
	public boolean isOpen()
	{
		//Return if we are open
		return ;
	}

Close this NioConnection, release all the resources associated with this connection and tell all the services, serializer and inspector to also close (release resources)

	public void close() throws IOException
	{
		//Close our channel if it hasn't been closed already
		//Tell all our objects that we are using that they should close (clean up)
		for (NioService service : )
		{
			service.close();
		}
		//Remove ourselves from our activeserver object
		//Wipe out variables so they can be garbage collected
		 = null;
		 = null;
		 = null;
		 = null;
		//We are closed
		 = false;
	}

This method is called periodically as a way to ask the NioConnection to check if it should time out. This feature is handled by the inspect object as it receives every packet which goes through and can make a decision based on them.

	public void timeout() throws IOException
	{
		//Check the inspect for a timeout
		{
			//Close this connection
			this.close();
		}
	}

The toString method gets the UID from the inspect object as the toString of this object.

Returns:
the String representation of this object (it's UID)
	public String toString()
	{
		return .getUid();
	}

Gets the context object for this connection

Returns:
the context
	{
		return ;
	}

Updates the objects associated with this definition if needed from the server definition.
	public void updateServerDefinition()
	{
		//Create some variables, if the new definition is good we will update with these at the end
		NioSerializer newSerializer = null;
		NioInspector newInspector = null;
		LinkedList<NioServiceservicesToAdd = new LinkedList<NioService>();
		LinkedList<NioServiceservicesToRemove;
		try
		{
			//Check and update our serializer if we need to
			{
				newSerializer.setContext();
			}
			//Check and update the inspector if we need to
			{
				newInspector.setContext();
			}
			//Make new lists we can manipulate that hold our objects
			servicesToRemove = new LinkedList<NioService>();
			//Loop through the factories and the services and try to match them up
			for (Iterator<NioObjectFactory<? extends NioService>> fit = newServices.iterator(); fit.hasNext();)
			{
				NioObjectFactory<? extends NioServicefactory = fit.next();
				//Loop thorough the services
				for (Iterator<NioServicesit = servicesToRemove.iterator(); sit.hasNext();)
				{
					NioService service = sit.next();
					if (factory.isInstance(service))
					{
						//Remove the factory and the service from the lists (we have a match)
						fit.remove();
						sit.remove();
						break;
					}
				}
			}
			//Add any new services
			for (NioObjectFactory<? extends NioServicefactory : newServices)
			{
				NioService service = factory.create();
				servicesToAdd.add(service);
			}
			//Now we remove all the old services then add all the new ones
			for (NioService service : servicesToRemove)
			{
				try
				{
					service.close();
				}
				catch (IOException ex)
				{
				}
				finally
				{
					.remove(service);
				}
			}
			//Add all our new services
			.addAll(servicesToAdd);
			//Update our serializer and inspector
			if (newSerializer != null)
			{
				try
				{
				}
				catch (IOException ex)
				{
				}
				finally
				{
					this. = newSerializer;
				}
			}
			if (newInspector != null)
			{
				try
				{
					this..close();
				}
				catch (IOException ex)
				{
				}
				finally
				{
					this. = newInspector;
				}
			}
		}
		{
			.error("There was an exception while trying to update the server with the updated definition"ex);
		}
	}

This class is provided to all of the NioService objects as a way to interact with the connection and each other. It provides several methods which can tell the connection to update itself, as well as a map which can hold properties to be shared by the services.
	public class Context
	{

Tell this connection to refresh it's interest operations. This should be run by a service when it's interest state has change and it now has data which it needs to write back to the client.

Throws:
java.io.IOException if the connection is closed
		public void refreshInterestOps() throws IOException
		{
			//Update our interest ops
		}

Writes a packet back to the client

Parameters:
packet the packet to be written
Throws:
java.io.IOException if the serializer is closed
		public void write(NioPacket packetthrows IOException
		{
		}

Gets the InetSocketAddress of the other end of the connection. This is the IP/Port of the socket which we are connected to.

Returns:
the InetSocketAddress of the connection we are connected to
		{
			try
			{
				//Get the socket address
			}
			catch (IOException ex)
			{
				//Otherwise return null
				return null;
			}
		}

Get the UID of this connection (be aware that this can change during execution based on the inspect object)

Returns:
the Unique identifier for this connection, used to identify packets from it in services.
		public String getUid()
		{
			return .getUid();
		}

Gets the ID of the server (a unique string identifying the server object which this connection came from). (this will not change during execution)

Returns:
the unique ID of the server
		{
		}

Gets the declared name of the server which this connection came from. (This can change during execution)

Returns:
the name of the server
		{
		}

Gets the port of the server we are connecting from. (this will not change during execution)

Returns:
the port of the server
		public int getServerPort()
		{
		}
	}
New to GrepCode? Check out our FAQ X