Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2007.07.29;
Скачать: [xml.tar.bz2];

Вниз

TSocketConnection - познее связывание - - в другом потоке.   Найти похожие ветки 

 
tytus ©   (2007-07-03 10:22) [0]

Доброго дня мастера. Вот собственно и тема - хочу выполнять методы сервера в отдельном потоке+показать форму выполнения.
В главном приложении есть TSocketConnection (Connect1) и TClientDataSet (CDS1).
В конструкторе потока передаю и Connect1 и CDS1.
...
Constructor WaitThread.Create(AConnect:TSocketConnection;ADataSet:TClientDataSet);
begin
FConnect:=AConnect;
FDataSet:=ADataSet;
inherited create(false);
end;

procedure Execute;
begin
FConnect.AppServer.МойМетод;
end;

вот на такой код делфи ругаеццо:EVariantInvalidArgError,
а если запускать екзешник - то Error reading from Socket.
Как правильно сие сделать...


 
Сергей М. ©   (2007-07-03 10:55) [1]


> ругаеццо:EVariantInvalidArgError


Значит параметры вызванного тобой метода инвалидны


 
Romkin ©   (2007-07-03 11:08) [2]

Это хорошо еще катастрофический сбой не словил :)
Для каждого потока - свое соединение и свои датасеты.


 
tytus ©   (2007-07-03 11:23) [3]

>Romkin ©   (03.07.07 11:08) [2]
Для каждого потока - свое соединение и свои датасеты.
В главном приложении  Connect1 ужо подключается к серверу.
Так что - нереально передать в поток уже подключенный SocketConnection?
Если нельзя - то как мне указывать имя сервера?


 
Сергей М. ©   (2007-07-03 11:42) [4]


> нереально передать в поток уже подключенный SocketConnection?


Реально. Криминала никакого в этом нет.


> как мне указывать имя сервера?


String-параметром ServerName конструктора потока


 
Anatoly Podgoretsky ©   (2007-07-03 11:45) [5]

> tytus  (03.07.2007 11:23:03)  [3]

А где здесь позднее связываение?


 
tytus ©   (2007-07-03 11:50) [6]

>Anatoly Podgoretsky ©   (03.07.07 11:45) [5]
а потму позднее, что не подключаю модуль ...TLB сервера, где описаны его методы а просто делаю FConnect.AppServer.МойМетод;
Как же с основным вопросом?


 
Сергей М. ©   (2007-07-03 12:00) [7]


> tytus ©   (03.07.07 11:50) [6]


У тебя что, метод интерфейса содержит символы кириллицы ?


 
tytus ©   (2007-07-03 12:03) [8]

>Сергей М. ©   (03.07.07 12:00) [7]
... да хоть китайские иероглифы - что это меняет ? кроме ухода в сторону от основной темы вопроса...


 
Сергей М. ©   (2007-07-03 12:10) [9]


> что это меняет ?


Это сразу вызывает вопрос - каким образом ты умудрился под Д7 скомпилировать декларацию интерфейса

IMyAppServer = interface(IAppServer)
..
 procedure МойМетод;
..
end;

?


 
Сергей М. ©   (2007-07-03 12:14) [10]


> кроме ухода в сторону от основной темы вопроса


А ты задумался над смыслом, заложенным в название ид-ра EVariantInvalidArgError ?


 
tytus ©   (2007-07-03 12:40) [11]

>Сергей М. ©   (03.07.07 12:10) [9]
интересно - а как вообще люди делают трехзвенку????
Я создал RemoteDataModule.
Затем сохранил прожект, и F9 - и вуаля - сервачег зарегистрировался!
Супер - неправда ли?
Затем добавил форму - File->New->Form... связал модули и.т.п.
Как я добавлял методы сервера? Лехко и проста!
в protected пишу процедурку (она же мой метод) с директивой safecall;
Затем Edit->Add to interface и вписываю сию процедурку.
Сохраняем, запускаем... и о чудо!!! далее думаю ненужно....

>Сергей М. ©   (03.07.07 12:14) [10]
нет недумал...времени нехватает...


 
Сергей М. ©   (2007-07-03 12:55) [12]


> в protected пишу процедурку (она же мой метод)


Прямо кириллицей пишешь ?! И компилятор это спокойно пропускает ?!

Не надо уж лапшу-то вешать)


 
tytus ©   (2007-07-03 13:03) [13]

>Сергей М. ©   (03.07.07 12:55) [12]
..да нет же не кирилицей есессно -))))) ну написал МойМетод - чтоб не вводить в заблуждение названием реальных методов... как видно  - получилось как всегда..
А все-таки - Сергей М. - не подскажите ли как правильно выполнять методы сервера в другом потоке через позднее связываение используя TSocketConnection?
Можно ссылочку на толковые статьи (с примерами желательно)...или книгу какую по-вразумительнее..


 
Сергей М. ©   (2007-07-03 13:04) [14]


> Затем Edit->Add to interface и вписываю сию процедурку


Да щщас !

А это что

"... invalid character #204 found"

?

Эта ошибка ЗАКОНОМЕРНА. если твой метод называется "Мойметод"


 
tytus ©   (2007-07-03 13:07) [15]

>Сергей М. ©   (03.07.07 13:04) [14]
tytus ©   (03.07.07 13:03) [13]


 
Anatoly Podgoretsky ©   (2007-07-03 13:12) [16]

> чтоб не вводить в заблуждение названием реальных методов

Да ну


 
tytus ©   (2007-07-03 13:18) [17]

>Anatoly Podgoretsky ©   (03.07.07 13:12) [16]
-))
tytus ©   (03.07.07 13:03) [13]


 
Сергей М. ©   (2007-07-03 13:30) [18]


> да нет же не кирилицей есессно


Ну а что ж тогда про иероглифы [8] начал ?)


> как правильно выполнять методы сервера в другом потоке через
> позднее связываение


1. Методы диспинтерфейса должны иметь соглашение о вызове safecall

2. Добавлять методы нужно не через анус (Edit -> Add to interface), а специально  существующими на то средствами редактора библ-ки типов (New -> Method/Property) - редактор сам произведет все необходимые изменения в RDM-юните.


 
Сергей М. ©   (2007-07-03 13:36) [19]


> или книгу какую по-вразумительнее


Эрик Хармон, "Разработка COM-приложений в среде Delphi"


 
tytus ©   (2007-07-03 13:44) [20]

>Сергей М. ©   (03.07.07 13:36) [19]
списобо за книгу, будем посмотреть...
>Сергей М. ©   (03.07.07 13:30) [18]
редактор сам
дык... тоже самое правится в RDM_TLB...


 
Сергей М. ©   (2007-07-03 13:49) [21]


> тоже самое правится в RDM_TLB


Редактор при манипуляциях с интерфейсами делает синхронную правку сразу двух юнитов - RDM и TLB. На то он и предоставлен разработчиками.

Зачем же делать это ручками, если это чревато ошибками, тем более когда знаний на эту тему не хватает ?


 
ага   (2007-07-03 13:54) [22]

Да низя так делать. Можно тока маршальнуть интерфейс в другой поток, и то тоrа при STA, да вот толку с того чуть, вызов все одно пойдет через майн нить.


 
Сергей М. ©   (2007-07-03 14:12) [23]


> ага   (03.07.07 13:54) [22]
>
> Да низя так делать


Можно.

TSocketConnection использует свой собственный маршаллинг.


 
ага   (2007-07-03 14:43) [24]

to Сергей М. ©

Я вот про ето:
"Сергей М. ©   (03.07.07 11:42) [4]

> нереально передать в поток уже подключенный SocketConnection?

Реально. Криминала никакого в этом нет."

Можна - покажи как.

>>>TSocketConnection использует свой собственный маршаллинг.

Ага. Для передачи через свое сокетное соединение и тока. Притом еще всякие объекты создает, списки заполняет, и без всякой межпоточной синхронизации.


 
ага   (2007-07-03 14:45) [25]

А еще он кажись отдельный поток создает для собсно связи но ето я точно не помню


 
Сергей М. ©   (2007-07-03 15:29) [26]


> ага   (03.07.07 14:43) [24]


Смотри исходники.


 
ага   (2007-07-03 17:38) [27]

Хе:) И чего именно мне там смотреть? Насмотрелся ужо.
Я так понял, что кода, подтверждающего сказанное в [4], не будет? Я так и думал.


 
Сергей М. ©   (2007-07-04 08:41) [28]


> чего именно мне там смотреть?


Конкретно взаимодействие методов

TStreamedConnection.Send
и
TTransportThread.Execute


 
Сергей М. ©   (2007-07-04 09:09) [29]


> ага


Ничто не мешает маршаллеру исполнение акций asCreateObject и asFreeObject в одном треде, а акций asInvoke для этого объекта - в другом треде. Естетственно при условии, что в момент существования объекта ни один третий тред не прикажет маршаллеру исполнить акцию asCreateObject или asFreeObject - в этом случае результат конечно же будет плачевный.


 
ага   (2007-07-04 09:40) [30]

2 Сергей М. ©

Слушай, ну я давно ужо с етим разбирался и щас опять вспоминать мне времени нетути. Я ж не говорю что я носитель верховной истины:) Может ты и прав. Просто покажи код, коротенько так, строк на двадцать. Типа передаем в нить открытый сокетКоннекшен и в ните дергаем какой-нить метод сервера с одним параметром.

Ну иль я попожже все таки освежу в памяти енто дело.


 
ага   (2007-07-04 11:27) [31]

Ага, значит глянул я исходники освежил:)
Вобщем ежели каллбак разрешен то полный обломс, ответ от сервака придет в майн поток или где коннекшен открывали, а там ево не ждуть:) Вот ето я видать и помнил. Ежли без обраток то типа можно, но шибко осторожно, ниче другого делать с коннектом походу в ето время нельзя. То бишь паралельности один фиг не получим.


 
Сергей М. ©   (2007-07-05 12:21) [32]


> ежели каллбак разрешен то полный обломс


Про этот режим и речи не идет.


> Ежли без обраток то типа можно, но шибко осторожно, ниче
> другого делать с коннектом походу в ето время нельзя


Ну а вот это уже ближе к телу)

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


 
ага   (2007-07-05 13:34) [33]

>> ежели каллбак разрешен то полный обломс

>Про этот режим и речи не идет

Как эт не идет? Ишшо как идет. Он по умолчанию включен а штоб отключал кто - о том ни слова. Значить о нем и речь:)) И ошибка в вопросе как раз с той оперы.


 
Сергей М. ©   (2007-07-05 13:46) [34]


> Он по умолчанию включен


Это ничего не меняет, если серверная сторона не пытается задействовать эту потенциальную возможность клиента.

Не без оснований смею предполагать, что автор знать об этом ничего не знает и никакими колбэками в его аппсервере не пахнет.


 
ага   (2007-07-06 06:49) [35]

"Это ничего не меняет, если серверная сторона не пытается задействовать эту потенциальную возможность клиента."

По барабану использует или нет. Если TSocketConnection.SupportCallbacks установлен в истину то для обмена с серваком запускается дополнительная нитка, хош используй хош не используй. И на этом усë, фишка из вопроса пахать не будет. Глянь TStreamedConnection.Send


 
ага   (2007-07-06 06:51) [36]

"Не без оснований смею предполагать, что автор знать об этом ничего не знает и никакими колбэками в его аппсервере не пахнет."

Ага. Потому он еë и оставил в истине:))


 
Сергей М. ©   (2007-07-06 08:20) [37]


> Если TSocketConnection.SupportCallbacks установлен в истину
> то для обмена с серваком запускается дополнительная нитка


Ну и что ?

Пока не поступают обратные вызовы, логика транспорта в этой нити принципиально ничем не отличается от логики транспорта в осн.нити - те же блокирующие вызовы send и recv, те же последовательные "двойки" из отправки CallSig-дейтаблока и ожидания/приема соответствующего ему ResultSig-дейтаблока. Все синхронно: запрос-ответ, запрос-ответ...

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


 
ага   (2007-07-06 08:47) [38]

"Пока не поступают обратные вызовы, логика транспорта в этой нити принципиально ничем не отличается от логики транспорта в осн.нити - те же блокирующие вызовы send и recv, те же последовательные "двойки" из отправки CallSig-дейтаблока и ожидания/приема соответствующего ему ResultSig-дейтаблока. Все синхронно: запрос-ответ, запрос-ответ..."

Ты че исходники не смотрел что-ли? Какие нафиг двойки?:) Лана, с сюда скопирую.
Вот так коннект открывается.
procedure TStreamedConnection.InternalOpen;
begin
 if FSupportCallbacks then
 begin
   FTransport := TTransportThread.Create(Handle, CreateTransport);
   FTransport.OnTerminate := TransportTerminated;
   WaitForSingleObject(FTransport.Semaphore, INFINITE);
 end else
 begin
   FTransIntf := CreateTransport;
   FTransIntf.SetConnected(True);
 end;
end;

По барабану будет кто пользоваться каллбэками али нет, все одно транспортный трэд запускается ежли FSupportCallbacks установлен, а устанавливается он в конструкторе.
А вот так с пакетами клиент работает
function TStreamedConnection.Send(const Data: IDataBlock; WaitForResult: Boolean): IDataBlock;
var
 Msg: TMsg;
 Context: Integer;
begin
 if FSupportCallbacks then
 begin
   if not Assigned(FTransport) then Exit;
   Data._AddRef;
   PostThreadMessage(FTransport.ThreadID, THREAD_SENDSTREAM, Ord(WaitForResult),
     Integer(Pointer(Data)));
   if WaitForResult then
     while True do
     begin
       if GetMessage(Msg, FHandle, THREAD_RECEIVEDSTREAM, THREAD_EXCEPTION) then
       begin
         if Msg.message = THREAD_RECEIVEDSTREAM then
         begin
           Result := IDataBlock(Msg.lParam);
           Result._Release;
           if (Result.Signature and ResultSig) = ResultSig then
             break else
             Interpreter.InterpretData(Result);
         end
         else if Msg.Message <> WM_NULL then
           DoError(Exception(Msg.lParam))
         else
           raise Exception.CreateRes(@SReturnError);
       end else
         raise Exception.CreateRes(@SReturnError);
     end
   else
     GetMessage(Msg, FHandle, THREAD_SENDNOTIFY, THREAD_SENDNOTIFY);
 end else
 begin
   if not Assigned(FTransIntf) then Exit;
   Context := FTransIntf.Send(Data);
   Result := FTransIntf.Receive(WaitForResult, Context);
 end;
 if Assigned(Result) and ((Result.Signature and asMask) = asError) then
   Interpreter.InterpretData(Result);
end;

Смотрящий да увидит:) Ежли в истине стоит FSupportCallbacks - ус&#235;, пакеты пошли через транспортную нить. А куда же ента нить ответ отправит? А вот куда!

if GetMessage(Msg, FHandle, THREAD_RECEIVEDSTREAM, THREAD_EXCEPTION)

А чеж эт за FHandle такой? Дык вот же он, в InternalOpen
FTransport := TTransportThread.Create(Handle, CreateTransport);
Вот здесь-то он зараза и создается. И че ж получается? А то что ответ пойдет в тот трэд в котором окно FHandle создавали, то бишь откуда коннект открывали. Если в главном потоке открывали то в главный и пойдет. А он про ентот запрос знать не знает и ведать не ведает:)

И чего тут непонятного?


 
Сергей М. ©   (2007-07-06 09:09) [39]


> чего тут непонятного?


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


 
tytus ©   (2007-07-06 09:19) [40]

БОЛЬШОЕ спасибо господа,
но я ужо и сам допер, чта SupportCallBacks нужна атключать.
Да и к тому-жо на клиенте всего адин дополнительный поток.
TWaitThread=class(TTHread)
 FConnect:TSocketConnection;
...

constructor TWaitThread.Create(AConnect:TSocketConnection...);
begin
FConnect:=AConnect;
...

inherited Create(false);
end;

procedure TWaitThread.Execute;
begin
FConnect.AppServer.MyMethod(MyParams);
...
end;

Все работает как нужна!!

Есще раз - благодарствую...!!

end;



Страницы: 1 2 вся ветка

Форум: "Начинающим";
Текущий архив: 2007.07.29;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.56 MB
Время: 0.043 c
15-1183328674
Германн
2007-07-02 02:24
2007.07.29
Какая всё-таки хорошая вещь - современные бытовые водонагреватели


15-1183523848
шпыён
2007-07-04 08:37
2007.07.29
Вопрос к тем кто в Америке, Зап. Европе и пр.


2-1183537724
Qzzma
2007-07-04 12:28
2007.07.29
Как открывать файлы приложениями используемыми Windows?


2-1183368943
Tonich
2007-07-02 13:35
2007.07.29
COM-порт


15-1182954688
Andy BitOff
2007-06-27 18:31
2007.07.29
Третья версия лицензии GPL будет выпущена на этой неделе





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский