Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Домашняя работа №8 #11

Merged
merged 4 commits into from
Dec 12, 2023
Merged
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Fix in homework 8
  • Loading branch information
arhostcode committed Dec 1, 2023
commit 3a1b5550837acb3cb6e28b38c422ad88df65d778
15 changes: 10 additions & 5 deletions src/main/java/edu/hw8/task1/QuotesClient.java
Original file line number Diff line number Diff line change
@@ -20,6 +20,7 @@ public QuotesClient(String address, int port) {
@SneakyThrows
public void start() {
clientChannel = SocketChannel.open(new InetSocketAddress(address, port));
clientChannel.configureBlocking(false);
}

@SneakyThrows
@@ -31,11 +32,15 @@ public String requestQuote(String message) {
@SneakyThrows
private String readFromServer() {
buffer.clear();
clientChannel.read(buffer);
buffer.flip();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
return new String(bytes, StandardCharsets.UTF_8);
StringBuilder answer = new StringBuilder();
while (clientChannel.read(buffer) > 0 || answer.isEmpty()) {
buffer.flip();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
answer.append(new String(bytes, StandardCharsets.UTF_8));
buffer.clear();
}
return answer.toString();
}

@SneakyThrows
33 changes: 25 additions & 8 deletions src/main/java/edu/hw8/task1/QuotesServer.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package edu.hw8.task1;

import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
@@ -19,7 +21,7 @@ public class QuotesServer {
private final ExecutorService executorService;
private final Semaphore parallelConnectionSemaphore;
private Consumer<String> messageConsumer;
private ServerSocket serverSocket;
private ServerSocketChannel serverSocketChannel;

public QuotesServer(int port, QuotesStorage quotesStorage, int parallelConnections) {
this.port = port;
@@ -32,11 +34,26 @@ public QuotesServer(int port, QuotesStorage quotesStorage, int parallelConnectio
@SneakyThrows
public void start() {
try (ServerSocketChannel channel = ServerSocketChannel.open()) {
serverSocket = channel.socket();
serverSocket.bind(new InetSocketAddress(port));
while (channel.isOpen()) {
if (parallelConnectionSemaphore.tryAcquire()) {
accept(channel);
serverSocketChannel = channel;
Selector selector = Selector.open();
channel.configureBlocking(false);
channel.register(selector, SelectionKey.OP_ACCEPT);
channel.bind(new InetSocketAddress(port));
processConnections(channel, selector);
}
}

@SneakyThrows
private void processConnections(ServerSocketChannel channel, Selector selector) {
while (channel.isOpen()) {
if (selector.selectNow() > 0) {
Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
if (key.isAcceptable() && parallelConnectionSemaphore.tryAcquire()) {
accept(channel);
iterator.remove();
}
}
}
}
@@ -53,8 +70,8 @@ private void accept(ServerSocketChannel channel) {

@SneakyThrows
public void stop() {
serverSocketChannel.close();
executorService.shutdownNow();
serverSocket.close();
}

public void setMessageConsumer(Consumer<String> messageConsumer) {
44 changes: 32 additions & 12 deletions src/main/java/edu/hw8/task1/QuotesServerWorker.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package edu.hw8.task1;

import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.function.Consumer;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
@@ -18,15 +21,27 @@ public class QuotesServerWorker implements Runnable {

@SneakyThrows @Override
public void run() {
Selector selector = Selector.open();
clientChannel.configureBlocking(false);
clientChannel.register(selector, SelectionKey.OP_READ);
while (clientChannel.isConnected()) {
String message = readMessageFromClient();
if (message == null) {
break;
if (selector.selectNow() > 0) {
Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
if (key.isReadable()) {
String message = readMessageFromClient();
if (message == null) {
break;
}
if (messageConsumer != null) {
messageConsumer.accept(message);
}
writeMessageToClient(quotesStorage.getQuote(message));
}
iterator.remove();
}
}
if (messageConsumer != null) {
messageConsumer.accept(message);
}
writeMessageToClient(quotesStorage.getQuote(message));
}
if (after != null) {
after.run();
@@ -36,15 +51,20 @@ public void run() {
@SneakyThrows
private String readMessageFromClient() {
try {
StringBuilder message = new StringBuilder();
int read = clientChannel.read(byteBuffer);
if (read <= 0) {
return null;
}
byteBuffer.flip();
byte[] bytesArray = new byte[byteBuffer.remaining()];
byteBuffer.get(bytesArray);
byteBuffer.clear();
return new String(bytesArray, StandardCharsets.UTF_8);
while (read > 0) {
byteBuffer.flip();
byte[] bytesArray = new byte[byteBuffer.remaining()];
byteBuffer.get(bytesArray);
message.append(new String(bytesArray, StandardCharsets.UTF_8));
byteBuffer.clear();
read = clientChannel.read(byteBuffer);
}
return message.toString();
} catch (Exception e) {
return null;
}
16 changes: 11 additions & 5 deletions src/test/java/edu/hw8/task1/QuotesTest.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package edu.hw8.task1;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import lombok.SneakyThrows;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;

public class QuotesTest {

@@ -25,11 +25,17 @@ public void quotes_shouldCorrectlyWork() {
Thread.sleep(1000);
quotesClient.start();
serverResponses.add(quotesClient.requestQuote("личности"));
serverResponses.add(quotesClient.requestQuote("оскорбления"));

Thread.sleep(1000);
quotesServer.stop();
quotesClient.close();

Assertions.assertThat(userRequests).containsExactly("личности");
Assertions.assertThat(serverResponses).containsExactly("Не переходи на личности там, где их нет");
Assertions.assertThat(userRequests).containsExactly("личности", "оскорбления");
Assertions.assertThat(serverResponses).containsExactly(
"Не переходи на личности там, где их нет",
"Если твои противники перешли на личные оскорбления, будь уверена — твоя победа не за горами"
);
}

}