Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.07.29;
Скачать: CL | DM;

Вниз

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;
Скачать: CL | DM;

Наверх




Память: 0.58 MB
Время: 0.024 c
15-1183013786
Ega23
2007-06-28 10:56
2007.07.29
Где скачать JediVCL?


15-1183450467
Начинающий программист
2007-07-03 12:14
2007.07.29
Книга по Delphi


15-1182925482
iXT
2007-06-27 10:24
2007.07.29
OLE Server


2-1183425203
Dreamse
2007-07-03 05:13
2007.07.29
Как найти все созданные формы ? Перечислить.


15-1182859100
Predfer
2007-06-26 15:58
2007.07.29
Мышь PS/2 не работает