Роботы, плагины и скрипты к чату MyChat. Разработка альтернативных клиентов и различных утилит. Технические вопросы по программированию, замечания и предложения по развитию API
Аватара пользователя
SV
Доброе время суток. Пытался сам разобраться с запросами данных к серверу.
Так и не смог понять как его реализовать. Хотелось бы видеть не большой пример.
Например как запросить список существующих каналов.
Аватара пользователя
Алексей Пикуров
Схема работы достаточно простая.

Есть процедура mcSendDataToMyChat. У неё два параметра, число iCmd типа DWORD и строка sJSONData типа WideString в формате JSON.

iCmd - это команда, которую следует выполнить, список констант находится в модуле mcClientAPI.pas

Все константы, которые касаются этой процедуры, начинаются с MCC_Send....

mcSendDataToMyChat - это процедура, которая отправляет данные запроса на сервер. Когда будет получен ответ от сервера, произойдёт соответствующее событие и будет вызвана procedure mcEvent в вашей DLL библиотеке.

В примере так и сделано:
Код: Выделить всё
procedure mcEvent(iCmd: DWORD; sJSONData: WideString);safecall;
begin
  case iCmd of
    MCC_On_LoginSucess: mcSendDataToMyChat(MCC_Get_ChannelsList, '');
    MCC_On_ChannelsList: ShowMessage(sJSONData);
  end;
end;

getchannelslistplugin.png

На успешный логин мы отправляем серверу команду получения списка текстовых конференций. Команда отправляется без параметров. Когда с сервера придёт ответ, мы выведем полученный JSON объект на экран. Формат описан в протоколе MyChat, команда 8008 sc_get_channels_list

Архив клиента и сервера: http://www.nsoft-s.com/work/mychat.zip, обновить, чтобы заработал пример.
Исходные тексты примера для Delphi XE3: http://www.nsoft-s.com/mychat/clientplu ... nflist.zip
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Аватара пользователя
SV
То есть, получается если я напишу плагин напишу то у других работать не будет пока они не обновят клиент?
Аватара пользователя
Алексей Пикуров
Вы сначала напишите :) А когда обновим версию - обновится и API плагинов, всё будет работать.
Plugins API мы расширяем по запросам, "в воздух" и "про запас" функции не делаем, наши ресурсы временные ограничены.
Аватара пользователя
SV
Сервер нужно обновлять?
Проблема с распаковкой сервера, выдаёт ошибку.
Пере запакуйте пожалуйста.
Аватара пользователя
Алексей Пикуров
Я написал выше, обновлять и клиент и сервер.
Проблема с распаковкой сервера, выдаёт ошибку.

Что за проблема? Кто выдаёт ошибку и какую? Может, вы архив недокачали?
Аватара пользователя
SV
Распаковал на сервере нормально, похоже встроенный архиватор кривой.

Что то не пойму, что здесь не так.
Код: Выделить всё
procedure mcEvent(iCmd: DWORD; sJSONData: WideString);safecall;
var S:String;
begin
  case iCmd of
    MCC_On_LoginSucess: mcSendDataToMyChat(MCC_Get_ChannelsList, '');
    MCC_On_ChannelsList: S:=sJSONData; //Заполняем переменную
  end;
    showmessage(sJSONData); //Показываем что пришло
    showmessage(s); //Смотрим что в переменной
end;




При этом клиент вылетает с ошибкой(Разрушительный сбой), приходиться перезапускать клиент.
Аватара пользователя
Алексей Пикуров
procedure mcEvent - это процедура, которая вызывается множество раз из MyChat Client. На любое событие, которое возникает в чате.

Вы поставили код
showmessage(sJSONData); //Показываем что пришло
showmessage(s); //Смотрим что в переменной

в основном цикле обработки сообщений (вне основного CASE) и заставили печатать на экран абсолютно всё, что приходит от MyChat Client.

Правильно - "поймать" в case нужное вам сообщение и вызвать специальную функцию для обработки этих данных, функцию имеет смысл расположить в другом модуле. Посмотрите, как это сделано в плагине-примере Beeper.
Аватара пользователя
SV
И так вроде разобрался с общим принципом работы плагинов в чате.
Не могу понять как же всё таки получить id каналов, когда их более 1
средствами SuperObject в delphi.

Код: Выделить всё
{"1":{"CreatorUIN":0,"UsersCount":2,"SyncLogs":true,"Created":"16.07.2014.12.58.37","Secured":false,"Topic":"Главный канал чата","Name":"Главный"},
"11":{"CreatorUIN":0,"UsersCount":2,"SyncLogs":true,"Created":"16.07.2014.12.58.37","Secured":false,"Topic":"Нет темы","Name":"Test"}}


Хочется что бы добавили ещё параметры такие как:
  • Общее количество каналов
  • Поместили бы id канала в вложения
Аватара пользователя
Алексей Пикуров
"1" и "11" это и есть ID каналов. Количество объектов - это количество каналов.

Чтобы "перебрать" JSON объект, используйте, например, вот такой код:
Код: Выделить всё
var
  JSONobj: ISuperObject;
  JSONIterator: TSuperObjectIter;
  iCount: integer; // общее количество каналов
begin
  // st - исходные данные, которые нужно "распарсить"

  iCount  := 0;
  JSONobj := TSuperObject.ParseString(StringToOleStr(st), false);

    if ObjectFindFirst(JSONobj, JSONIterator) then
      repeat
       
        sAddTxtChannel2List(strtoint(JSONIterator.key), // это и есть ID канала
                                     JSONIterator.val.B['Secured'],
                                     JSONIterator.val.I['UsersCount'],
                                     JSONIterator.val.S['Name'],
                                     JSONIterator.val.S['Topic'],
                                     JSONIterator.val.B['SyncLogs']);
        inc(iCount); // увеличиваем счётчик количества каналов на сервере
      until not ObjectFindNext(JSONIterator);

  ObjectFindClose(JSONIterator);

  JSONobj.Clear(true);
  JSONobj := nil;
end;

P.S. Пример кода для Delphi 7
Аватара пользователя
Алексей Пикуров
Константа для получения списка текстовых каналов изменена с MCC_Get_ChannelsList на MCC_Send_Request_ChannelsList (= 22).
Аватара пользователя
SV
Произошли ли изменения в запросе данных?
Аватара пользователя
Алексей Пикуров
Нет, только константа изменилась. Я параллельно описываю команды в справке клиента, чтобы было ясно, что нужно отправлять и какие данные ожидаются в ответ.