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
23 changes: 23 additions & 0 deletions resources/log4j2.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<properties>
<Property name="basePath">logs</Property>
</properties>

<appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>

<File name="LogFile" fileName="${basePath}/app.log">
<PatternLayout pattern="%d{yyyy-mm-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</File>
</appenders>

<loggers>
<root level="debug">
<appender-ref ref="Console"/>
<appender-ref ref="LogFile"/>
</root>
</loggers>
</configuration>
130 changes: 130 additions & 0 deletions src/logging_testing_6/ChatServer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package logging_testing_6;


import logging_testing_6.auth.AuthService;
import logging_testing_6.auth.AuthServiceImpl;
import logging_testing_6.gui.Message;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ChatServer {

// private static final String USER_CONNECTED_PATTERN = "/userconn";
// private static final String USER_DISCONN_PATTERN = "/userdissconn";
private static final Pattern AUTH_PATTERN = Pattern.compile("^/auth (\\w+) (\\w+)$");

private AuthService authService = new AuthServiceImpl();

private Map<String, ClientHandler> clientHandlerMap = Collections.synchronizedMap(new HashMap<>());
private ExecutorService executorService;

// private static final Logger logger = LoggerFactory.getLogger(ChatServer.class);
private static final Logger log = LogManager.getLogger(ChatServer.class);

public static void main(String[] args) {
ChatServer chatServer = new ChatServer();
chatServer.start(7777);
}

public void start(int port) {
executorService = Executors.newCachedThreadPool();
try (ServerSocket serverSocket = new ServerSocket(port)) {
log.info("Server started!");
while (true) {
Socket socket = serverSocket.accept();
DataInputStream inp = new DataInputStream(socket.getInputStream());
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
log.info("New client connected!");

try {
String authMessage = inp.readUTF();
Matcher matcher = AUTH_PATTERN.matcher(authMessage);
if (matcher.matches()) {
String username = matcher.group(1);
String password = matcher.group(2);
if (authService.authUser(username, password)) {
clientHandlerMap.put(username, new ClientHandler(username, socket, this));
out.writeUTF("/auth successful");
out.flush();
broadcastUserConnected();

log.info("Authorization for user {} %s successful", username);
} else {
log.info("Authorization for user {} failed", username);
out.writeUTF("/auth fails");
out.flush();
socket.close();
}
} else {
log.info("Incorrect authorization message {}", authMessage);
out.writeUTF("/auth fails");
out.flush();
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Стоит добавить логирование ошибок

}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// authService.close();
executorService.shutdown();
}
}

public void sendMessage(String userTo, String userFrom, String msg) throws IOException {
ClientHandler userToClientHandler = clientHandlerMap.get(userTo);
if (userToClientHandler != null) {
userToClientHandler.sendMessage(userFrom, msg);
} else {
log.debug("User {} not found. Message from {} is lost.", userTo, userFrom);
}
}

public ExecutorService getExecutorService() {
return executorService;
}

public void sendMessage(Message message) throws IOException {
String userTo = message.getUserTo();
String userFrom = message.getUserFrom();
String msg = message.getText();
ClientHandler userToClientHandler = clientHandlerMap.get(userTo);
if (userToClientHandler != null) {
userToClientHandler.sendMessage(userFrom, msg);
} else {
log.debug("User {} not found. Message from {} is lost.", userTo, userFrom);
}
}

public List<String> getUserList() {
return new ArrayList<>(clientHandlerMap.keySet());
}

public void unsubscribeClient(ClientHandler clientHandler) {
clientHandlerMap.remove(clientHandler.getUsername());
broadcastUserDisconnected();
}

public void broadcastUserConnected() {
// TODO сообщать о том, что конкретный пользователь подключился
}

public void broadcastUserDisconnected() {
// TODO сообщать о том, что конкретный пользователь отключился
}
}
77 changes: 77 additions & 0 deletions src/logging_testing_6/ClientHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package logging_testing_6;

import logging_testing_6.gui.Message;
import logging_testing_6.history.HistoryKeeper;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class ClientHandler {

private static final Pattern MESSAGE_PATTERN = Pattern.compile("^/w (\\w+) (.+)", Pattern.MULTILINE);
private static final String MESSAGE_SEND_PATTERN = "/w %s %s";
private static final Logger log = LogManager.getLogger(ClientHandler.class);


// private final Thread handleThread;
private final DataInputStream inp;
private final DataOutputStream out;
private final ChatServer server;
private final String username;
private final Socket socket;

public ClientHandler(String username, Socket socket, ChatServer server) throws IOException {
this.username = username;
this.socket = socket;
this.server = server;
this.inp = new DataInputStream(socket.getInputStream());
this.out = new DataOutputStream(socket.getOutputStream());

server.getExecutorService().submit(() -> {
try {
while (!Thread.currentThread().isInterrupted()) {
String msg = inp.readUTF();
log.info("Message from user {}: {}", username, msg);

Matcher matcher = MESSAGE_PATTERN.matcher(msg);
if (matcher.matches()) {
String userTo = matcher.group(1);
String messageText = matcher.group(2);
Message message = new Message(username, userTo, messageText);
server.sendMessage(message);

// Добавляем сообщения в файл истории отправителя
HistoryKeeper.saveMassageToHistoryFrom(message);
// Добавляем сообщения в файл истории получателя
HistoryKeeper.saveMassageToHistoryTo(message);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
log.info("Client {} disconnected", username);
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
server.unsubscribeClient(ClientHandler.this);
}
});
}

public void sendMessage(String userTo, String msg) throws IOException {
out.writeUTF(String.format(MESSAGE_SEND_PATTERN, userTo, msg));
}

public String getUsername() {
return username;
}
}
6 changes: 6 additions & 0 deletions src/logging_testing_6/auth/AuthService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package logging_testing_6.auth;

public interface AuthService {

boolean authUser(String username, String password);
}
13 changes: 13 additions & 0 deletions src/logging_testing_6/auth/AuthServiceImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package logging_testing_6.auth;

import logging_testing_6.dbconn.JdbcExample;

public class AuthServiceImpl implements AuthService {

@Override
public boolean authUser(String username, String password) {
String pwd = JdbcExample.readFromDB(username);

return pwd != null && pwd.equals(password);
}
}
44 changes: 44 additions & 0 deletions src/logging_testing_6/dbconn/JdbcExample.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package logging_testing_6.dbconn;

import java.sql.*;

public class JdbcExample {
private static final String URL = "jdbc:sqlite:database.db";

static {
try {
Class.forName("org.sqlite.JDBC");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}

public static String readFromDB(String clientName) {
String password = null;
try (Connection connection = DriverManager.getConnection(URL)) {
PreparedStatement preparedStatement = connection.prepareStatement("SELECT u.name, p.password FROM users u INNER JOIN passwords p on u.id = p.id WHERE u.name = ?");
preparedStatement.setString(1, clientName);
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
// String name = resultSet.getString("name");
password = resultSet.getString("password");
}
} catch (SQLException e) {
e.printStackTrace();
}
System.out.println("returned password: " + password);
return password;
}

public static void changeNick(String oldName, String newName) {
try (Connection connection = DriverManager.getConnection(URL)) {
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE users SET name = ? WHERE name = ?;");
preparedStatement.setString(1, newName);
preparedStatement.setString(2, oldName);
preparedStatement.executeUpdate();
System.out.println("Name " + oldName + " changed to: " + newName);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
17 changes: 17 additions & 0 deletions src/logging_testing_6/gui/App.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package logging_testing_6.gui;

import javax.swing.*;

public class App {

private static MainWindow mainWindow;

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
mainWindow = new MainWindow();
}
});
}
}
4 changes: 4 additions & 0 deletions src/logging_testing_6/gui/AuthException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package logging_testing_6.gui;

public class AuthException extends RuntimeException {
}
Loading