|
Асинхронный сокет внутри компоненты. | ☑ | ||
|---|---|---|---|---|
|
0
Gugatar
29.03.15
✎
14:08
|
Добрый день . Стоит задача реализовать компоненту для 1С которая могла бы выполнять функции клиента. Т.е. есть удаленный сервер, к которому подключаемся из 1С, режим работы обязательно асинхронный. Почитав немного на эту тему, понял что реализация должна быть через сообщения Windows и через создание окна, которое будет обрабатывать сообщения. На Delphi видел в интернете пару примеров, но они написаны с использованием TClientSocket в режиме ctNonBlocking. Мне нужно написать на C++. В компоненте при вызове функции CallAsProc создаю окно, опиcываю оконную процедуру. Пока все происходит внутри dll – все работает. Как только код возвращается в 1С – выскакивает ошибка. Необработанное исключение по адресу 0x0F10113B в 1cv8.exe: 0xC0000005: нарушение прав доступа при исполнении по адресу 0x0F10113B. Кто сталкивался с решением подобной проблемы подскажите, может вообще не в ту сторону копаю?
|
|||
|
1
romix
29.03.15
✎
16:07
|
Так а встроенные средства работы из 1С 8.3 HTTP вроде и есть асинхронные?
|
|||
|
2
Gugatar
29.03.15
✎
16:19
|
Может быть и так, но должно работать на 8.2. HTTP не подойдет, нужна работа на уровне сокета.
|
|||
|
3
H A D G E H O G s
29.03.15
✎
16:36
|
(0) Ты копаешь не в ту строну.
|
|||
|
4
Gugatar
29.03.15
✎
16:46
|
Подскажи направление.
|
|||
|
5
H A D G E H O G s
29.03.15
✎
16:50
|
(4) "понял что реализация должна быть через сообщения Windows и через создание окна, которое будет обрабатывать сообщения. "
Что за ересь? Создаем поток, который ждет сообщения от сервера, записывает в буфер данные сообщения и отправляет сообщение в 1С через iEvent.ExternalEvent('TCPClient', 'УСПЕХ', Inttostr(GetCurrentThreadId)); 1C во ВнешнемСобытии вызывает метод ВК, который читает из буфера ВК накопленные данные (скорее всего ComSafeArray, либо ДвоичныеДанные). |
|||
|
6
Gugatar
29.03.15
✎
17:32
|
(5) Отлично, спасибо тебе огромное, а мог бы ты раскрыть ту первую часть по которой ты пробежал весьма поверхностно немного поглубже. "Создаем поток, который ждет сообщения от сервера," и как бы это все сделать в асинхронном режиме с неблокирующим сокетом...? Если тебе не сложно мог бы ты привести пример.
|
|||
|
7
H A D G E H O G s
29.03.15
✎
17:37
|
(6) Вот тебе пример асинхронного чтения COM-порта, то же самое:
Procedure T_vk_object.ReadThread(); stdcall; var tmp: Cardinal; Buffer: Pointer; StaticBuffer: array [0 .. 80000] of Byte; BytesRead: Cardinal; ExtendedResultList: TStructureList; RetStructure: TStructure; ResultArray: OleVariant; begin tmp := EV_RXCHAR; repeat WaitCommEvent(hPort, tmp, nil); if not ReadFile(hPort, StaticBuffer, 80000, BytesRead, nil) then begin ErrorCode := GetLastError; ErrorDescription := _GetErrorMsg(ErrorCode); ExtendedResultList := self.ExtendedResultList; RetStructure := TStructure.Create; ExtendedResultList.Add(RetStructure); RetStructure.Insert('ID', ID); self.ExtendedResultList := ExtendedResultList; iEvent.ExternalEvent('COMPORT', 'ОШИБКА', Inttostr(GetCurrentThreadId)); Continue; end; if BytesRead = 0 then Continue; ResultArray := VarArrayCreate([0, 0], VarOfType); VarArrayRedim(ResultArray, Round(BytesRead / DataType) - 1); Buffer := VarArrayLock(ResultArray); CopyMemory(Buffer, @StaticBuffer, BytesRead); VarArrayUnLock(ResultArray); ExtendedResultList := self.ExtendedResultList; RetStructure := TStructure.Create; ExtendedResultList.Add(RetStructure); RetStructure.Insert('Данные', ResultArray); RetStructure.Insert('ID', ID); self.ExtendedResultList := ExtendedResultList; iEvent.ExternalEvent('COMPORT', 'УСПЕХ', Inttostr(GetCurrentThreadId)); until false; end; |
|||
|
8
Gugatar
29.03.15
✎
18:13
|
Спасибо конечно, но решение которое ты предложил заставляет крутить в цикле и постоянно проверять, не пришли ли тебе данные, тем самым куча времени теряется в никуда. Мне хотелось уйти от этого принципа и воспользоваться функциями из асинхронного расширения Windows. WSAAsyncSelect ...
|
|||
|
9
H A D G E H O G s
29.03.15
✎
18:28
|
(8) плохо.
Функция WaitCommEvent ожидает какое-то событие, которое произойдет для заданного коммуникационного устройства. Пакет событий, которые проверяются этой функцией, содержится в маске события, связанной с дескриптором устройства. |
|||
|
10
Gugatar
29.03.15
✎
23:41
|
(9) Странно, не понимаю какое отношение сюда имеет WaitCommEvent, и как ей можно подсунуть сокет. Через CreateFile нельзя получить сокет... Пожалуйста!!! если то что ты пишешь это не так лишь бы было, потрать 5-ть минут своего времени напиши реальный пример, не думаю что он будет больше 10 строк. Спасибо!!!
|
|||
|
11
Torquader
30.03.15
✎
00:27
|
(10) Очень просто - читаем WSAEventSelect и чешем репу.
Всё достаточно просто - только вот главный вопрос - а зачем ? Не проще ли из вашей поделки на Delphi вызвать 1С через внешнее соединение ? |
|||
|
12
Gugatar
30.03.15
✎
11:11
|
(11) 1)Еще чуть чуть и у меня будет плешь.
2)Ответ в (0) 3)У меня нет ничего на Delphi кроме примеров других людей, задача стоит писать не на Delphi, а на C++. Мне кстати очень хотелось бы узнать как реализован TClientSocket. |
| Форум | Правила | Описание | Секции | Поиск |