Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions OWNER.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
MAXIM
6 changes: 2 additions & 4 deletions client.xml
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
<root>

<bean id="protocol" class="arhangel.dim.core.net.StringProtocol"/>

<bean id="client" class="arhangel.dim.client.Client">
<property name="port" val="19000"/>
<property name="port" val="8000"/>
<property name="host" val="localhost"/>
<property name="protocol" ref="protocol"/>
<property name="protocol" ref="StringProtocol"/>
</bean>

</root>
Binary file added logs/application.log
Binary file not shown.
11 changes: 2 additions & 9 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
<artifactId>exec-maven-plugin</artifactId>
<version>1.4.0</version>
<configuration>
<mainClass>arhangel.dim.lections.jdbc.JdbcExample</mainClass>
<mainClass>arhangel.dim.container.Application</mainClass>
</configuration>
</plugin>
<plugin>
Expand Down Expand Up @@ -84,17 +84,10 @@
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc</artifactId>
<version>14</version>
<scope>system</scope>
<systemPath>${basedir}/lib/ojdbc6.jar</systemPath>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.4-1204-jdbc42</version>
<version>9.4-1201-jdbc41</version>
</dependency>
</dependencies>

Expand Down
178 changes: 142 additions & 36 deletions src/main/java/arhangel/dim/client/Client.java
Original file line number Diff line number Diff line change
@@ -1,23 +1,31 @@
package arhangel.dim.client;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Arrays;
import java.util.Scanner;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import arhangel.dim.container.Container;
import arhangel.dim.container.InvalidConfigurationException;
import arhangel.dim.container.exceptions.InvalidConfigurationException;
import arhangel.dim.core.messages.InfoMessage;
import arhangel.dim.core.messages.ListChatResultMessage;
import arhangel.dim.core.messages.Message;
import arhangel.dim.core.messages.StatusMessage;
import arhangel.dim.core.messages.TextMessage;
import arhangel.dim.core.messages.Type;
import arhangel.dim.core.messages.CreateChatMessage;
import arhangel.dim.core.messages.LoginMessage;
import arhangel.dim.core.net.ConnectionHandler;
import arhangel.dim.core.net.Protocol;
import arhangel.dim.core.net.ProtocolException;
import arhangel.dim.core.net.StringProtocol;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
import java.util.stream.Collectors;

/**
* Клиент для тестирования серверного приложения
Expand All @@ -26,13 +34,12 @@ public class Client implements ConnectionHandler {

/**
* Механизм логирования позволяет более гибко управлять записью данных в лог (консоль, файл и тд)
* */
*/
static Logger log = LoggerFactory.getLogger(Client.class);

/**
* Протокол, хост и порт инициализируются из конфига
*
* */
*/
private Protocol protocol;
private int port;
private String host;
Expand All @@ -41,13 +48,16 @@ public class Client implements ConnectionHandler {
* Тред "слушает" сокет на наличие входящих сообщений от сервера
*/
private Thread socketThread;
private Socket socket;

/**
* С каждым сокетом связано 2 канала in/out
*/
private InputStream in;
private OutputStream out;

private Long userId;

public Protocol getProtocol() {
return protocol;
}
Expand All @@ -72,10 +82,26 @@ public void setHost(String host) {
this.host = host;
}

public static int CONNECTION_TIMEOUT_SECONDS = 10;

public void initSocket() throws IOException {
Socket socket = new Socket(host, port);
in = socket.getInputStream();
out = socket.getOutputStream();
log.info("Создание сетевого подключения: " + host + ":" + port);
try {
Socket socket = new Socket(host, port);
in = socket.getInputStream();
out = socket.getOutputStream();
} catch (ConnectException error) {
log.error("Невозможно установить подключение, " +
"следующая попытка через " + CONNECTION_TIMEOUT_SECONDS + " секунд");
try {
Thread.sleep(CONNECTION_TIMEOUT_SECONDS * 1000L);
} catch (InterruptedException e) {
throw new IOException(e);
}

initSocket();
return;
}

/**
* Инициализируем поток-слушатель. Синтаксис лямбды скрывает создание анонимного класса Runnable
Expand All @@ -87,15 +113,14 @@ public void initSocket() throws IOException {
try {
// Здесь поток блокируется на ожидании данных
int read = in.read(buf);
if (read > 0) {

// По сети передается поток байт, его нужно раскодировать с помощью протокола
if (read > 0) {
log.info("< New Message received >");
Message msg = protocol.decode(Arrays.copyOf(buf, read));
onMessage(msg);
}
} catch (Exception e) {
log.error("Failed to process connection: {}", e);
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
Expand All @@ -109,7 +134,38 @@ public void initSocket() throws IOException {
*/
@Override
public void onMessage(Message msg) {
log.info("Message received: {}", msg);
switch (msg.getType()) {
case MSG_STATUS:
StatusMessage msgStatus = (StatusMessage) msg;
log.info(msgStatus.getStatus());
System.out.println(msgStatus.getStatus());
break;
case MSG_CHAT_LIST_RESULT:
ListChatResultMessage msgChatListResult = (ListChatResultMessage) msg;
if (msgChatListResult.getChatIds().size() == 0) {
log.info("У вас нет активных чатов в данный момент");
} else {
log.info("Ваши активные чаты: " + String.join(",", msgChatListResult.getChatIds().stream()
.map(Object::toString)
.collect(Collectors.toList())));
}
System.out.println("Ваши активные чаты: " + String.join(",", msgChatListResult.getChatIds().stream()
.map(Object::toString)
.collect(Collectors.toList())));
break;
case MSG_INFO:
InfoMessage infoMessage = (InfoMessage) msg;
log.info(infoMessage.getInfo());
break;
case MSG_TEXT:
log.info(msg.toString());
System.out.println(msg.toString());
break;
default:
log.error("Данный тип сообщений не поддерживается");
System.err.println("Полученный тип сообщений не поддерживается");
break;
}
}

/**
Expand All @@ -122,22 +178,62 @@ public void processInput(String line) throws IOException, ProtocolException {
String cmdType = tokens[0];
switch (cmdType) {
case "/login":
// TODO: реализация
if (tokens.length != 3) {
log.error("Неправильное использование команды");
break;
}
LoginMessage loginMessage = new LoginMessage();
loginMessage.setLogin(tokens[1]);
loginMessage.setPassword(tokens[2]);
send(loginMessage);
break;
case "/help":
// TODO: реализация
log.info(
"login <имя пользователя> <пароль> - выполнить вход\n" +
"help - справка по месседжеру\n" +
"text <id чата> <сообщение> - отправить сообщение в чат с заданным id\n" +
"info <id пользователя> - получить информациию о пользователе\n" +
"info - получить информациию о себе\n" +
"chat_create <user id list> - создать новый чат " +
"(использование: chat_create 1, 2, 3, 66)\n"
);
break;
case "/text":
// FIXME: пример реализации для простого текстового сообщения
if (tokens.length != 3) {
log.error("Неправильное использование команды");
break;
}
TextMessage sendMessage = new TextMessage();
sendMessage.setType(Type.MSG_TEXT);
sendMessage.setText(tokens[1]);
sendMessage.setChatId(Long.parseLong(tokens[1]));
sendMessage.setText(tokens[2]);
send(sendMessage);
break;
// TODO: implement another types from wiki

case "/info":
InfoMessage infoMessage = new InfoMessage();
if (tokens.length > 1) {
infoMessage.setUserId(Long.parseLong(tokens[1]));
} else {
infoMessage.setUserId(-1);
}
infoMessage.setInfo(null);
send(infoMessage);
break;
case "/chat_create":
CreateChatMessage createChatMessage = new CreateChatMessage();
String[] userIdsStr = tokens[1].split(",");
List<Long> userIds = new ArrayList<>();
for (String anUserIdsStr : userIdsStr) {
userIds.add(Long.parseLong(anUserIdsStr));
}
createChatMessage.setUsersIds(userIds);
send(createChatMessage);
break;
case "/chat_hist":
//TODO: Доделать
case "/chat_list":
//TODO: Доделать
default:
log.error("Invalid input: " + line);
log.error("Команда не найдена: " + line);
}
}

Expand All @@ -146,23 +242,33 @@ public void processInput(String line) throws IOException, ProtocolException {
*/
@Override
public void send(Message msg) throws IOException, ProtocolException {
log.info(msg.toString());
log.info("< Sending new message >");
out.write(protocol.encode(msg));
out.flush(); // принудительно проталкиваем буфер с данными
out.flush();
}

@Override
public void close() {
// TODO: написать реализацию. Закройте ресурсы и остановите поток-слушатель
public void close() throws IOException {
log.error("Closing socket...");
if (!socketThread.isInterrupted()) {
socketThread.interrupt();
}

if (!socket.isClosed()) {
socket.close();
}
}

public static void main(String[] args) throws Exception {

Client client = null;
Client client;
// Пользуемся механизмом контейнера
//TODO: or not o:
try {
Container context = new Container("client.xml");
client = (Client) context.getByName("client");
//TODO FIX
client.setProtocol(new StringProtocol());
} catch (InvalidConfigurationException e) {
log.error("Failed to create client", e);
return;
Expand All @@ -175,7 +281,7 @@ public static void main(String[] args) throws Exception {
System.out.println("$");
while (true) {
String input = scanner.nextLine();
if ("q".equals(input)) {
if ("exit".equals(input)) {
return;
}
try {
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/arhangel/dim/container/Application.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package arhangel.dim.container;

/**
* Created by spec45as on 3/23/2016.
*/
public class Application {
public static void main(String[] args) {
System.out.println("Container Application");
}
}
Loading