1/* 2 * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * - Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 11 * - Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * - Neither the name of Oracle nor the names of its 16 * contributors may be used to endorse or promote products derived 17 * from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32/* 33 * This source code is provided to illustrate the usage of a given feature 34 * or technique and has been deliberately simplified. Additional steps 35 * required for a production-quality application, such as security checks, 36 * input validation and proper error handling, might not be present in 37 * this sample code. 38 */ 39 40 41import java.nio.ByteBuffer; 42import java.nio.channels.CompletionHandler; 43 44/** 45 * Handles a cycle of reading / writing on the {@code Client}. 46 */ 47class ClientReader { 48 private final DataReader callback; 49 private final ChatServer chatServer; 50 51 ClientReader(ChatServer chatServer, DataReader callback) { 52 this.chatServer = chatServer; 53 this.callback = callback; 54 } 55 56 public boolean acceptsMessages() { 57 return callback.acceptsMessages(); 58 } 59 60 /** 61 * Runs a cycle of doing a beforeRead action and then enqueuing a new 62 * read on the client. Handles closed channels and errors while reading. 63 * If the client is still connected a new round of actions are called. 64 */ 65 public void run(final Client client) { 66 callback.beforeRead(client); 67 client.read(new CompletionHandler<Integer, ByteBuffer>() { 68 @Override 69 public void completed(Integer result, ByteBuffer buffer) { 70 // if result is negative or zero the connection has been closed or something gone wrong 71 if (result < 1) { 72 client.close(); 73 System.out.println("Closing connection to " + client); 74 chatServer.removeClient(client); 75 } else { 76 callback.onData(client, buffer, result); 77 // enqueue next round of actions 78 client.run(); 79 } 80 } 81 82 @Override 83 public void failed(Throwable exc, ByteBuffer buffer) { 84 client.close(); 85 chatServer.removeClient(client); 86 } 87 }); 88 } 89} 90