[New] added small chat server/client
This commit is contained in:
parent
b5ac7d008f
commit
863ffecd95
15
pom.xml
15
pom.xml
|
@ -30,6 +30,11 @@
|
||||||
</scm>
|
</scm>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-log4j12</artifactId>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -46,9 +51,9 @@
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-source-plugin</artifactId>
|
<artifactId>maven-source-plugin</artifactId>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-javadoc-plugin</artifactId>
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
@ -57,11 +62,11 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-site-plugin</artifactId>
|
<artifactId>maven-site-plugin</artifactId>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<!-- explicitly define maven-deploy-plugin after other to force exec order -->
|
<!-- explicitly define maven-deploy-plugin after other to force exec order -->
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-deploy-plugin</artifactId>
|
<artifactId>maven-deploy-plugin</artifactId>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
|
@ -48,6 +48,7 @@ public class CommunicationConnection implements Runnable {
|
||||||
private Thread queueThread;
|
private Thread queueThread;
|
||||||
private volatile boolean run;
|
private volatile boolean run;
|
||||||
private MapOfLists<CommandKey, ConnectionObserver> connectionObservers;
|
private MapOfLists<CommandKey, ConnectionObserver> connectionObservers;
|
||||||
|
private List<ConnectionStateObserver> connectionStateObservers;
|
||||||
|
|
||||||
private CommunicationEndpoint endpoint;
|
private CommunicationEndpoint endpoint;
|
||||||
private IoMessageVisitor messageVisitor;
|
private IoMessageVisitor messageVisitor;
|
||||||
|
@ -73,6 +74,7 @@ public class CommunicationConnection implements Runnable {
|
||||||
this.stateMsg = this.state.toString();
|
this.stateMsg = this.state.toString();
|
||||||
this.messageQueue = new LinkedBlockingDeque<>();
|
this.messageQueue = new LinkedBlockingDeque<>();
|
||||||
this.connectionObservers = new MapOfLists<>();
|
this.connectionObservers = new MapOfLists<>();
|
||||||
|
this.connectionStateObservers = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setArchive(IoMessageArchive archive) {
|
public void setArchive(IoMessageArchive archive) {
|
||||||
|
@ -123,9 +125,31 @@ public class CommunicationConnection implements Runnable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addConnectionStateObserver(ConnectionStateObserver observer) {
|
||||||
|
synchronized (this.connectionStateObservers) {
|
||||||
|
this.connectionStateObservers.add(observer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeConnectionStateObserver(ConnectionStateObserver observer) {
|
||||||
|
synchronized (this.connectionStateObservers) {
|
||||||
|
this.connectionStateObservers.remove(observer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void notifyStateChange(ConnectionState state, String stateMsg) {
|
public void notifyStateChange(ConnectionState state, String stateMsg) {
|
||||||
|
ConnectionState oldState = this.state;
|
||||||
|
String oldStateMsg = this.stateMsg;
|
||||||
this.state = state;
|
this.state = state;
|
||||||
this.stateMsg = stateMsg;
|
this.stateMsg = stateMsg;
|
||||||
|
|
||||||
|
List<ConnectionStateObserver> observers;
|
||||||
|
synchronized (this.connectionStateObservers) {
|
||||||
|
observers = new ArrayList<>(this.connectionStateObservers);
|
||||||
|
}
|
||||||
|
for (ConnectionStateObserver observer : observers) {
|
||||||
|
observer.notify(oldState, oldStateMsg, state, stateMsg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void switchMode(ConnectionMode mode) {
|
public void switchMode(ConnectionMode mode) {
|
||||||
|
@ -160,7 +184,6 @@ public class CommunicationConnection implements Runnable {
|
||||||
logger.info("Started SIMULATION connection!"); //$NON-NLS-1$
|
logger.info("Started SIMULATION connection!"); //$NON-NLS-1$
|
||||||
break;
|
break;
|
||||||
case ON:
|
case ON:
|
||||||
logger.info("Connecting..."); //$NON-NLS-1$
|
|
||||||
if (this.queueThread != null) {
|
if (this.queueThread != null) {
|
||||||
logger.warn(MessageFormat.format("{0}: Already connected!", this.id)); //$NON-NLS-1$
|
logger.warn(MessageFormat.format("{0}: Already connected!", this.id)); //$NON-NLS-1$
|
||||||
} else {
|
} else {
|
||||||
|
@ -327,8 +350,10 @@ public class CommunicationConnection implements Runnable {
|
||||||
}
|
}
|
||||||
synchronized (this.connectionObservers) {
|
synchronized (this.connectionObservers) {
|
||||||
List<ConnectionObserver> observers = this.connectionObservers.getList(message.getKey());
|
List<ConnectionObserver> observers = this.connectionObservers.getList(message.getKey());
|
||||||
for (ConnectionObserver observer : observers) {
|
if (observers != null) {
|
||||||
observer.notify(message.getKey(), message);
|
for (ConnectionObserver observer : observers) {
|
||||||
|
observer.notify(message.getKey(), message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,7 @@ public class ConnectionMessages {
|
||||||
value = StringHelper.NULL;
|
value = StringHelper.NULL;
|
||||||
|
|
||||||
String msg = "{0}: parameter ''{1}'' has invalid value ''{2}''"; //$NON-NLS-1$
|
String msg = "{0}: parameter ''{1}'' has invalid value ''{2}''"; //$NON-NLS-1$
|
||||||
msg = MessageFormat.format(msg, clazz.getName(), parameterName, value);
|
msg = MessageFormat.format(msg, clazz.getSimpleName(), parameterName, value);
|
||||||
ConnectionException e = new ConnectionException(msg);
|
ConnectionException e = new ConnectionException(msg);
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ public class ConnectionMessages {
|
||||||
*/
|
*/
|
||||||
public static ConnectionException throwConflictingParameters(Class<?> clazz, String parameter1, String parameter2) {
|
public static ConnectionException throwConflictingParameters(Class<?> clazz, String parameter1, String parameter2) {
|
||||||
String msg = "{0} : The parameters {1} and {2} can not be both activated as they conflict"; //$NON-NLS-1$
|
String msg = "{0} : The parameters {1} and {2} can not be both activated as they conflict"; //$NON-NLS-1$
|
||||||
msg = MessageFormat.format(msg, clazz.getName(), parameter1, parameter1);
|
msg = MessageFormat.format(msg, clazz.getSimpleName(), parameter1, parameter1);
|
||||||
ConnectionException e = new ConnectionException(msg);
|
ConnectionException e = new ConnectionException(msg);
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
@ -101,10 +101,12 @@ public class ConnectionMessages {
|
||||||
* @param defValue
|
* @param defValue
|
||||||
*/
|
*/
|
||||||
public static void warnUnsetParameter(Class<?> clazz, String parameterName, String defValue) {
|
public static void warnUnsetParameter(Class<?> clazz, String parameterName, String defValue) {
|
||||||
String msg = "{0}: parameter ''{1}'' is not set, using default value ''{2}''"; //$NON-NLS-1$
|
if (logger.isDebugEnabled()) {
|
||||||
msg = MessageFormat.format(msg, clazz.getName(), parameterName, defValue);
|
String msg = "{0}: parameter ''{1}'' is not set, using default value ''{2}''"; //$NON-NLS-1$
|
||||||
Map<String, String> properties = new HashMap<String, String>();
|
msg = MessageFormat.format(msg, clazz.getSimpleName(), parameterName, defValue);
|
||||||
logger.warn(MessageFormat.format(msg, properties));
|
Map<String, String> properties = new HashMap<String, String>();
|
||||||
|
logger.warn(MessageFormat.format(msg, properties));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
package ch.eitchnet.communication;
|
||||||
|
|
||||||
|
public interface ConnectionStateObserver {
|
||||||
|
|
||||||
|
public void notify(ConnectionState oldState, String oldStateMsg, ConnectionState newState, String newStateMsg);
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
package ch.eitchnet.communication.chat;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
|
||||||
|
import ch.eitchnet.utils.helper.StringHelper;
|
||||||
|
|
||||||
|
public class Chat {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
if (args.length < 3)
|
||||||
|
printIllegalArgsAndExit(args);
|
||||||
|
|
||||||
|
if (args[0].equals("server")) { //$NON-NLS-1$
|
||||||
|
if (args.length != 3)
|
||||||
|
printIllegalArgsAndExit(args);
|
||||||
|
startServer(args);
|
||||||
|
} else if (args[0].equals("client")) { //$NON-NLS-1$
|
||||||
|
if (args.length != 4)
|
||||||
|
printIllegalArgsAndExit(args);
|
||||||
|
startClient(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void startServer(String[] args) {
|
||||||
|
|
||||||
|
// port
|
||||||
|
int port;
|
||||||
|
String portS = args[1];
|
||||||
|
try {
|
||||||
|
port = Integer.parseInt(portS);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
System.err.println(MessageFormat.format("Illegal port: {0}", portS)); //$NON-NLS-1$
|
||||||
|
printIllegalArgsAndExit(args);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (port < 1 || port > 65535) {
|
||||||
|
System.err.println(MessageFormat.format("Illegal port: {0}", port)); //$NON-NLS-1$
|
||||||
|
printIllegalArgsAndExit(args);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// username
|
||||||
|
String username = args[2];
|
||||||
|
|
||||||
|
// start
|
||||||
|
ChatServer chatServer = new ChatServer(port, username);
|
||||||
|
chatServer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void startClient(String[] args) {
|
||||||
|
|
||||||
|
// server
|
||||||
|
InetAddress host;
|
||||||
|
String hostS = args[1];
|
||||||
|
try {
|
||||||
|
host = InetAddress.getByName(hostS);
|
||||||
|
} catch (UnknownHostException e1) {
|
||||||
|
System.err.println(MessageFormat.format("Illegal server address: {0}", hostS)); //$NON-NLS-1$
|
||||||
|
printIllegalArgsAndExit(args);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// port
|
||||||
|
int port;
|
||||||
|
String portS = args[2];
|
||||||
|
try {
|
||||||
|
port = Integer.parseInt(portS);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
System.err.println(MessageFormat.format("Illegal port: {0}", portS)); //$NON-NLS-1$
|
||||||
|
printIllegalArgsAndExit(args);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (port < 1 || port > 65535) {
|
||||||
|
System.err.println(MessageFormat.format("Illegal port: {0}", port)); //$NON-NLS-1$
|
||||||
|
printIllegalArgsAndExit(args);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// username
|
||||||
|
String username = args[3];
|
||||||
|
|
||||||
|
// start
|
||||||
|
ChatClient chatClient = new ChatClient(host, port, username);
|
||||||
|
chatClient.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void printIllegalArgsAndExit(String[] args) {
|
||||||
|
System.err.print("Illegal arguments: "); //$NON-NLS-1$
|
||||||
|
if (args.length == 0) {
|
||||||
|
System.err.print("(none)"); //$NON-NLS-1$
|
||||||
|
} else {
|
||||||
|
for (String arg : args) {
|
||||||
|
System.err.print(arg + StringHelper.SPACE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.err.println();
|
||||||
|
System.err.println("Usage: java ...Chat server <port> <username>"); //$NON-NLS-1$
|
||||||
|
System.err.println("Usage: java ...Chat client <server> <port> <username>"); //$NON-NLS-1$
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,91 @@
|
||||||
|
package ch.eitchnet.communication.chat;
|
||||||
|
|
||||||
|
import static ch.eitchnet.communication.chat.ChatMessageVisitor.inboundKey;
|
||||||
|
import static ch.eitchnet.communication.chat.ChatMessageVisitor.outboundKey;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
import ch.eitchnet.communication.CommandKey;
|
||||||
|
import ch.eitchnet.communication.CommunicationConnection;
|
||||||
|
import ch.eitchnet.communication.ConnectionMode;
|
||||||
|
import ch.eitchnet.communication.ConnectionObserver;
|
||||||
|
import ch.eitchnet.communication.ConnectionState;
|
||||||
|
import ch.eitchnet.communication.ConnectionStateObserver;
|
||||||
|
import ch.eitchnet.communication.IoMessage;
|
||||||
|
import ch.eitchnet.communication.tcpip.ClientSocketEndpoint;
|
||||||
|
import ch.eitchnet.communication.tcpip.SocketEndpointConstants;
|
||||||
|
import ch.eitchnet.communication.tcpip.SocketMessageVisitor;
|
||||||
|
|
||||||
|
public class ChatClient implements ConnectionObserver, ConnectionStateObserver {
|
||||||
|
|
||||||
|
private static final String id = "ChatClient"; //$NON-NLS-1$
|
||||||
|
private InetAddress host;
|
||||||
|
private int port;
|
||||||
|
private String username;
|
||||||
|
private boolean connected;
|
||||||
|
|
||||||
|
public ChatClient(InetAddress host, int port, String username) {
|
||||||
|
this.host = host;
|
||||||
|
this.port = port;
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start() {
|
||||||
|
ConnectionMode mode = ConnectionMode.ON;
|
||||||
|
|
||||||
|
Map<String, String> parameters = new HashMap<>();
|
||||||
|
parameters.put(SocketEndpointConstants.PARAMETER_USE_TIMEOUT, Boolean.FALSE.toString());
|
||||||
|
parameters.put(SocketEndpointConstants.PARAMETER_REMOTE_INPUT_ADDRESS, this.host.getHostAddress());
|
||||||
|
parameters.put(SocketEndpointConstants.PARAMETER_REMOTE_INPUT_PORT, Integer.toString(this.port));
|
||||||
|
parameters.put(SocketEndpointConstants.PARAMETER_CLOSE_AFTER_SEND, Boolean.FALSE.toString());
|
||||||
|
|
||||||
|
SocketMessageVisitor messageVisitor = new ChatMessageVisitor(id);
|
||||||
|
ClientSocketEndpoint endpoint = new ClientSocketEndpoint();
|
||||||
|
|
||||||
|
CommunicationConnection connection = new CommunicationConnection(id, mode, parameters, endpoint, messageVisitor);
|
||||||
|
connection.addConnectionObserver(outboundKey, this);
|
||||||
|
connection.addConnectionObserver(inboundKey, this);
|
||||||
|
connection.addConnectionStateObserver(this);
|
||||||
|
connection.configure();
|
||||||
|
connection.start();
|
||||||
|
|
||||||
|
while (!this.connected) {
|
||||||
|
synchronized (this) {
|
||||||
|
try {
|
||||||
|
this.wait(2000l);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
System.err.println("oops: " + e.getMessage()); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("Connected. Send messages to user:"); //$NON-NLS-1$
|
||||||
|
while (true) {
|
||||||
|
@SuppressWarnings("resource")
|
||||||
|
Scanner in = new Scanner(System.in);
|
||||||
|
//System.out.print(this.username + ": ");
|
||||||
|
String line = in.nextLine();
|
||||||
|
connection.send(ChatIoMessage.msg(outboundKey, id, this.username, line));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notify(CommandKey key, IoMessage message) {
|
||||||
|
if (key.equals(inboundKey)) {
|
||||||
|
ChatIoMessage chatIoMessage = (ChatIoMessage) message;
|
||||||
|
System.out.println(chatIoMessage.getChatMsg());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notify(ConnectionState oldState, String oldStateMsg, ConnectionState newState, String newStateMsg) {
|
||||||
|
this.connected = newState == ConnectionState.CONNECTED || newState == ConnectionState.IDLE
|
||||||
|
|| newState == ConnectionState.WORKING;
|
||||||
|
synchronized (this) {
|
||||||
|
this.notifyAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package ch.eitchnet.communication.chat;
|
||||||
|
|
||||||
|
import ch.eitchnet.communication.CommandKey;
|
||||||
|
import ch.eitchnet.communication.IoMessage;
|
||||||
|
import ch.eitchnet.utils.helper.StringHelper;
|
||||||
|
|
||||||
|
public class ChatIoMessage extends IoMessage {
|
||||||
|
|
||||||
|
private String chatMsg;
|
||||||
|
|
||||||
|
public ChatIoMessage(String id, CommandKey key, String connectionId) {
|
||||||
|
super(id, key, connectionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getChatMsg() {
|
||||||
|
return this.chatMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChatMsg(String chagMsg) {
|
||||||
|
this.chatMsg = chagMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ChatIoMessage msg(CommandKey key, String connId, String username, String msg) {
|
||||||
|
|
||||||
|
String line = username + StringHelper.COLON + StringHelper.SPACE + msg;
|
||||||
|
|
||||||
|
ChatIoMessage chatIoMessage = new ChatIoMessage(StringHelper.getUniqueId(), key, connId);
|
||||||
|
chatIoMessage.setChatMsg(line);
|
||||||
|
return chatIoMessage;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package ch.eitchnet.communication.chat;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
|
||||||
|
import ch.eitchnet.communication.CommandKey;
|
||||||
|
import ch.eitchnet.communication.IoMessage;
|
||||||
|
import ch.eitchnet.communication.tcpip.SocketMessageVisitor;
|
||||||
|
import ch.eitchnet.utils.helper.StringHelper;
|
||||||
|
|
||||||
|
public class ChatMessageVisitor extends SocketMessageVisitor {
|
||||||
|
|
||||||
|
public static final CommandKey inboundKey = CommandKey.key("server", "msg"); //$NON-NLS-1$//$NON-NLS-2$
|
||||||
|
public static final CommandKey outboundKey = CommandKey.key("client", "msg"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
|
||||||
|
public ChatMessageVisitor(String connectionId) {
|
||||||
|
super(connectionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IoMessage visit(DataInputStream inputStream, DataOutputStream outputStream) throws Exception {
|
||||||
|
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
|
||||||
|
String line = bufferedReader.readLine();
|
||||||
|
ChatIoMessage chatIoMessage = new ChatIoMessage(StringHelper.getUniqueId(), inboundKey, this.connectionId);
|
||||||
|
chatIoMessage.setChatMsg(line);
|
||||||
|
return chatIoMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(DataInputStream inputStream, DataOutputStream outputStream, IoMessage message) throws Exception {
|
||||||
|
ChatIoMessage chatIoMessage = (ChatIoMessage) message;
|
||||||
|
outputStream.writeBytes(chatIoMessage.getChatMsg());
|
||||||
|
outputStream.writeByte('\n');
|
||||||
|
outputStream.flush();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,88 @@
|
||||||
|
package ch.eitchnet.communication.chat;
|
||||||
|
|
||||||
|
import static ch.eitchnet.communication.chat.ChatMessageVisitor.inboundKey;
|
||||||
|
import static ch.eitchnet.communication.chat.ChatMessageVisitor.outboundKey;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
import ch.eitchnet.communication.CommandKey;
|
||||||
|
import ch.eitchnet.communication.CommunicationConnection;
|
||||||
|
import ch.eitchnet.communication.ConnectionMode;
|
||||||
|
import ch.eitchnet.communication.ConnectionObserver;
|
||||||
|
import ch.eitchnet.communication.ConnectionState;
|
||||||
|
import ch.eitchnet.communication.ConnectionStateObserver;
|
||||||
|
import ch.eitchnet.communication.IoMessage;
|
||||||
|
import ch.eitchnet.communication.tcpip.ServerSocketEndpoint;
|
||||||
|
import ch.eitchnet.communication.tcpip.SocketEndpointConstants;
|
||||||
|
import ch.eitchnet.communication.tcpip.SocketMessageVisitor;
|
||||||
|
|
||||||
|
public class ChatServer implements ConnectionObserver, ConnectionStateObserver {
|
||||||
|
|
||||||
|
private static final String id = "ChatServer"; //$NON-NLS-1$
|
||||||
|
private int port;
|
||||||
|
private String username;
|
||||||
|
private boolean connected;
|
||||||
|
|
||||||
|
public ChatServer(int port, String username) {
|
||||||
|
this.port = port;
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start() {
|
||||||
|
ConnectionMode mode = ConnectionMode.ON;
|
||||||
|
|
||||||
|
Map<String, String> parameters = new HashMap<>();
|
||||||
|
parameters.put(SocketEndpointConstants.PARAMETER_USE_TIMEOUT, Boolean.FALSE.toString());
|
||||||
|
parameters.put(SocketEndpointConstants.PARAMETER_LOCAL_INPUT_PORT, Integer.toString(this.port));
|
||||||
|
parameters.put(SocketEndpointConstants.PARAMETER_CLOSE_AFTER_SEND, Boolean.FALSE.toString());
|
||||||
|
parameters.put(SocketEndpointConstants.PARAMETER_CLOSE_AFTER_SEND, Boolean.FALSE.toString());
|
||||||
|
|
||||||
|
SocketMessageVisitor messageVisitor = new ChatMessageVisitor(id);
|
||||||
|
ServerSocketEndpoint endpoint = new ServerSocketEndpoint();
|
||||||
|
|
||||||
|
CommunicationConnection connection = new CommunicationConnection(id, mode, parameters, endpoint, messageVisitor);
|
||||||
|
connection.addConnectionObserver(outboundKey, this);
|
||||||
|
connection.addConnectionObserver(inboundKey, this);
|
||||||
|
connection.addConnectionStateObserver(this);
|
||||||
|
connection.configure();
|
||||||
|
connection.start();
|
||||||
|
|
||||||
|
while (!this.connected) {
|
||||||
|
synchronized (this) {
|
||||||
|
try {
|
||||||
|
this.wait(2000l);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
System.err.println("oops: " + e.getMessage()); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("Connected. Send messages to user:"); //$NON-NLS-1$
|
||||||
|
while (true) {
|
||||||
|
@SuppressWarnings("resource")
|
||||||
|
Scanner in = new Scanner(System.in);
|
||||||
|
//System.out.print(this.username + ": ");
|
||||||
|
String line = in.nextLine();
|
||||||
|
connection.send(ChatIoMessage.msg(outboundKey, id, this.username, line));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notify(CommandKey key, IoMessage message) {
|
||||||
|
if (key.equals(inboundKey)) {
|
||||||
|
ChatIoMessage chatIoMessage = (ChatIoMessage) message;
|
||||||
|
System.out.println(chatIoMessage.getChatMsg());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notify(ConnectionState oldState, String oldStateMsg, ConnectionState newState, String newStateMsg) {
|
||||||
|
this.connected = newState == ConnectionState.CONNECTED || newState == ConnectionState.IDLE
|
||||||
|
|| newState == ConnectionState.WORKING;
|
||||||
|
synchronized (this) {
|
||||||
|
this.notifyAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -173,9 +173,11 @@ public class ClientSocketEndpoint implements CommunicationEndpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
// configure the socket
|
// configure the socket
|
||||||
String msg = "BufferSize (send/read): {0} / {1} SoLinger: {2} TcpNoDelay: {3}"; //$NON-NLS-1$
|
if (logger.isDebugEnabled()) {
|
||||||
logger.info(MessageFormat.format(msg, this.socket.getSendBufferSize(),
|
String msg = "BufferSize (send/read): {0} / {1} SoLinger: {2} TcpNoDelay: {3}"; //$NON-NLS-1$
|
||||||
this.socket.getReceiveBufferSize(), this.socket.getSoLinger(), this.socket.getTcpNoDelay()));
|
logger.info(MessageFormat.format(msg, this.socket.getSendBufferSize(),
|
||||||
|
this.socket.getReceiveBufferSize(), this.socket.getSoLinger(), this.socket.getTcpNoDelay()));
|
||||||
|
}
|
||||||
//outputSocket.setSendBufferSize(1);
|
//outputSocket.setSendBufferSize(1);
|
||||||
//outputSocket.setSoLinger(true, 0);
|
//outputSocket.setSoLinger(true, 0);
|
||||||
//outputSocket.setTcpNoDelay(true);
|
//outputSocket.setTcpNoDelay(true);
|
||||||
|
@ -196,7 +198,7 @@ public class ClientSocketEndpoint implements CommunicationEndpoint {
|
||||||
this.inputStream.skip(available);
|
this.inputStream.skip(available);
|
||||||
}
|
}
|
||||||
|
|
||||||
msg = "Connected {0}: {1}:{2} with local side {3}:{4}"; //$NON-NLS-1$
|
String msg = "Connected {0}: {1}:{2} with local side {3}:{4}"; //$NON-NLS-1$
|
||||||
logger.info(MessageFormat.format(msg, this.connection.getId(), this.remoteInputAddressS,
|
logger.info(MessageFormat.format(msg, this.connection.getId(), this.remoteInputAddressS,
|
||||||
Integer.toString(this.remoteInputPort), this.socket.getLocalAddress().getHostAddress(),
|
Integer.toString(this.remoteInputPort), this.socket.getLocalAddress().getHostAddress(),
|
||||||
Integer.toString(this.socket.getLocalPort())));
|
Integer.toString(this.socket.getLocalPort())));
|
||||||
|
@ -325,7 +327,7 @@ public class ClientSocketEndpoint implements CommunicationEndpoint {
|
||||||
|
|
||||||
// if local output address is not set, then we will use the localhost InetAddress
|
// if local output address is not set, then we will use the localhost InetAddress
|
||||||
if (this.localOutputAddressS == null || this.localOutputAddressS.length() == 0) {
|
if (this.localOutputAddressS == null || this.localOutputAddressS.length() == 0) {
|
||||||
logger.warn("No localOutputAddress set. Using localhost"); //$NON-NLS-1$
|
logger.debug("No localOutputAddress set. Using localhost"); //$NON-NLS-1$
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// parse local output address name to InetAddress object
|
// parse local output address name to InetAddress object
|
||||||
|
@ -462,7 +464,7 @@ public class ClientSocketEndpoint implements CommunicationEndpoint {
|
||||||
if (!this.closed) {
|
if (!this.closed) {
|
||||||
logger.warn(MessageFormat.format("CommunicationConnection {0} already started.", this.connection.getId())); //$NON-NLS-1$
|
logger.warn(MessageFormat.format("CommunicationConnection {0} already started.", this.connection.getId())); //$NON-NLS-1$
|
||||||
} else {
|
} else {
|
||||||
logger.info(MessageFormat.format("Enabling connection {0}...", this.connection.getId())); //$NON-NLS-1$
|
// logger.info(MessageFormat.format("Enabling connection {0}...", this.connection.getId())); //$NON-NLS-1$
|
||||||
this.closed = false;
|
this.closed = false;
|
||||||
this.connection.notifyStateChange(ConnectionState.INITIALIZED, ConnectionState.INITIALIZED.toString());
|
this.connection.notifyStateChange(ConnectionState.INITIALIZED, ConnectionState.INITIALIZED.toString());
|
||||||
if (this.connectOnStart) {
|
if (this.connectOnStart) {
|
||||||
|
|
|
@ -187,9 +187,11 @@ public class ServerSocketEndpoint implements CommunicationEndpoint, Runnable {
|
||||||
}
|
}
|
||||||
|
|
||||||
// configure the socket
|
// configure the socket
|
||||||
msg = "BufferSize (send/read): {0} / {1} SoLinger: {2} TcpNoDelay: {3}"; //$NON-NLS-1$
|
if (logger.isDebugEnabled()) {
|
||||||
logger.info(MessageFormat.format(msg, this.socket.getSendBufferSize(),
|
msg = "BufferSize (send/read): {0} / {1} SoLinger: {2} TcpNoDelay: {3}"; //$NON-NLS-1$
|
||||||
this.socket.getReceiveBufferSize(), this.socket.getSoLinger(), this.socket.getTcpNoDelay()));
|
logger.debug(MessageFormat.format(msg, this.socket.getSendBufferSize(),
|
||||||
|
this.socket.getReceiveBufferSize(), this.socket.getSoLinger(), this.socket.getTcpNoDelay()));
|
||||||
|
}
|
||||||
//inputSocket.setSendBufferSize(1);
|
//inputSocket.setSendBufferSize(1);
|
||||||
//inputSocket.setSoLinger(true, 0);
|
//inputSocket.setSoLinger(true, 0);
|
||||||
//inputSocket.setTcpNoDelay(true);
|
//inputSocket.setTcpNoDelay(true);
|
||||||
|
@ -344,7 +346,7 @@ public class ServerSocketEndpoint implements CommunicationEndpoint, Runnable {
|
||||||
|
|
||||||
// if remote address is not set, then we will use the localhost InetAddress
|
// if remote address is not set, then we will use the localhost InetAddress
|
||||||
if (this.remoteOutputAddressS == null || this.remoteOutputAddressS.length() == 0) {
|
if (this.remoteOutputAddressS == null || this.remoteOutputAddressS.length() == 0) {
|
||||||
logger.warn("No remoteOutputAddress set. Allowing connection from any remote address"); //$NON-NLS-1$
|
logger.debug("No remoteOutputAddress set. Allowing connection from any remote address"); //$NON-NLS-1$
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// parse remote output address name to InetAddress object
|
// parse remote output address name to InetAddress object
|
||||||
|
@ -464,7 +466,7 @@ public class ServerSocketEndpoint implements CommunicationEndpoint, Runnable {
|
||||||
if (this.serverThread != null) {
|
if (this.serverThread != null) {
|
||||||
logger.warn(MessageFormat.format("CommunicationConnection {0} already started.", this.connection.getId())); //$NON-NLS-1$
|
logger.warn(MessageFormat.format("CommunicationConnection {0} already started.", this.connection.getId())); //$NON-NLS-1$
|
||||||
} else {
|
} else {
|
||||||
logger.info(MessageFormat.format("Enabling connection {0}...", this.connection.getId())); //$NON-NLS-1$
|
// logger.info(MessageFormat.format("Enabling connection {0}...", this.connection.getId())); //$NON-NLS-1$
|
||||||
this.closed = false;
|
this.closed = false;
|
||||||
|
|
||||||
this.serverThread = new Thread(this, this.connection.getId());
|
this.serverThread = new Thread(this, this.connection.getId());
|
||||||
|
@ -528,9 +530,9 @@ public class ServerSocketEndpoint implements CommunicationEndpoint, Runnable {
|
||||||
if (this.serverSocket == null || this.serverSocket.isClosed()) {
|
if (this.serverSocket == null || this.serverSocket.isClosed()) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String msg = "Opening socket on {0}:{1}..."; //$NON-NLS-1$
|
// String msg = "Opening socket on {0}:{1}..."; //$NON-NLS-1$
|
||||||
logger.info(MessageFormat.format(msg, this.localInputAddress.getHostAddress(),
|
// logger.info(MessageFormat.format(msg, this.localInputAddress.getHostAddress(),
|
||||||
Integer.toString(this.localInputPort)));
|
// Integer.toString(this.localInputPort)));
|
||||||
this.serverSocket = new ServerSocket(this.localInputPort, 1, this.localInputAddress);
|
this.serverSocket = new ServerSocket(this.localInputPort, 1, this.localInputAddress);
|
||||||
this.serverSocket.setReuseAddress(true);
|
this.serverSocket.setReuseAddress(true);
|
||||||
} catch (BindException e) {
|
} catch (BindException e) {
|
||||||
|
|
|
@ -23,6 +23,16 @@ import ch.eitchnet.communication.IoMessageVisitor;
|
||||||
|
|
||||||
public abstract class SocketMessageVisitor extends IoMessageVisitor {
|
public abstract class SocketMessageVisitor extends IoMessageVisitor {
|
||||||
|
|
||||||
|
protected final String connectionId;
|
||||||
|
|
||||||
|
public SocketMessageVisitor(String connectionId) {
|
||||||
|
this.connectionId = connectionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getConnectionId() {
|
||||||
|
return this.connectionId;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract IoMessage visit(DataInputStream inputStream, DataOutputStream outputStream) throws Exception;
|
public abstract IoMessage visit(DataInputStream inputStream, DataOutputStream outputStream) throws Exception;
|
||||||
|
|
||||||
public abstract void visit(DataInputStream inputStream, DataOutputStream outputStream, IoMessage message)
|
public abstract void visit(DataInputStream inputStream, DataOutputStream outputStream, IoMessage message)
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE log4j:configuration PUBLIC
|
||||||
|
"-//APACHE//DTD LOG4J 1.2//EN" "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">
|
||||||
|
<log4j:configuration debug="false" xmlns:log4j='http://jakarta.apache.org/log4j/'>
|
||||||
|
|
||||||
|
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
|
||||||
|
<layout class="org.apache.log4j.PatternLayout">
|
||||||
|
<param name="ConversionPattern" value="%d %5p [%t] %C{1} %M - %m%n" />
|
||||||
|
</layout>
|
||||||
|
</appender>
|
||||||
|
<appender name="FILE" class="org.apache.log4j.FileAppender">
|
||||||
|
<param name="File" value="sample.log"/>
|
||||||
|
<param name="BufferedIO" value="true" />
|
||||||
|
<param name="Append" value="true" />
|
||||||
|
<layout class="org.apache.log4j.PatternLayout">
|
||||||
|
<param name="ConversionPattern" value="%d %5p [%t] %C{1} %M - %m%n" />
|
||||||
|
</layout>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<logger name="ch.eitchnet">
|
||||||
|
<level value="info" />
|
||||||
|
</logger>
|
||||||
|
|
||||||
|
<root>
|
||||||
|
<priority value="info" />
|
||||||
|
<appender-ref ref="CONSOLE" />
|
||||||
|
<!-- appender-ref ref="FILE" / -->
|
||||||
|
</root>
|
||||||
|
|
||||||
|
</log4j:configuration>
|
|
@ -61,7 +61,7 @@ public class SocketEndpointTest extends AbstractEndpointTest {
|
||||||
parameters.put(SocketEndpointConstants.PARAMETER_CLOSE_AFTER_SEND, Boolean.TRUE.toString());
|
parameters.put(SocketEndpointConstants.PARAMETER_CLOSE_AFTER_SEND, Boolean.TRUE.toString());
|
||||||
|
|
||||||
CommunicationEndpoint endpoint = new ClientSocketEndpoint();
|
CommunicationEndpoint endpoint = new ClientSocketEndpoint();
|
||||||
SocketMessageVisitor messageVisitor = new SocketMessageVisitorExtension();
|
SocketMessageVisitor messageVisitor = new SocketMessageVisitorExtension(CLIENT_CONNECTION_ID);
|
||||||
this.clientConnection = new CommunicationConnection(CLIENT_CONNECTION_ID, ConnectionMode.ON, parameters,
|
this.clientConnection = new CommunicationConnection(CLIENT_CONNECTION_ID, ConnectionMode.ON, parameters,
|
||||||
endpoint, messageVisitor);
|
endpoint, messageVisitor);
|
||||||
this.clientConnection.configure();
|
this.clientConnection.configure();
|
||||||
|
@ -73,7 +73,7 @@ public class SocketEndpointTest extends AbstractEndpointTest {
|
||||||
parameters.put(SocketEndpointConstants.PARAMETER_LOCAL_INPUT_PORT, PORT);
|
parameters.put(SocketEndpointConstants.PARAMETER_LOCAL_INPUT_PORT, PORT);
|
||||||
|
|
||||||
CommunicationEndpoint endpoint = new ServerSocketEndpoint();
|
CommunicationEndpoint endpoint = new ServerSocketEndpoint();
|
||||||
SocketMessageVisitor messageVisitor = new SocketMessageVisitorExtension();
|
SocketMessageVisitor messageVisitor = new SocketMessageVisitorExtension(SERVER_CONNECTION_ID);
|
||||||
this.serverConnection = new CommunicationConnection(SERVER_CONNECTION_ID, ConnectionMode.ON, parameters,
|
this.serverConnection = new CommunicationConnection(SERVER_CONNECTION_ID, ConnectionMode.ON, parameters,
|
||||||
endpoint, messageVisitor);
|
endpoint, messageVisitor);
|
||||||
this.serverConnection.configure();
|
this.serverConnection.configure();
|
||||||
|
@ -114,8 +114,9 @@ public class SocketEndpointTest extends AbstractEndpointTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class SocketMessageVisitorExtension extends SocketMessageVisitor {
|
private final class SocketMessageVisitorExtension extends SocketMessageVisitor {
|
||||||
public SocketMessageVisitorExtension() {
|
|
||||||
// do nothing
|
public SocketMessageVisitorExtension(String connectionId) {
|
||||||
|
super(connectionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Reference in New Issue