Java Socket HTTP Server замедляется при подключении нескольких клиентов

-4

Я делаю M-JPEG Server на Android, и я успешно его реализовал, но у меня возникла проблема:

В первый раз, когда я подключаюсь к нему (используя браузер для подключения), поток хорош, и я получаю предварительный просмотр в режиме реального времени, но открывая новый клиент (например, перезагружая страницу или открывая новую вкладку), поток получает медленнее и медленнее. Даже если я закрываю предыдущий клиент, он не улучшает производительность.

Я пробовал другие M-JPEG Android Streamers (например, myMobKit), он не замедляется.

Вот мой код сервера -

public class StreamServer implements Runnable {
public static Stack<byte[]> bufferStack;
...
public StreamServer(int port) {
...
bufferStack = new Stack<>();
bufferStack.setSize(100);
}
public void start() {
new Thread(this).start();
}
...
@Override
public void run() {
try {
serverSocket = new ServerSocket(port);
while (isRunning) {
Socket socket = serverSocket.accept();
new Thread(new StreamSocket(socket)).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void addBufferToStack(byte[] buffer) {
bufferStack.push(buffer);
}
}

... И реализация Socket -

public class StreamSocket implements Runnable {

private Stack<byte[]> bufferStack = StreamServer.bufferStack;
...
StreamSocket(Socket socket) throws SocketException {
this.socket = socket;
this.socket.setTcpNoDelay(true);
this.socket.setKeepAlive(false);
...
}
@Override
public void run() {
if (!isStreaming) return;
PrintStream output = null;
try {
output = new PrintStream(socket.getOutputStream());
// Sent the initial header for M-JPEG.
...
// Start the loop for sending M-JPEGs
while (isStreaming && !socket.isClosed() && socket.isConnected()) {
try {
if (bufferStack.empty()) continue;
byte[] buffer = bufferStack.pop();
if (buffer == null) continue;
... (Some headers needed for M-JPEG streaming. Read it on Wikipedia)
output.write(buffer);
} catch (Exception e) {
e.printStackTrace();
}
}
output.flush();
output.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (output != null) output.close();
if (!socket.isClosed() || socket.isConnected()) socket.close();
isStreaming = false;
socket = null;
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

addBufferToStack(...) вызывается при создании нового JPEG (кадр предварительного просмотра камеры берется и обрабатывается в JPG через собственный код).

Я думаю, что Socket Thread не закрыт даже после отсоединения клиента, хотя я не уверен. Пожалуйста, помогите в этом, спасибо!

Если вам нужна другая информация/код, скажите, я отредактирую вопрос и добавлю его.

РЕДАКТИРОВАТЬ -

bufferStack не пуст при запуске сервера. Сервер запускается после камеры + еще несколько вещей.

спросил(а) 2017-03-14T14:00:00+03:00 3 года, 11 месяцев назад
0
61

Ваш цикл будет продолжать цикл, даже если другая сторона завершает соединение: (обратите внимание на мои комментарии)

while (isStreaming && !socket.isClosed() && socket.isConnected()) {
try {
if (bufferStack.empty()) continue;
byte[] buffer = bufferStack.pop();
if (buffer == null) continue;
... (Some headers needed for M-JPEG streaming. Read it on Wikipedia)
output.write(buffer); // <-- will throw Exception if connection is broken
} catch (Exception e) {
e.printStackTrace(); // here you should also reset isStreaming
}
}

Улавливая Исключение (и не обрабатывая его на самом деле), вы увольняете информацию о том, что соединение ушло.

Проверка isConnected поскольку условие цикла является избыточным - оно всегда будет истинным, если сокет один раз был подключен. См. Https://docs.oracle.com/javase/8/docs/api/java/net/Socket.html#isConnected--:

Примечание. Закрытие сокета не очищает его состояние соединения, что означает, что этот метод вернет true для закрытого сокета (см. IsClosed()), если он был успешно подключен до закрытия.

В настоящее время я не уверен на 100% о поведении isClosed но я твердо верю, что это вернется, когда вы isClosed close, а не в том случае, если базовый поток генерирует исключение IOException.

ответил(а) 2017-03-14T14:30:00+03:00 3 года, 11 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема