Перейти к содержанию
  • Регистрация

Вопрос

Здравствуйте! Уже почти неделю пытаюсь завести библиотеку org.eclipse.paho.client.mqttv3-1.2.0 в своём приложении. Я знаю о существовании компонента от TMS, но он не умеет работать в фоновом сервисе.
Вот код который я использую для тестов:
 

Спойлер

unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, System.Android.Service,
  FMX.Controls.Presentation, FMX.StdCtrls, Androidapi.JNI.App, Androidapi.JNI.GraphicsContentViewText,
  Androidapi.Helpers, JavaInterfaces, System.Notification, Androidapi.JNI.JavaTypes,
  Androidapi.JNIBridge, System.IOUtils;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    NotificationCenter1: TNotificationCenter;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}
{$R *.LgXhdpiPh.fmx ANDROID}

procedure TForm1.Button1Click(Sender: TObject);
begin
 TLocalServiceConnection.StartService('serviceTest2Service');
end;

procedure TForm1.Button2Click(Sender: TObject);
var
LIntent: JIntent;
begin
 LIntent := TJIntent.Create;
  LIntent.setClassName(TAndroidHelper.Context.getPackageName(), TAndroidHelper.StringToJString('com.embarcadero.services.serviceTest2Service'));
  TAndroidHelper.Activity.stopService(LIntent);
end;

procedure TForm1.Button3Click(Sender: TObject);
var
MyNotification: TNotification;
mqtt:JMqttClient;
mqttconopt:JMqttConnectOptions;
//presistance:JMqttDefaultFilePersistence;
jstr:jstring;
//context:JContext;
patch:tpath;
begin
MyNotification := NotificationCenter1.CreateNotification;
  MyNotification.Title := 'Service';  //заголовок
  MyNotification.AlertBody := (patch.GetPublicPath);//текст
  //MyNotification.Name:='Notification Name';
  MyNotification.EnableSound:=True;
  //presistance:=TJMqttDefaultFilePersistence.JavaClass.init(StringToJString(patch.GetPublicPath));
  NotificationCenter1.PresentNotification(MyNotification);
  mqtt:=TJMqttClient.JavaClass.init(StringToJString('tcp://m23.cloudmqtt.com:11021'), StringToJString('java'));
  //MyNotification.AlertBody := '2';//текст
  //NotificationCenter1.PresentNotification(MyNotification);
  mqttconopt:=TJMqttConnectOptions.JavaClass.init();
  //MyNotification.AlertBody := '3';//текст
  //NotificationCenter1.PresentNotification(MyNotification);
  mqttconopt.setUserName(StringToJString('wfntgpvq'));
  jstr:=StringToJString('MWPri3WtH_QZ');
  mqttconopt.setPassword(jstr.toCharArray);
  mqttconopt.setAutomaticReconnect(True);
  mqttconopt.setCleanSession(false);
  //MyNotification.AlertBody := '4';//текст
  //NotificationCenter1.PresentNotification(MyNotification);
  mqtt.connect() ;
  MyNotification.AlertBody := '5';//текст
  NotificationCenter1.PresentNotification(MyNotification);

end;

end.

 

Стандартная библиотека org.eclipse.paho.client.mqttv3-1.2.0 выпадает в ошибку initializer error сразу на строчке 

mqtt:=TJMqttClient.JavaClass.init(StringToJString('tcp://m23.cloudmqtt.com:11021'), StringToJString('java'));

по логам с телефона стало понятно, что проблема в логах ? а конкретно когда библиотека пытается создать логгер выпадает ошибка что не найден файл локализации ru_RU для logcat (сами файлы там вроде как есть). Ладно. Скачал исходники почистил код библиотеки от упоминаний логгера, собрал ииии и ничего. Продвинулся до строчки 

mqtt.connect();

также пробивал 

mqtt.connect(mqttconopt);

ничего не помагает, получаю ошибку сегментации класса 
Пока не понятно куда копать дальше? Возможно что не все библиотеки можно использовать в delphi приложениях? 

P.S Старая версия 1.1.1 тоже не завелась :(

service test2.rar

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Рекомендуемые сообщения

  • 0
57 минут назад, Tarik Live сказал:

Вопрос закрыт. Удалось завести другую библиотеку

которую?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
3 минуты назад, FREEFAR сказал:

которую?

https://github.com/fusesource/mqtt-client
без танцев с бубном не обошлось, но уже получилось подключится к серверу 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
В 25.11.2018 в 19:37, Tarik Live сказал:

https://github.com/fusesource/mqtt-client
без танцев с бубном не обошлось, но уже получилось подключится к серверу 

А можно ваш пример реализации приложения?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
В 25.11.2018 в 18:35, Tarik Live сказал:

Вопрос закрыт. Удалось завести другую библиотеку

Пробовал сделать приложение с сервисом, в самом приложении MQTT работает, а вот сервис запускается и останавливается, но не работает с MQTT, ни отсылает на брокер ни принимает. Я правильно понимаю, этот код принимает сообщения и выдает сообщение MyNotification?

Procedure TDM.MqttMonitor;
var
MyNotification: TNotification;
mess:Jclient_Message;
Bytes: TJavaArray<Byte>;
JS2: JString;
begin
running:=True;
MyNotification := NotificationCenter1.CreateNotification;
MyNotification.Title := 'Mqtt Service';  //заголовок
while True do
begin
  mess:=connection.receive;

  Bytes:=mess.getPayload;
  JS2:=TJString.JavaClass.init(bytes);
  MyNotification.AlertBody := (JStringToString(JS2));//текст
  MyNotification.EnableSound:=True;
  NotificationCenter1.PresentNotification(MyNotification);
end;
end;

А при создании сервиса подписка на топик, который будет мониторится, верно?

topic:=TJTopic.JavaClass.init(StringToJString('android'), TJQoS.JavaClass.AT_LEAST_ONCE);

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
10 минут назад, tetronis сказал:

Пробовал сделать приложение с сервисом, в самом приложении MQTT работает, а вот сервис запускается и останавливается, но не работает с MQTT, ни отсылает на брокер ни принимает. Я правильно понимаю, этот код принимает сообщения и выдает сообщение MyNotification?


Procedure TDM.MqttMonitor;
var
MyNotification: TNotification;
mess:Jclient_Message;
Bytes: TJavaArray<Byte>;
JS2: JString;
begin
running:=True;
MyNotification := NotificationCenter1.CreateNotification;
MyNotification.Title := 'Mqtt Service';  //заголовок
while True do
begin
  mess:=connection.receive;

  Bytes:=mess.getPayload;
  JS2:=TJString.JavaClass.init(bytes);
  MyNotification.AlertBody := (JStringToString(JS2));//текст
  MyNotification.EnableSound:=True;
  NotificationCenter1.PresentNotification(MyNotification);
end;
end;

А при создании сервиса подписка на топик, который будет мониторится, верно?


topic:=TJTopic.JavaClass.init(StringToJString('android'), TJQoS.JavaClass.AT_LEAST_ONCE);

 

Подписка чуть больше, а так да все верно.

topicArray:=TJavaObjectArray<Jtopic>.Create(1);
topic:=TJTopic.JavaClass.init(StringToJString('android/java/'), TJQoS.JavaClass.AT_LEAST_ONCE);
topicArray.Items[0]:=topic;
connection.subscribe(topicArray);

Очень рад, что у вас получилось)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
В 18.04.2019 в 22:20, Tarik Live сказал:

Подписка чуть больше, а так да все верно.


topicArray:=TJavaObjectArray<Jtopic>.Create(1);
topic:=TJTopic.JavaClass.init(StringToJString('android/java/'), TJQoS.JavaClass.AT_LEAST_ONCE);
topicArray.Items[0]:=topic;
connection.subscribe(topicArray);

Очень рад, что у вас получилось)

Еще вопрос, а как вы реализовали отслеживание, если отключится от брокера? или будет переподключаться сам? но у меня так не происходит и через время телефон отрубает WiFi и видимо происходит отключение, сообщения не приходят.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
В 20.04.2019 в 01:40, tetronis сказал:

Еще вопрос, а как вы реализовали отслеживание, если отключится от брокера? или будет переподключаться сам? но у меня так не происходит и через время телефон отрубает WiFi и видимо происходит отключение, сообщения не приходят.

Переподключение я не делал т.к использовал на сотовом интернете а он был всегда

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
В 20.04.2019 в 01:40, tetronis сказал:

Еще вопрос, а как вы реализовали отслеживание, если отключится от брокера? или будет переподключаться сам? но у меня так не происходит и через время телефон отрубает WiFi и видимо происходит отключение, сообщения не приходят.

Думаю у вашем случае будет полезно. Просто поставьте проверку значения данной функции

mqtt.JPG

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
1 час назад, Tarik Live сказал:

Переподключение я не делал т.к использовал на сотовом интернете а он был всегда

за пределы города хоть раз выезжали? :-)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
17 часов назад, Tarik Live сказал:

Думаю у вашем случае будет полезно. Просто поставьте проверку значения данной функции

mqtt.JPG

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

Но про подключение я имел ввиду, что когда гаснет экран телефона/планшета, устройство выключает WiFi, и соответственно сервис отключается от MQTT брокера, а значит это нужно отлавливать и переподключаться.

Не совсем понятен этот код

if running = False then TTask.Run(MqttMonitor);

Сам running нигде не меняет значение, кроме TDM.MqttMonitor; (running:=True;), а при каких условиях выставляется false?

Изменено пользователем tetronis

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
19 часов назад, tetronis сказал:

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

Но про подключение я имел ввиду, что когда гаснет экран телефона/планшета, устройство выключает WiFi, и соответственно сервис отключается от MQTT брокера, а значит это нужно отлавливать и переподключаться.

Не совсем понятен этот код


if running = False then TTask.Run(MqttMonitor);

Сам running нигде не меняет значение, кроме TDM.MqttMonitor; (running:=True;), а при каких условиях выставляется false?

Т.к TDM.AndroidServiceStartCommand может срабатывать несколько раз я ввел   переменную running, чтобы по нескольку раз не стартовал сам mqtt клиент. По вопросу автоматического переподключения я пока не разбирался, нужно чуток больше свободного времени, но есть пару идей. Как протестирую отпишусь. И да, таймер и все что обращается к "форме" в сервисах не работает :(

Изменено пользователем Tarik Live

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
В 22.04.2019 в 22:02, Tarik Live сказал:

Т.к TDM.AndroidServiceStartCommand может срабатывать несколько раз я ввел   переменную running, чтобы по нескольку раз не стартовал сам mqtt клиент. По вопросу автоматического переподключения я пока не разбирался, нужно чуток больше свободного времени, но есть пару идей. Как протестирую отпишусь. И да, таймер и все что обращается к "форме" в сервисах не работает :(

С таймером разобрался, использую AndroidTimerSetInterval, сделал отсылку на брокер каждые 10 сек данные, но столкнулся с проблемой, сервис через время убивается, шлется какое-то время данные, а потом все, убивается и приложение и сервис...хоть и указано START_STICKY.

А вы как-то реализовывали отсылку из приложения через сервис и обратно, данные MQTT?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.


  • Похожий контент

    • От Ali Ezzeddine
      65/5000       Уважаемые,
      Есть ли способ вызвать сервис Java из приложения Delphi FMX?
    • От Эрик Шакиров
      Привет всем! Кто нибудь может подсказать как реализовать анимацию переходов между формами в Android без использования TabControl? Или подсказать в какую сторону "рыть"
    • От Светлана
      Ну всё в принципе как всегда, либо я барашка, либо лыжи не едут)
      А всё просто - я хочу, чтобы пока данные с сервера загружались по клику кнопки, пользователю элементарно был отклик в виде крутящейся какой нибудь фигни и он видел, что процесс идёт и что прога не зависла и никуда лишний раз не тыкал.
      Пока что для тестов сделала элементарно кнопку Update (speedbutton с image), данные элементарно грузятся и отображаются в GridPanel, а поверх него, чтоб пользователь и не смог куда либо тыкнуть, замостила панелькой с Image, вращаемой по таймеру (всё это дело наверху Visible:=false). И когда клацаем по кнопке Update, то панельку сверху грида делаю отображаемой и запускаю таймер, потом этот же обработчик/процедура грузит данные, а по окончанию останавливаем таймер и скрываем полупрозрачну, еще кстати, панельку. Аля вот так:
      procedure TForm1.SB_DataUpdateClick(Sender: TObject); begin //отображаем лого загрузки P_showLoad.Visible := true; Timer_load_rotate.Enabled := true; //с запуском таймера GetDeD_List(DE_set.Date); //процедура загрузки и отображения чего нам надо, которая весьма долго выполняется //и скрывае лого загрузки Timer_load_rotate.Enabled := false; //уже в обратном порядке P_showLoad.Visible := false; end; иии... ни черта не происходит как я хочу(
      Это лого вообще в итоге не отображается, а если убрать его скрытие, то оно у нас отобразится уже только тогда, когда всё загрузится. Логика мне стала подсказывать, что следовало его как то отобразить выполнив в параллельном асинхронном потоке аля так:
      procedure TForm1.SB_DataUpdateClick(Sender: TObject); begin TThread.Queue(TThread.Current, //TThread.Queue TThread.Synchronize ForceQueue procedure() begin P_showLoad.Visible := true; Timer_load_rotate.Enabled := true; end); GetDeD_List(DE_set.Date); //процедура загрузки и отображения чего нам надо, которая весьма долго выполняется end; И опять оно отображается только после того, как всё загрузится и проработает вся процедура. И уже чего только не пробовала и Synchronize и ForceQueue; и через TTask.Run и |task := TTask.Create(procedure () ... и т.д.| ничего не подходит, вот хоть убейся это всё дело будет отображаться только после полной отработки процедуры клика. Может я не в том направлении вообще рою и это как то по другому делается? Может я еще пока отлаживаю на Win32, а не всё на android, а там вот пара вариантов и норм на нём работают? Но чтот я никак не могу понять, что к чему... должно же быть как то просто, а я чтот никак не могу понять как(
    • От ComAlex
      Goоgle Play перестает поддерживать 32-bit Android-приложения c 01.08.2019.
      А выкладывать в Goоgle Play новые УЖЕ нельзя.
      Последние же Delphi XE не позволяют создать 64-bit Android-приложения.
      Кто знает, когда появится новая версия с поддержкой 64 - bit? Говорили, что в конце лета, но лето кончилось
    • От ComAlex
      Здравствуйте, господа программисты!
      Пытаюсь протестировать Android приложение на любом эмуляторе.
      Всегда одна ошибка "Unable to create process: Performing Streamed Install"
      Понимаю, что ссылок много по данной теме в интернете, но ни одна не помогла.
      Использую Embarsadero Delphi 10.3
      При компиляции на реальный телефон всё работает
      При компиляции на эмулятор даже пустого приложения выдается та же ошибка
      "Unable to create process: Performing Streamed Install"
      В чем проблема? Хотя бы в какую сторону копать?
    • От Дмитрий Потапов
      Задался идеей написания IPTV приложения "для себя", в котором при желании смог бы реализовать что-то необходимое и удалить то, что не нужно.
      Собственно вопрос в другом: Я написал простое приложение, которое отлавливает коды кнопок с пульта, приложение по сути самое банальное, использует OnKeyDown и OnKeyUp (чисто для теста). И по нажатию на кнопку на пульте высылает например в Memo или ListBox Информацию о нажатой кнопке (включая ее код).
      Но суть в том, что далеко не все кнопки таким образом распознаются. Для примера:
      Кнопки громкости, назад, домой, увеличение\уменьшение громкости, стрелки(влево, вправо, вверх, вниз) и центральная кнопка (по совместительству OK).
      Цифры все определяются, как одна - 0
      Кнопки, которые не определяются (не срабатывает событие, ибо если был бы неизвестен код, то думаю, в таком случае получил бы все, кроме кода кнопки), но по нажатию кнопки, которая не определяется приложением - ничего не происходит вообще.
       
      Вопрос: Есть ли возможность как-то "научить" приложение распознавать эти кнопки? (Я где-то читал, может даже и здесь, что это все так реализовано именно на уровне самого FireMonkey, будто этих кнопок вообще не существует).
      Если эта тема уже поднималась на форуме или вопрос очень просто решается - извиняюсь)
      Решение: http://fire-monkey.ru/topic/5624-как-отловить-кнопки-пульта-ду/?do=findComment&comment=36399
       
    • От Татьяна
      Здравствуйте!
      Как можно из Android приложения узнать электронный адрес пользователя gmail (если он был настроен, конечно). Где-то же он сохраняется, если Google Play знает.
    • От msp888
      Всем привет! 
      У меня уже несколько лет работают приложения под Windows и под Andriod, в которых выполняется обмен данными по локальной сети по протоколу TCP-IP. Теперь вот мне понадобился прием multicast-пакетов по протоколу UDP. Под Windows всё работает замечательно, а вот под Android ничего принять не могу... 
      Подскажите чего не хватает, или дайте ссылку на пример, где уже реализовано подобное...
      Вот выдержки из кода:
      // переменные FSocket:TSocket; FiAR:IAsyncResult; FasyncWE:TMultiWaitEvent; data:TBytes; res:TWaitResult; WifiLock: JWifiManager_WifiLock; MulticastLock: JWifiManager_MulticastLock; ... // регистрация в группе procedure AddMemberShip(MultiAddr, InterfaceAddr:Cardinal); var Mreq:ip_mreq; begin fillchar(Mreq, SizeOf(Mreq), 0); move(MultiAddr, Mreq.IMR_MultiAddr.S_addr, SizeOf(Mreq.IMR_MultiAddr.S_addr)); move(InterfaceAddr, Mreq.IMR_Interface.S_addr, SizeOf(Mreq.IMR_Interface.S_addr)); CheckSocketResult(setsocketoption(FSocket.Handle, IPPROTO_IP, IP_ADD_MEMBERSHIP, Mreq, SizeOf(Mreq)), 'setsockopt:IP_ADD_MEMBERSHIP'); end; ... // permission... ACCESS_COARSE_LOCATION ACCESS_FINE_LOCATION ACCESS_NETWORK_STATE ACCESS_WIFI_STATE CHANGE_CONFIGURATION CHANGE_NETWORK_STATE CHANGE_WIFI_MULTICAST_STATE CHANGE_WIFI_STATE INTERNET READ_CALENDAR READ_EXTERNAL_STORAGE WRITE_CALENDAR WRITE_EXTERNAL_STORAGE WAKE_LOCK ... // настройка wi-fi WifiLock.acquire; MulticastLock.acquire; ... // создание и настройка сокета FSocket:=TSocket.Create(TSocketType.UDP); FSocket.Bind(TNetEndpoint.Create(ServerIP, ServerPort)); AddMemberShip(TIPAddress.Create(239, 78, 1, 1).Addr.S_addr, ServerIP.Addr.S_addr); AddMemberShip(TIPAddress.Create(239, 78, 1, 2).Addr.S_addr, ServerIP.Addr.S_addr); AddMemberShip(TIPAddress.Create(239, 78, 1, 78).Addr.S_addr, ServerIP.Addr.S_addr); ... // Прием данных в потоке... FiAR:=FSocket.BeginReceiveFrom; FasyncWE:=FiAR.AsyncWaitEvent; res:=FasyncWE.WaitFor; if res = wrSignaled then data:=FSocket.EndReceiveBytesFrom(FiAR); // Прием  
    • От Brovin Yaroslav
      Хочу поделиться с вами знаковой новостью для развития библиотеки FGX Native. Официально выпущено первое Андроид приложение в Google Play Market. 
      Это приложение разработано Станиславом(@sinuke) для учащихся лицея по специальности "Почтовая связь". Оно одновременно является и полным конспектом, который всегда под рукой, и системой проверки своих знаний.
      Полностью разработано на Delphi и стандартных компонентах альфа версии FGX Native 0.9.7.0 в Delphi 10.3 Community Edition. Быстрые списки, гибкая разметка, продвинутая навигация, анимации переходов, поддержка тем и многое другое. Это лишь малая часть того, что было задействовано из текущих возможностей библиотеки.
      Приложение опубликовано в Google Play Market. Вы можете уже прямо сейчас скачать и протестировать приложение самостоятельно, загрузив его по ссылке (https://play.google.com/store/apps/details?id=com.sinukeapps.post).
      Оставляйте свои комментарии и предложения. Они помогут сделать приложение лучше, а FGX Native еще удобнее и стабильнее.
      Релиз первого приложения с использование библиотеки FGX Native - это результат огромной работы, проделанной за эти годы. В тоже время, это сигнал того, что библиотека обладает достаточным минимумом для создания типовых Андроид приложений.
      Ну, и пожалуй самое приятное, это то, что библиотека готова к бета тестированию, которое откроется в ближайшее время.  О начале закрытого бета тестирования будет сообщено позже.
      Отдельное спасибо участникам закрытого альфа тестирования за поддержку, тестирование и идеи по улучшению библиотеки. В настоящее время участниками тестирования ведутся и другие интересные проекты на базе FGX Native, о которых я расскажу позже.
      Следите за новостями.
      Приложение: https://play.google.com/store/apps/details?id=com.sinukeapps.post Автор: Станислав Игнатович @sinuke Минимальные системные требования: Android 5.0 и arm v7         
    • От Yarpda
      В серьезных приложениях (Сбербанк-онлайн или Ютюб и т.п.) когда выходят обновления с новыми функциими, они запускают своеобразный интерактивный ролик. Когда экран затемняется и остается не затемненным только новый элемент экрана например, а на затемненном фоне описывается что делает этот новый элемент.Потом все это плавно переходит к другому элементу и т.д. Выглядит все довольно красиво.
      Задался вопросом, как сделать что-то подобное под FMX. Для себя не нахожу никаких очевидных решений.
      Подскажите если кто знает, направления решения этой задачи?
      Заранее спасибо.
  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу

×
×
  • Создать...