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.
/*
* MIT License
*
* Copyright (c) 2002-2023 Mikko Tommila
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.apfloat.samples;
import java.nio.channels.Channels;
import java.nio.channels.Selector;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
import java.nio.channels.ServerSocketChannel;
import java.net.InetSocketAddress;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.util.Set;
import java.util.Iterator;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
/**
* Server for executing {@link Operation}s from remote calls. The client
* should simply send a class implementing the {@link Operation}
* interface serialized through a socket connection. Obviously, the
* class must exist also in the server's classpath. The server will then
* simply call {@link Operation#execute()} on the operation, and send
* the resulting object back in the socket, serialized. If an exception
* occurs during the operation execution, nothing is returned and
* the socket connection is closed.
*
* @version 1.9.0
* @author Mikko Tommila
*/
public class OperationServer
{
private static class Request
implements Runnable
{
public Request(SocketChannel channel)
{
this.channel = channel;
}
@Override
public void run()
{
try (SocketChannel channel = this.channel)
{
info("Request processing started");
ObjectInputStream in = new ObjectInputStream(Channels.newInputStream(this.channel));
info("Ready to receive input data");
Operation> operation = (Operation>) in.readObject();
info("Executing operation");
Object result = operation.execute();
ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(Channels.newOutputStream(this.channel), BUFFER_SIZE));
info("Ready to write output data");
out.writeObject(result);
out.flush();
info("Request processing complete");
}
catch (Exception e)
{
// Avoid exiting the thread
warning("Request processing failed", e);
}
}
private SocketChannel channel;
}
private OperationServer()
{
}
/**
* Command-line entry point.
*
* @param args Command-line parameters.
*
* @exception IOException In case of unexpected network error.
*/
public static void main(String[] args)
throws IOException
{
int port,
workerThreads = 1;
if (args.length < 1)
{
System.err.println("USAGE: OperationServer port [workerThreads] [messageLevel]");
return;
}
try
{
port = Integer.parseInt(args[0]);
}
catch (NumberFormatException nfe)
{
System.err.println("Invalid port: " + args[0]);
return;
}
try
{
if (args.length > 1)
{
workerThreads = Integer.parseInt(args[1]);
if (workerThreads <= 0)
{
throw new NumberFormatException();
}
}
}
catch (NumberFormatException nfe)
{
System.err.println("Invalid number of workerThreads: " + args[0]);
return;
}
try
{
if (args.length > 2)
{
messageLevel = Integer.parseInt(args[2]);
}
}
catch (NumberFormatException nfe)
{
System.err.println("Invalid messageLevel: " + args[0]);
return;
}
// Create a selector object to monitor all open client connections.
Selector selector = Selector.open();
// Create a new non-blocking ServerSocketChannel, bind it to a port, and register it with the Selector
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); // Open channel
serverSocketChannel.configureBlocking(false); // Set non-blocking mode
serverSocketChannel.socket().bind(new InetSocketAddress(port)); // Bind to port
SelectionKey serverKey = serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
// Create a pool of worker threads that will run independently
Executor executor = Executors.newFixedThreadPool(workerThreads);
info("Waiting for connections to port " + port);
while (true) // The main server loop. The server runs forever.
{
// This call blocks until there is activity on one of the registered channels
selector.select();
// Get a java.util.Set containing the SelectionKey objects for all channels that are ready for I/O
Set keys = selector.selectedKeys();
// Use a java.util.Iterator to loop through the selected keys
for (Iterator i = keys.iterator(); i.hasNext(); )
{
SelectionKey key = i.next();
i.remove(); // Remove the key from the set of selected keys
// Check whether this key is the SelectionKey we got when we registered the ServerSocketChannel
if (key == serverKey)
{
// Activity on the ServerSocketChannel means a client is trying to connect to the server
if (key.isAcceptable())
{
// Accept the client connection
// Note that the client channel is in blocking mode; a separate thread will use it
SocketChannel clientSocketChannel = serverSocketChannel.accept();
info("New connection accepted");
// Put a new request to the queue so a worker thread can pick it up from there
executor.execute(new Request(clientSocketChannel));
}
}
}
}
}
private static void warning(String message, Exception e)
{
if (messageLevel >= WARNING)
{
System.err.println("WARNING: " + Thread.currentThread().getName() + ": " + message);
e.printStackTrace(System.err);
}
}
private static void info(String message)
{
if (messageLevel >= INFO)
{
System.err.println("INFO: " + Thread.currentThread().getName() + ": " + message);
}
}
private static void debug(String message)
{
if (messageLevel >= DEBUG)
{
System.err.println("DEBUG: " + Thread.currentThread().getName() + ": " + message);
}
}
private static final int BUFFER_SIZE = 8192;
private static final int ERROR = 0;
private static final int WARNING = 1;
private static final int INFO = 2;
private static final int DEBUG = 3;
private static int messageLevel = WARNING;
}