Crossfire JXClient, Trunk
ChatServer.java
Go to the documentation of this file.
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 
41 import java.io.IOException;
42 import java.net.InetSocketAddress;
43 import java.net.SocketAddress;
44 import java.net.StandardSocketOptions;
45 import java.nio.channels.*;
46 import java.util.*;
47 import java.util.concurrent.Executors;
48 import java.util.concurrent.TimeUnit;
49 
54 public class ChatServer implements Runnable {
55  private final List<Client> connections = Collections.synchronizedList(new ArrayList<Client>());
56  private int port;
57  private final AsynchronousServerSocketChannel listener;
58  private final AsynchronousChannelGroup channelGroup;
59 
65  public ChatServer(int port) throws IOException {
66  channelGroup = AsynchronousChannelGroup.withFixedThreadPool(Runtime.getRuntime().availableProcessors(),
67  Executors.defaultThreadFactory());
68  this.port = port;
70  }
71 
77  public SocketAddress getSocketAddress() throws IOException {
78  return listener.getLocalAddress();
79  }
80 
84  public void run() {
85 
86  // call accept to wait for connections, tell it to call our CompletionHandler when there
87  // is a new incoming connection
88  listener.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() {
89  @Override
90  public void completed(AsynchronousSocketChannel result, Void attachment) {
91  // request a new accept and handle the incoming connection
92  listener.accept(null, this);
93  handleNewConnection(result);
94  }
95 
96  @Override
97  public void failed(Throwable exc, Void attachment) {
98  }
99  });
100  }
101 
107  public void shutdown() throws InterruptedException, IOException {
108  channelGroup.shutdownNow();
109  channelGroup.awaitTermination(1, TimeUnit.SECONDS);
110  }
111 
112  /*
113  * Creates a listener and starts accepting connections
114  */
115  private AsynchronousServerSocketChannel createListener(AsynchronousChannelGroup channelGroup) throws IOException {
116  final AsynchronousServerSocketChannel listener = openChannel(channelGroup);
117  listener.setOption(StandardSocketOptions.SO_REUSEADDR, true);
118  listener.bind(new InetSocketAddress(port));
119  return listener;
120  }
121 
122  private AsynchronousServerSocketChannel openChannel(AsynchronousChannelGroup channelGroup) throws IOException {
123  return AsynchronousServerSocketChannel.open(channelGroup);
124  }
125 
132  private void handleNewConnection(AsynchronousSocketChannel channel) {
133  Client client = new Client(channel, new ClientReader(this, new NameReader(this)));
134  try {
135  channel.setOption(StandardSocketOptions.TCP_NODELAY, true);
136  } catch (IOException e) {
137  // ignore
138  }
139  connections.add(client);
140  client.run();
141  }
142 
151  public void writeMessageToClients(Client client, String message) {
152  synchronized (connections) {
153  for (Client clientConnection : connections) {
154  if (clientConnection != client) {
155  clientConnection.writeMessageFrom(client, message);
156  }
157  }
158  }
159  }
160 
161  public void removeClient(Client client) {
162  connections.remove(client);
163  }
164 
165  private static void usage() {
166  System.err.println("ChatServer [-port <port number>]");
167  System.exit(1);
168  }
169 
170  public static void main(String[] args) throws IOException {
171  int port = 5000;
172  if (args.length != 0 && args.length != 2) {
173  usage();
174  } else if (args.length == 2) {
175  try {
176  if (args[0].equals("-port")) {
177  port = Integer.parseInt(args[1]);
178  } else {
179  usage();
180  }
181  } catch (NumberFormatException e) {
182  usage();
183  }
184  }
185  System.out.println("Running on port " + port);
186  new ChatServer(port).run();
187  }
188 }
ChatServer.main
static void main(String[] args)
Definition: ChatServer.java:170
ChatServer
Definition: ChatServer.java:54
ChatServer.openChannel
AsynchronousServerSocketChannel openChannel(AsynchronousChannelGroup channelGroup)
Definition: ChatServer.java:122
ChatServer.shutdown
void shutdown()
Definition: ChatServer.java:107
ChatServer.getSocketAddress
SocketAddress getSocketAddress()
Definition: ChatServer.java:77
ChatServer.port
int port
Definition: ChatServer.java:56
ChatServer.connections
final List< Client > connections
Definition: ChatServer.java:55
ChatServer.listener
final AsynchronousServerSocketChannel listener
Definition: ChatServer.java:57
ChatServer.channelGroup
final AsynchronousChannelGroup channelGroup
Definition: ChatServer.java:58
ChatServer.usage
static void usage()
Definition: ChatServer.java:165
ChatServer.handleNewConnection
void handleNewConnection(AsynchronousSocketChannel channel)
Definition: ChatServer.java:132
ChatServer.createListener
AsynchronousServerSocketChannel createListener(AsynchronousChannelGroup channelGroup)
Definition: ChatServer.java:115
ChatServer.run
void run()
Definition: ChatServer.java:84
ChatServer.removeClient
void removeClient(Client client)
Definition: ChatServer.java:161
ChatServer.writeMessageToClients
void writeMessageToClients(Client client, String message)
Definition: ChatServer.java:151
ChatServer.ChatServer
ChatServer(int port)
Definition: ChatServer.java:65