Прерывание Java DataInputStream читаемо()
у меня есть Java-апплет, который транслирует видео (MJPEG) с сервера. Я написал прокси-сервер на C# (служба Windows), чтобы поместить между апплетом и несколькими видеосерверами. Интерфейс HTML/CSS/Js используется вместе с апплетом Java. Все функции работают нормально (наконец!!!), за исключением одного.
видеосервер позволяет воспроизводить записанное видео через интерфейс REST. Когда клип закончен, сервер оставляет соединение открытым, если вы хотите отправить ему команды как перемотка назад или поиск. Клип воспроизводится в апплете до конца. При попытке запустить новый клип (что влечет за собой отправку команды из Javscript в апплет) браузер зависает. Однако последующие команды, которые будут использовать одно и то же соединение, такие как play, pause и seek. Если я остановлю службу windows, браузер снова станет отзывчивым.
это я предполагая, что происходит: клип заканчивается (или приостанавливается); больше нет данных отправил, но соединение все еще активно. Апплет ждет на прокси для следующего кадра, но прокси ждет на видеосервере для следующего кадра, который не собирается отправлять больше данных.
это код в цикле while, который считывает каждый кадр
byte[] img = new byte[mContentLength];
inputStream.skipBytes(headerLen);
inputStream.readFully(img);
мне нужно как-то прервать этот код.
когда новый видеоклип выбран в интерфейсе HTML, мы уведомляем апплет, который вызывает disconnect () в классе CameraStream. Это функции:
// DataInputStream inputStream
// HttpURLConnection conn
public void disconnect() {
System.out.println("disconnect called.");
if(running) {
running = false;
try {
// close the socket
if(inputStream != null) {
inputStream.close();
}
if(conn != null) {
conn.disconnect();
}
inputStream = null;
System.out.println("closed.");
} catch(Exception ignored) {
System.out.println("exc:" + ignored.getMessage());
main.reportErrorFromThrowable(ignored);
}
}
}
чтобы проверить это, я позволил быстрому клипу играть и бежать до конца. Затем я выбираю новый клип. В моей консоли Java я получаю вывод disconnect called.
но я не понимаю последующем closed.
сообщение, и это общее исключение не ловится. Когда я останавливаю службу Windows, я, наконец, получаю closed.
сообщение, так что это похоже на inputStream.close();
блокирует.
Итак, я думаю, мой вопрос в том, как я могу остановить блокировку? Это readFully(img)
блокировка вызова? Или это отключите функцию (как предложено консольным выходом, который я получаю)?
edit: чтобы уточнить, я написал Java-апплет, HTML, CSS, Javascript и прокси-сервер C#, поэтому у меня есть доступ ко всему этому коду. Единственный код, который я не могу изменить, - это интерфейс REST на видеосервере.
edit2: я имел в виду, чтобы сделать баунти за этот пост https://stackoverflow.com/questions/12219758/proxy-design-pattern
2 ответов
в общем случае блок методов ввода-вывода Java. Лучшим решением, по-видимому, является создание другого потока для чтения данных и использования буферов NIO. Пример чтения на основе NIO (предупреждение: непроверено!):
// get the InputStream from somewhere (a queue possibly)
ReadableByteChannel inChannel = Channels.newChannel(inputStream);
ByteBuffer buf = ByteBuffer.allocate(mContentLength + headerLen);
inChannel.read(buf);
byte[] img = new byte[mContentLength];
inChannel.get(img, headerLen, mContentLength);
этот код создает Channel
С InputStream
и использует Channel
для чтения данных. JavaDoc для ReadableByteChannel.read(ByteBuffer)
функция говорит, что прерывание потока, содержащего вызов inChannel.read(buf)
перестанут читать.
вам придется адаптировать этот код, я просто вытащил это вылетело у меня из головы. Удачи!
Я наконец нашел ответ:
public void disconnect() {
if(running) {
running = false;
try {
try{
// had to add this
conn.getOutputStream().close();
}
catch(Exception exc){
}
// close the socket
if(inputStream != null) {
inputStream.close();
}
if(conn != null) {
conn.disconnect();
}
inputStream = null;
} catch(Exception ignored) {
main.reportErrorFromThrowable(ignored);
}
}
}
хотя я использую HttpUrlConnection, который является одним из способов и не имеет выходного потока, попытка закрыть выходной поток вызвала исключение и по какой-то причине заставила все это работать.