// Copyright 2002 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.opengse.core;
import java.io.IOException;
import java.nio.channels.SelectionKey;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
/**
* Translates ACCEPT {@code NetSelectionCallback} events
* generated by {@code NetSelector} into
* {@code AcceptCallback} events. During the translation, sockets
* are accepted and configured for NIO usage.
*
* @see AcceptCallback
* @author Peter Mattis
*/
public class AcceptServer implements NetSelectionCallback {
private final AcceptCallback callback;
private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
/**
* Class constructor.
*/
public AcceptServer(AcceptCallback callback) {
this.callback = callback;
}
/**
* Accepts new connections on the {@code ServerSocketChannel}
* associated with {@code key} and passes them on to
* {@code callback}.
*/
public void handleEvent(SelectionKey key) {
ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
try {
for (;;) {
SocketChannel ns = ssc.accept();
if (ns == null) {
break;
}
initSocketChannel(ns);
callback.handleNewConnection(ns, EMPTY_BYTE_ARRAY);
}
} catch (IOException e) { /* ignored */ }
}
private static void initSocketChannel(SocketChannel channel)
throws IOException {
// Disable nagle's algorithm, as servlet i/o is not interactive and
// performance is negatively impacted with a TCP delay.
channel.socket().setTcpNoDelay(true);
// Set for asynchronous i/o.
channel.configureBlocking(false);
}
/**
* Accepts a new socket connection together some bytes that have been read
* from the given socket already.
*/
public void handleNewConnectionWithBytesRead(SocketChannel channel,
byte[] bytesAlreadyRead) {
try {
initSocketChannel(channel);
callback.handleNewConnection(channel, bytesAlreadyRead);
} catch (IOException e) { /* ignored */ }
}
}