Форум: "Начинающим";
Текущий архив: 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 - усë, пакеты пошли через транспортную нить. А куда же ента нить ответ отправит? А вот куда!
if GetMessage(Msg, FHandle, THREAD_RECEIVEDSTREAM, THREAD_EXCEPTION)
А чеж эт за FHandle такой? Дык вот же он, в InternalOpenFTransport := 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.051 c