Здравствуйте, lexius, Вы писали:
L>Нужно запретить запуск нескольких копий одного и того же приложения, подскажите как это сделать. Есть мысль через сокеты сделать....
lexius wrote:
> Нужно запретить запуск нескольких копий одного и того же приложения, > подскажите как это сделать. Есть мысль через сокеты сделать....
Можно также создавать файл во временной директории, и держать его
открытым пока работает приложение. При запуске проверять наличие этого
файла, если есть — пытаться удалить. Если не получилось — работает
другой инстанс.
По сравнению с сокетами:
+ Вероятность ложного срабатывания меньше.
— Послать сообщение работающему приложению нельзя.
В конечном итоге мы использовали и сокеты, и файлы.
Posted via RSDN NNTP Server 2.0
Re[2]: Как реализовать проверку - запущено приложение или не
Здравствуйте, Gurney, Вы писали:
G>lexius wrote:
>> Нужно запретить запуск нескольких копий одного и того же приложения, >> подскажите как это сделать. Есть мысль через сокеты сделать....
G>Можно также создавать файл во временной директории, и держать его G>открытым пока работает приложение. При запуске проверять наличие этого G>файла, если есть — пытаться удалить. Если не получилось — работает G>другой инстанс.
под unix-подобными не сработает.
G>По сравнению с сокетами: G>+ Вероятность ложного срабатывания меньше. G>- Послать сообщение работающему приложению нельзя.
G>В конечном итоге мы использовали и сокеты, и файлы.
С уважением,
Александр.
icq: 118852038
Re[2]: Как реализовать проверку - запущено приложение или не
Здравствуйте, Gurney, Вы писали:
G>lexius wrote:
>> Нужно запретить запуск нескольких копий одного и того же приложения, >> подскажите как это сделать. Есть мысль через сокеты сделать....
G>Можно также создавать файл во временной директории, и держать его G>открытым пока работает приложение. При запуске проверять наличие этого G>файла, если есть — пытаться удалить. Если не получилось — работает G>другой инстанс.
под unix-подобными системами сработает?
G>По сравнению с сокетами: G>+ Вероятность ложного срабатывания меньше. G>- Послать сообщение работающему приложению нельзя.
G>В конечном итоге мы использовали и сокеты, и файлы.
С уважением,
Александр.
icq: 118852038
Re[3]: Как реализовать проверку - запущено приложение или не
Alexandro wrote:
> G>Можно также создавать файл во временной директории, и держать его > G>открытым пока работает приложение. При запуске проверять наличие этого > G>файла, если есть — пытаться удалить. Если не получилось — работает > G>другой инстанс. > под unix-подобными системами сработает?
Описанный алгоритм — нет. На *nix-ах действительно вместо попытки удаления
нужно пытаться захватить блокировку через FileLock.
Posted via RSDN NNTP Server 2.0
Re[3]: Как реализовать проверку - запущено приложение или не
Blazkowicz wrote: > Можно про вероятность ложного срабатывания поподробнее? Это откуда она? > Если порт занят уже кем-то другим? Так это через обмен сообщениями и > решается.
Допустим у вас на компьютере стоит некое приложение которое агрессивно
использует порты. Это могу быть IM-ры, P2P, традиционные сервера и т.д.
Если программа проверяет наличие другого инстанса по наличию открытого
порта, а этот порт уже занят др. процессом, то имеем ложное срабатывание
механизма ограничения повторного запуска. Конечно, это можно обойти
попыткой обмена сообщениями, но:
1. Если мы определили, что порт открыт, но не нашим приложением, что
делать дальше? Попытаться открыт другой порт? Но тогда нужно как-то
сообщить всем, что искать нужно на др. порту. Если через файл свойтсв,
то мы опять вернулись к связке файл с блокировкой/сокет.
2. Есть один довольно неприятный баг MS Firewall Client (в 2006-м, его
поправили), в результате которого Java приложения не могут открывать
серверные сокеты на 0.0.0.0. В результате, вполне может оказаться, что
ваше приложение не отвечает на условленному порту просто из-за того, что
оно просто не смогло открыть сокет. Сюда можно добавить возможные
проблемы с др. personal файрволами.
Posted via RSDN NNTP Server 2.0
Re[4]: Как реализовать проверку - запущено приложение или не
Здравствуйте, Gurney, Вы писали:
G>1. Если мы определили, что порт открыт, но не нашим приложением, что G>делать дальше? Попытаться открыт другой порт? Но тогда нужно как-то G>сообщить всем, что искать нужно на др. порту. Если через файл свойтсв, G>то мы опять вернулись к связке файл с блокировкой/сокет.
Зачем сообщать? Просто надо итерироватся дальше по номеру порта (или забить список предефайненых возможных портов)
На каждой итерации:
Если порт свободен — запускатся
Если порт занят — попытатся связатся с предыдущим экземпляром себя
Если ответили — закрываемся с чистой совестью
Если не ответили — повотряем итерацию для следующего порта.
В этой схеме есть ошибки?
G>2. Есть один довольно неприятный баг MS Firewall Client (в 2006-м, его G>поправили), в результате которого Java приложения не могут открывать G>серверные сокеты на 0.0.0.0. В результате, вполне может оказаться, что G>ваше приложение не отвечает на условленному порту просто из-за того, что G>оно просто не смогло открыть сокет. Сюда можно добавить возможные G>проблемы с др. personal файрволами.
Да, про firewall не подумал. Спасибо.
Re[3]: Как реализовать проверку - запущено приложение или не
Blazkowicz пишет:
> Можно про вероятность ложного срабатывания поподробнее? Это откуда она? > Если порт занят уже кем-то другим? Так это через обмен сообщениями и > решается.
Могу предположить ситуацию с работающим файерволом — может быть
запрещено порт открыть или отправить сообщение.
Posted via RSDN NNTP Server 2.0
Punk Not Dead
Re[5]: Как реализовать проверку - запущено приложение или не
Blazkowicz wrote:
> Если порт свободен — запускатся > Если порт занят — попытатся связатся с предыдущим экземпляром себя > Если ответили — закрываемся с чистой совестью > Если не ответили — повотряем итерацию для следующего порта. > > В этой схеме есть ошибки?
Очевидных проблем нет. Однако что-то мне в таком методе стрельбы
по квадратам не нравится. Хотя конечно случай сильно вырожденный
и вероятность наведенного сбоя достаточно низкая.
> Да, про firewall не подумал. Спасибо.
Плс.
Posted via RSDN NNTP Server 2.0
Re[5]: Как реализовать проверку - запущено приложение или не
Здравствуйте, Blazkowicz, Вы писали:
B>Здравствуйте, Gurney, Вы писали:
G>>1. Если мы определили, что порт открыт, но не нашим приложением, что G>>делать дальше? Попытаться открыт другой порт? Но тогда нужно как-то G>>сообщить всем, что искать нужно на др. порту. Если через файл свойтсв, G>>то мы опять вернулись к связке файл с блокировкой/сокет. B>Зачем сообщать? Просто надо итерироватся дальше по номеру порта (или забить список предефайненых возможных портов) B>На каждой итерации: B>Если порт свободен — запускатся B>Если порт занят — попытатся связатся с предыдущим экземпляром себя B>Если ответили — закрываемся с чистой совестью B>Если не ответили — повотряем итерацию для следующего порта.
B>В этой схеме есть ошибки?
Ну можно предположить такой вариант развития событий для выделеной выше части:
Для приложения есть порт 100 и посделующие определяются итерированием.
Пусть p2p использует для закачки 100. Порт 101 свободен.
1. Приложение запускается. Порт 100 занят не нами — вешаемся на 101.
2. Закачка p2p завершается — порт 100 освобождается.
3. Второе приложение запускается. Порт 100 свободен и получаем второй инстанс.
IMHO, выход — ограниченный набор портов, которые будут сканироваться для проверки приложения на выполнение.
Здравствуйте, lexius, Вы писали:
L>Нужно запретить запуск нескольких копий одного и того же приложения, подскажите как это сделать. Есть мысль через сокеты сделать....
Может через еще один компьютер-сервер, который будет регистрировать запущенные приложения.
При запуске приложение отправляет запрос серверу, на которое сервер отвечает ответом о возможности запуска.
Re[6]: Как реализовать проверку - запущено приложение или не
Здравствуйте, xBlackCat, Вы писали:
BC>IMHO, выход — ограниченный набор портов, которые будут сканироваться для проверки приложения на выполнение.
Чего-то я не понимаю, а почему бы просто не записывать захваченный порт в файл настроек? Второй инстанс прочитает файл и проверит этот порт, если он свободен — значит можно запускаться.
Cider
Re[5]: Как реализовать проверку - запущено приложение или не
Blazkowicz wrote:
> Да, про firewall не подумал. Спасибо.
Ещё подумай про многопользовательские ОС. Если на серваке (почти любой unix или Win TS) сидят два юзера и один из них
запустил аппликуху, другой уже не сможет, т.к. порты вещь глобальная на хост... уж лучше файлы в профиле юзера.
Если файловая система не поддерживает лочку, то в файл можно сохранить PID и проверять наличие процесса с данным PID.
Posted via RSDN NNTP Server 2.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[2]: Как реализовать проверку - запущено приложение или не
Здравствуйте, _Oleg_, Вы писали:
_O_>Здравствуйте, lexius, Вы писали:
_O_>Может через еще один компьютер-сервер, который будет регистрировать запущенные приложения. _O_>При запуске приложение отправляет запрос серверу, на которое сервер отвечает ответом о возможности запуска.
И делать это надо по http, чтобы не было проблем с файерволами.
Re[7]: Как реализовать проверку - запущено приложение или не
Здравствуйте, Cider, Вы писали:
C>Чего-то я не понимаю, а почему бы просто не записывать захваченный порт в файл настроек? Второй инстанс прочитает файл и проверит этот порт, если он свободен — значит можно запускаться.
захват порта и запись в файл не удастся реализовать атомарной операцией
Re: Как реализовать проверку - запущено приложение или нет?
Я таки реализовал через сокеты и после нескольких дней тестирования сделал неутешительный вывод — работает не всегда. Я так и не понял от чего оно зависит, но иногда второй экземпляр таки можно запустить. Пробовал на разных портах и т.п. — все равно иногда запускается вторая копия.
Сделал через lock файла. теперь тестирую.
private File getAppFile() {
return new File(AnuranUtils.getAnuranHomePath(), "anuran.lock");
}
private void lockInstance() throws IOException {
File appFile = getAppFile();
if (!appFile.exists()) {
appFile.createNewFile();
}
RandomAccessFile userAppFile = new RandomAccessFile(appFile, "rw");
FileChannel channel = userAppFile.getChannel();
FileLock lock = channel.tryLock();
if (lock == null) throw new IOException();
appFile.deleteOnExit();
}
Перед выходом файлик удаляю, дабы не мусолить им глаза (хотя...), но если выход будет некорректным — ничего страшного не случится.
Но мне все же интересно, чего при реализации через ServerSocket не работало?
Я использую jdk6, но не думаю, что дело в ней, как никак beta2 уже.
Метод не работал как под linux так и под windows. Может кто в курсе?