41 import java.io.IOException;
42 import java.nio.ByteBuffer;
43 import java.nio.channels.AsynchronousSocketChannel;
44 import java.nio.channels.CompletionHandler;
45 import java.util.LinkedList;
46 import java.util.Queue;
47 import java.util.concurrent.atomic.AtomicReference;
60 private final AsynchronousSocketChannel channel;
61 private AtomicReference<ClientReader> reader;
62 private String userName;
63 private final StringBuilder messageBuffer =
new StringBuilder();
65 private final Queue<ByteBuffer> queue =
new LinkedList<ByteBuffer>();
66 private boolean writing =
false;
68 public Client(AsynchronousSocketChannel channel, ClientReader reader) {
69 this.channel = channel;
70 this.reader =
new AtomicReference<ClientReader>(reader);
80 private void writeMessage(
final ByteBuffer buffer) {
81 boolean threadShouldWrite =
false;
88 threadShouldWrite =
true;
92 if (threadShouldWrite) {
97 private void writeFromQueue() {
100 synchronized (queue) {
101 buffer = queue.poll();
102 if (buffer ==
null) {
113 private void writeBuffer(ByteBuffer buffer) {
114 channel.write(buffer, buffer,
new CompletionHandler<Integer, ByteBuffer>() {
116 public void completed(Integer result, ByteBuffer buffer) {
117 if (buffer.hasRemaining()) {
118 channel.write(buffer, buffer,
this);
126 public void failed(Throwable exc, ByteBuffer attachment) {
135 public void writeStringMessage(String
string) {
136 writeMessage(ByteBuffer.wrap(
string.getBytes()));
144 public void writeMessageFrom(Client client, String message) {
145 if (reader.get().acceptsMessages()) {
146 writeStringMessage(client.getUserName() +
": " + message);
154 public void read(CompletionHandler<Integer, ? super ByteBuffer> completionHandler) {
155 ByteBuffer input = ByteBuffer.allocate(256);
156 if (!channel.isOpen()) {
159 channel.read(input, input, completionHandler);
165 public void close() {
168 }
catch (IOException e) {
177 reader.get().run(
this);
180 public void setUserName(String userName) {
181 this.userName = userName;
184 public void setReader(ClientReader reader) {
185 this.reader.set(reader);
188 public String getUserName() {
192 public void appendMessage(String message) {
193 synchronized (messageBuffer) {
194 messageBuffer.append(message);
202 public String nextMessage() {
203 synchronized(messageBuffer) {
204 int nextNewline = messageBuffer.indexOf(
"\n");
205 if (nextNewline == -1) {
208 String message = messageBuffer.substring(0, nextNewline + 1);
209 messageBuffer.delete(0, nextNewline + 1);