Буферизация Записи инди / Эффективная коммуникация TCP

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

Я думаю, что это может быть то, что вы хотите:

SELECT B.AC,
  A.PN,
  COUNT (DISTINCT A.AC) AS "Nº OF CONTROLS",
  B.AC_TYPE ||'-'|| B.AC_SERIES AS "TYPE/SERIES",
  CASE WHEN COUNT (DISTINCT A.AC) = 1 THEN 1 ELSE 0 END AS "CHECK"
FROM ODB.AC_MASTER B
LEFT JOIN ODB.PLANNING A
ON A.AC = B.AC
AND A.PN = 'RCF6709'
WHERE B.AC_TYPE ||'-'|| B.AC_SERIES = 'ATR72-600'
AND B.STATUS = 'ACTIVE'
GROUP BY B.AC,
  B.AC_TYPE ||'-'|| B.AC_SERIES,
  A.PN

, но это явно не проверено, поскольку у нас нет выборочных данных или ожидаемых результатов.

Я не уверен, что вам нужно distinct в счетчиках, как это значение (или, по крайней мере, версия b, которая одинакова из-за условия соединения, если есть совпадение, и счет будет ноль, если нет) включается в группировку.

8
задан jpfollenius 3 March 2009 в 09:55
поделиться

3 ответа

Запишите, что буферизация отключена по умолчанию. Можно проверить буферизацию записи, чтобы видеть, активно ли это в коде путем тестирования fConnection. IOHandler. Свойство WriteBufferingActive.

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

Взятый от IdIOHandler:

// Optimal Extra Methods
//
// These methods are based on the core methods. While they can be
// overridden, they are so simple that it is rare a more optimal method can
// be implemented. Because of this they are not overrideable.
//
//
// Write Methods
//
// Only the ones that have a hope of being better optimized in descendants
// have been marked virtual
procedure Write(const AOut: string; const AEncoding: TIdEncoding = enDefault); overload; virtual;
procedure WriteLn(const AEncoding: TIdEncoding = enDefault); overload;
procedure WriteLn(const AOut: string; const AEncoding: TIdEncoding = enDefault); overload; virtual;
procedure WriteLnRFC(const AOut: string = ''; const AEncoding: TIdEncoding = enDefault); virtual;
procedure Write(AValue: TStrings; AWriteLinesCount: Boolean = False; const AEncoding: TIdEncoding = enDefault); overload; virtual;
procedure Write(AValue: Byte); overload;
procedure Write(AValue: Char; const AEncoding: TIdEncoding = enDefault); overload;
procedure Write(AValue: LongWord; AConvert: Boolean = True); overload;
procedure Write(AValue: LongInt; AConvert: Boolean = True); overload;
procedure Write(AValue: SmallInt; AConvert: Boolean = True); overload;
procedure Write(AValue: Int64; AConvert: Boolean = True); overload;
procedure Write(AStream: TStream; ASize: Int64 = 0; AWriteByteCount: Boolean = False); overload; virtual;

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

Как очень грубый быстрый пример:

TmyCommand = class(TmyProtocol)
private
  fCommand:Integer;
  fParameter:String;
  fDestinationID:String;
  fSourceID:String;
  fWhatever:Integer;
public
  property Command:Integer read fCommand write fCommand;
  ...

  function Serialize;
  procedure Deserialize(Packet:String);
end;

function TmyCommand.Serialize:String;
begin
  //you'll need to delimit these to break them apart on the other side
  result := AddItem(Command) + 
            AddItem(Parameter) + 
            AddItem(DestinationID) + 
            AddItem(SourceID) + 
            AddItem(Whatever);
end; 
procedure TMyCommand.Deserialize(Packet:String);
begin
   Command := StrToInt(StripOutItem(Packet));
   Parameter := StripOutItem(Packet);
   DesintationID := StripOutItem(Packet); 
   SourceID := StripOutItem(Packet);
   Whatever := StrToInt(StripOutItem(Packet));
end;

Затем отправьте это через:

  FConnection.IOHandler.Write(myCommand.Serialize());

С другой стороны можно получить данные через Инди и затем

  myCommand.Deserialize(ReceivedData);
6
ответ дан 5 December 2019 в 17:41
поделиться

Я не знаком с Инди, но Вы могли бы хотеть осмотреть ее API для опции TCP_NODELAY (Вы могли бы хотеть к grep, исходное дерево Инди для чего-то как этот - нечувствительный к регистру для "задержки" должно сделать это.)

Править: Rob Kennedy указал, что свойство, к которому я обращался, TIdIOHandlerSocket.UseNagle - Спасибо!

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

Я всегда использовал UDP вместе с наивной схемой ACK/retransmission, когда я должен был отправить сообщения, где граница сообщения была важна, те, которые являются Вашим случаем. Мог бы хотеть принять это во внимание. UDP намного лучше подходит для сообщений команды.

4
ответ дан 5 December 2019 в 17:41
поделиться

Кажется, что необходимо сбросить буфер. Попробуйте это:

TIdTCPConnection.FlushWriteBuffer;

Если Вы не хотите буфера записи, используйте это:

TIdTCPConnection.CancelWriteBuffer;

Согласно справке, это сначала называет ClearWriteBuffer, для очистки буфера и затем называет CloseWriteBuffer.

Лучший способ отправить целое число (использование Инди 10) использует TIdIOHandler. Запишите (согласно Инди, 10 Записей справки перегружаются для обработки различных видов данных, включая Целые числа),

0
ответ дан 5 December 2019 в 17:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: