powered by simpleCommunicator - 2.0.38     © 2025 Programmizd 02
Форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M [игнор отключен] [закрыт для гостей] / Аналог сокета GT.M в Cache
10 сообщений из 10, страница 1 из 1
Аналог сокета GT.M в Cache
    #39646259
Valeriu
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Доброго времени всем.
Помогите писать кусочек кода для работы с сокетом по аналогии GT.M в Каше
(версия старая 5,0), я не очень силен в сокетах Каше
Не пинайте сильно.

Код работающий в GT.M:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
listen
 n tcpdev,nr,SYSGLD
 s nr=0 
 s timeo=30
 s port=9998
 s ^fcgilog(1,"knownserver")=port_"`"_$j
 s tcpdev="SCK$"_$S
 o tcpdev:(ZLISTEN=port_":TCP":NODELIMITER:ZNODELAY:ATTACH="listener"):timeo:"SOCKET"
 e  s ^fcgilog($job)="-1,NotOpen" q
 u tcpdev
 w /listen(1)
 f  d  q:$key]""
 . w /wait(timeo)
 . i $key]"" q
 s socket=$p($key,"|",2)
 c tcpdev:(SOCKET="listener") j listen^FCGIjobs 
loop 
    n $zt s $zt="goto errstop^FCGIjobs"
    u tcpdev:(NODELIMITER:ZNODELAY:SOCKET=socket)
    r *version,*type,*requestIdB1,*requestIdB0 s requestId=256*requestIdB1+requestIdB0
    r *contentLengthB1,*contentLengthB0,*paddingLength,*reserved
    s contentLength=256*contentLengthB1+contentLengthB0
    s contentData="" i contentLength r contentData#contentLength
    s paddingData="" i paddingLength r paddingData#paddingLength
    i type=1 s nr=nr+1 do  g loop
   .......
   итд



Спасибо.
...
Рейтинг: 0 / 0
Аналог сокета GT.M в Cache
    #39646793
Valeriu
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я получаю что-то, но очень и очень туманно ...
Может подскажите что я делаю не так ???
Примерно такой код:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
webFC ;;
 ;
 QUIT
 ;
Version()
 ;; Build2
 q
port
 ;;9998
 ;
server ;
     s nr=0
     SET io="|TCP|1"
     SET ^serverport=9998
     OPEN io:(:^serverport:"ACT"):15 
     IF $TEST=0 {
     WRITE !,"Cannot open server port"
     QUIT }
     ELSE { WRITE !,"Server port opened" }
loop USE io READ x ; Read for accept        
     USE 0 WRITE !,"Accepted connection",!
     JOB child:(:5:io:io) ;Concurrent server bit is on
     ;GOTO loop
     ;QUIT
child
    WRITE $JOB,! ;Send job id on TCP device to be read by client
    ;write *-3
     USE io
    ;u $io:(::"+Q":$c(10))
    ;use $io:(/IOTABLE="UTF8"::"-Q+W":$c(0))
    ;U $P:(::"CT")
    s ^CON(1)="TEST"    
    r *version,*type,*requestIdB1,*requestIdB0 s requestId=256*requestIdB1+requestIdB0
    r *contentLengthB1,*contentLengthB0,*paddingLength,*reserved
    s contentLength=256*contentLengthB1+contentLengthB0
    s contentData="" i contentLength r contentData#contentLength
    s paddingData="" i paddingLength r paddingData#paddingLength
    s ^CON(2)="version -"_version
    s ^CON(3)="type -"_type
    s ^CON(4)="requestIdB1 -"_requestIdB1
    s ^CON(5)="requestIdB0 -"_requestIdB0
    s ^CON(6)="requestId -"_requestId
    i type=1 s nr=nr+1 do  g child
     ;. f i=1:1:contentLength s ^type1(i)=$A(contentData,i)
    i type=4 s %fcgi("i","params")=$G(%fcgi("i","params"))_contentData d:'contentLength  g child
    . s pos=1 f  q:pos>$L(%fcgi("i","params"))  do
    . . s l1=$A(%fcgi("i","params"),pos),l2=$A(%fcgi("i","params"),pos+1)
    . . s %fcgi("i","header",$E(%fcgi("i","params"),pos+2,pos+2+l1-1))=$E(%fcgi("i","params"),pos+2+l1,pos+2+l1+l2-1)
    . . s pos=pos+l1+l2+2
    . k %fcgi("i","params")
    i type=5&(contentLength>0) s %fcgi("i","stdin")=$G(%fcgi("i","stdin"))_contentData g child    
    ; Jetzt sind alle Daten da
    ;
    s %fcgi("o","header","Set-Cookie")="SID="_$S($G(%fcgi("i","header","SID"))="":($P($H,",")_"00000"+$P($H,",",2))_nr_",1",1:$P(%fcgi("i","header","SID"),",")_","_($P(%fcgi("i","header","SID"),",",2)+1))
    s ^CONN(1)="TEST1"
    i $G(%fcgi("i","header","HTTP_CONTENT_TYPE"))="application/x-www-form-urlencoded" d HTMLVARDECODE(%fcgi("i","stdin"),"%fcgi(""i"",""_POST""")
    i %fcgi("i","header","QUERY_STRING")'="" d HTMLVARDECODE(%fcgi("i","header","QUERY_STRING"),"%fcgi(""i"",""_GET""")
    ; Jetzt auf Programme verteilen
    s t=$G(^%FCGI("DOCUMENT_URI",$P(%fcgi("i","header","DOCUMENT_URI"),"/",1,3)))
    s sid=$p(%fcgi("i","header","SID"),",")
    i sid="" s sid=$j ; ???
    s ^CONN(2)="TEST2"
    d:t'="" startappl(t)
    s (ind,txt)="" f  s ind=$O(%fcgi("o","header",ind)) q:ind=""  s txt=txt_ind_": "_%fcgi("o","header",ind)_$C(13,10)
    s txt=txt_$C(13,10)
    ;u tcpdev:(NODELIMITER:ZNODELAY:SOCKET=socket) ; why   ???
    u $io:(::"+Q":$c(10))
    w $C(1,6,requestIdB1,requestIdB0,$L(txt)\256,$L(txt)#256,0,0),txt
    i $G(%fcgi("o","stdout"))'="" w $C(1,6,requestIdB1,requestIdB0,$L(%fcgi("o","stdout"))\256,$L(%fcgi("o","stdout"))#256,0,0),%fcgi("o","stdout")
    w $C(1,6,requestIdB1,requestIdB0,0,0,0,0) ; stdout Complete
    w $C(1,3,requestIdB1,requestIdB0,0,8,0,0),$C(0,0,0,0,0,0,0,0) ; Request Complete
    c $io:(::"+Q":$c(10))
    g loop
    q
    ;
startappl(appl)
 s sid=$p(%fcgi("i","header","SID"),",",1) ;i sid="" s sid=$job
 d @appl
 q
 ;
record(type,data)   ; Not used
    w $C(1,type,requestIdB1,requestIdB0,$L(data)\256,$L(data)#256,0,0)_data
    q
    ;
init ;  Not used
    n (fcgi)
    s fcgi("type",1,"FCGI_BEGIN_REQUEST")=1
    s fcgi("type",1,"FCGI_ABORT_REQUEST")=2
    s fcgi("type",1,"FCGI_END_REQUEST")=3
    s fcgi("type",1,"FCGI_PARAMS")=4
    s fcgi("type",1,"FCGI_STDIN")=5
    s fcgi("type",1,"FCGI_STDOUT")=6
    s fcgi("type",1,"FCGI_STDERR")=7
    s fcgi("type",1,"FCGI_DATA")=8
    s fcgi("type",1,"FCGI_GET_VALUES")=9
    s fcgi("type",1,"FCGI_GET_VALUES_RESULT")=10
    s fcgi("type",1,"FCGI_UNKNOWN_TYPE")=0
    ;
HTTPSTATUS401(realm)
    s %fcgi("o","header","Status")="401 Unauthorized"
    s %fcgi("o","header","WWW-Authenticate")="Basic realm="""_realm_""""
    s %fcgi("o","header","Content-Type")="text/plain",%fcgi("o","stdout")="Unauthorized"
    q
    ;
HTMLVARDECODE(data,var)  ; Decodiert nach HTML-Variablen-Standard
    ;w data,!,var,!
    n l,i,ind,val,t
    s l=$L(data,"&") f i=1:1:l s t=$P(data,"&",i) d
    . ;s ind=$$CONVERT($TR($P(t,"="),lower,upper)),val=$$CONVERT($P(t,"=",2))
    . s ind=$$CONVERT($P(t,"=")),val=$$CONVERT($P(t,"=",2))
    . i $L(ind) s @(var_","""_ind_""")")=val ;w ind,": ",val,!
    q
    ;
HEX2DEZ(dez)	;
    n (dez) s hex=0,dez=$TR(dez,"abcdef","ABCDEF")
    f i=1:1:$L(dez) s hex=hex*16+$s($A(dez,i)>59:$A(dez,i)-55,1:$E(dez,i))
    q hex
    ;
CONVERT(t)	;
    n (t)
    s t=$TR(t,"+"," "),p=0
    f  s p=$F(t,"%",p) q:p<1  s t=$E(t,1,p-2)_$C($$HEX2DEZ($E(t,p,p+1)))_$E(t,p+2,255)
    q t
    ;


При инициирование ВЕБ страницы в терминале получаю;
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
USER>d server^%FCGI

Server port opened
Accepted connection
6553

    i %fcgi("i","header","QUERY_STRING")'="" d HTMLVARDECODE(%fcgi("i","header",
    ^
"QUERY_STRING"),"%fcgi(""i"",""_GET""")
<UNDEFINED>child+32^%FCGI
USER 2d0>zw

%fcgi("o","header","Set-Cookie")="SID=64786562601,1"
contentData="ID"
contentLength=18179
contentLengthB0=3
contentLengthB1=71
io="|TCP|1"
nr=1
paddingData=""
paddingLength=0
requestId=18766
requestIdB0=78
requestIdB1=73
reserved=83
type=82
version=84
x=""
 

...
Рейтинг: 0 / 0
Аналог сокета GT.M в Cache
    #39646955
Alexey Maslov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Зачем закомментирован GOTO loop ? Было правильно. Структура сокет-сервера:

слушаем
if словили коннект, job child, передав ему код 5 = открытый сокет (4) + таблицу символов (1)
снова слушаем...

Кстати, в последних версиях GT.M (начиная с 6.2 вроде) реализуема и рекомендуется та же структура сокет-сервера, что и в Cache. Отпочковывать job-ом слушатель нехорошо, т.к. какое-то время порт при этом не слушается. Была об этом статейка у Fidelity.
...
Рейтинг: 0 / 0
Аналог сокета GT.M в Cache
    #39647609
Valeriu
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey Maslov,
Можете обьяснить, что имеется введу под "открытый сокет (4) + таблицу символов (1)" ?
Типа этого ?
Код: vbnet
1.
2.
3.
4.
    ;u $io:(::"+Q":$c(10))
    u $p:(/IOTABLE="UTF8"::"PSTE")
    ;u $p:(/IOTABLE="RAW"::"-Q+W"::32000)
    ;U $P:(::"PSTE")



Видно, что-то не правильно получает сокет со стороны nginx здесь:

Код: vbnet
1.
i %fcgi("i","header","QUERY_STRING")'="" d HTMLVARDECODE(%fcgi("i","header","QUERY_STRING"),"%fcgi(""i"",""_GET""")
...
Рейтинг: 0 / 0
Аналог сокета GT.M в Cache
    #39647696
Alexey Maslov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Открытый сокет - сокет с открытым tcp-соединением. Код 4 в команде JOB. Кода 16 в 5.0 вроде бы ещё не было.
Таблица символов - все локальные переменные процесса. Код 1 в JOB. (Передавать не обязательно).
Всё по примеру: http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=GIOD_tcp#GIOD_tcp_connect_job
В Cache 5.0 наверняка были отличия, которых я уже не помню, но и аналогичный пример тоже был, более-менее рабочий, ЕМНИП.

Лучше отладить сокет-сервер на простейших примерах, (чтобы и клиент был на COS/mumps), научиться уверенно ловить соединение, потом уже переходить к нюансам nginx.
...
Рейтинг: 0 / 0
Аналог сокета GT.M в Cache
    #39648278
Valeriu
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey Maslov,

<<Лучше отладить сокет-сервер на простейших примерах, (чтобы и клиент был на COS/mumps), научиться уверенно ловить соединение, потом уже переходить к нюансам nginx.>>

Этот сокет давно я раскусил на примерах MWire Rob Twid-а ...
Работает безупречно ...
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
port
 ;;9998
 ;
start
 i $zv["GT.M" QUIT
 n io,port,x
 ;
 l +^zmwire("daemon"):0 e  QUIT  ; already running
 ;
 s io="|TCP|1" 
 s port=$p($t(port+1),";;",2) 
 o io:(:port:"PTA"):20 e  QUIT
 u io
loop
 r x
 j child:(:5:io:io)
 g loop
 ;
child
 ;
 u $io:(::"+Q":$c(10))
 d command^zmwire
 QUIT
 ;


Вот вклинить его для общения с nginx никак не могу..
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
server {
	listen 8082 default_server;
	listen [::]:8082 default_server ipv6only=on;

	root /media/sf_share/html/;
	index index.html index.htm;
	server_name localhost;

        location ~ (\.m$|^/cache/.*) {
              fastcgi_pass 127.0.0.1:9998;
		fastcgi_param   QUERY_STRING            $query_string;
		fastcgi_param 	SID 			$cookie_sid;
		fastcgi_param   DOCUMENT_URI            $document_uri;
		fastcgi_param   REQUEST_METHOD          $request_method;
        }
}

...
Рейтинг: 0 / 0
Аналог сокета GT.M в Cache
    #39648552
Alexey Maslov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Valeriu,

Возможно, причина в том, что fastcgi - это двоичный протокол, а в примерах (включая MWire) чаще встречается текстовый. Пишу сейчас в фоновом режиме двоичный сокет-сервер. Гашу разделители (/TER="") и делаю всё сам. Мне проще, т.к. протокол мой собственный. Вам придётся подстраиваться под "чужое": скорее всего читать length#N, распаковывать длину, потом читать message#lengthUnpacked.
...
Рейтинг: 0 / 0
Аналог сокета GT.M в Cache
    #39648595
Valeriu
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey Maslov,
Вроде вклинил ...
Заработал. Все с ВЕБ страницы получаю в каше, сформировал даже
при вызове рутины - глобаль ^mTEMP. Осталось из него $order-м выбирать
и обратно отсылать на ВЕБ страницу и заполнить таблицу.
Если получится и обратно, я "победил"
...
Рейтинг: 0 / 0
Аналог сокета GT.M в Cache
    #39648629
Alexey Maslov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Valeriu,

рад слышать.глобаль ^mTEMPЛучше ^mtempУникальныйСуффикс, тогда попадёт в нежурналируемую БД CACHETEMP, которая к тому же чистится при [ре]старте Cache.
...
Рейтинг: 0 / 0
Аналог сокета GT.M в Cache
    #39648698
Valeriu
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey Maslov,
<<Лучше ^mtempУникальныйСуффикс,>>

Думаю SID ему присвоить.
Примерно так работает сокет:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
webFC ;;Compilation 
 ;
 QUIT
 ;
Version()
 ;; Build2
 q
port
 ;;9998
 ;
start
 s nr=0
 s ^serverport=9998
 s tcpport=^serverport
server ;
     k (io,tcpport,nr,DDB)
     s io="|TCP|"_tcpport
     o io:(:tcpport:"AS"):5
     i $t=0 {
     u 0 w !,"Cannot open server port"
     q }
     else { u 0 w !,"Server port opened" }
loop u io r x ; Read for accept        
     u 0 w !,"Accepted connection",!
     j ini(io,tcpport,nr):(:5:io:io):5
     I $ZA\8196#2=1 w *-2 ;job failed to clear bit
     g loop
     q
ini(io,tcpport,nr)
    ;     
child
    n $es n $et s $et="g:'$es error"
    s io=$i
    u io
    r *version,*type,*requestIdB1,*requestIdB0 s requestId=256*requestIdB1+requestIdB0
    r *contentLengthB1,*contentLengthB0,*paddingLength,*reserved
    s contentLength=256*contentLengthB1+contentLengthB0
    s contentData="" i contentLength r contentData#contentLength
    s paddingData="" i paddingLength r paddingData#paddingLength
    i type=1 s nr=nr+1 do  g child
     . f i=1:1:contentLength s ^type1(i)=$A(contentData,i)
     . w !
    i type=4 s %fcgi("i","params")=$G(%fcgi("i","params"))_contentData d:'contentLength  g child
    . s pos=1 f  q:pos>$L(%fcgi("i","params"))  do
    . . s l1=$A(%fcgi("i","params"),pos),l2=$A(%fcgi("i","params"),pos+1)
    . . s %fcgi("i","header",$E(%fcgi("i","params"),pos+2,pos+2+l1-1))=$E(%fcgi("i","params"),pos+2+l1,pos+2+l1+l2-1)
    . . s pos=pos+l1+l2+2
    . k %fcgi("i","params")
    i type=5&(contentLength>0) s %fcgi("i","stdin")=$G(%fcgi("i","stdin"))_contentData g child    
    ; Jetzt sind alle Daten da
    ;
    s %fcgi("o","header","Set-Cookie")="SID="_$S($G(%fcgi("i","header","SID"))="":($P($H,",")_"00000"+$P($H,",",2))_nr_",1",1:$P(%fcgi("i","header","SID"),",")_","_($P(%fcgi("i","header","SID"),",",2)+1))
    i $G(%fcgi("i","header","HTTP_CONTENT_TYPE"))="application/x-www-form-urlencoded" d HTMLVARDECODE(%fcgi("i","stdin"),"%fcgi(""i"",""_POST""")
    i %fcgi("i","header","QUERY_STRING")'="" d HTMLVARDECODE(%fcgi("i","header","QUERY_STRING"),"%fcgi(""i"",""_GET""")
   .....
   ....
    c io
    g loop
    q


Получилось, заполнил таблицу.
Огорчает одно, всегда нужно смотреть на длину строки,
передавая клиенту порциями, иначе получаю ошибку "максимальная строка"
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M [игнор отключен] [закрыт для гостей] / Аналог сокета GT.M в Cache
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]