Гость
Форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M [игнор отключен] [закрыт для гостей] / Аналог сокета GT.M в Cache / 10 сообщений из 10, страница 1 из 1
17.05.2018, 16:44
    #39646259
Valeriu
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Аналог сокета GT.M в Cache
Доброго времени всем.
Помогите писать кусочек кода для работы с сокетом по аналогии 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
18.05.2018, 15:53
    #39646793
Valeriu
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Аналог сокета GT.M в Cache
Я получаю что-то, но очень и очень туманно ...
Может подскажите что я делаю не так ???
Примерно такой код:
Код: 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
19.05.2018, 00:00
    #39646955
Alexey Maslov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Аналог сокета GT.M в Cache
Зачем закомментирован GOTO loop ? Было правильно. Структура сокет-сервера:

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

Кстати, в последних версиях GT.M (начиная с 6.2 вроде) реализуема и рекомендуется та же структура сокет-сервера, что и в Cache. Отпочковывать job-ом слушатель нехорошо, т.к. какое-то время порт при этом не слушается. Была об этом статейка у Fidelity.
...
Рейтинг: 0 / 0
21.05.2018, 14:57
    #39647609
Valeriu
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Аналог сокета GT.M в Cache
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
21.05.2018, 17:35
    #39647696
Alexey Maslov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Аналог сокета GT.M в Cache
Открытый сокет - сокет с открытым 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
22.05.2018, 18:52
    #39648278
Valeriu
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Аналог сокета GT.M в Cache
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
23.05.2018, 11:45
    #39648552
Alexey Maslov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Аналог сокета GT.M в Cache
Valeriu,

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

рад слышать.глобаль ^mTEMPЛучше ^mtempУникальныйСуффикс, тогда попадёт в нежурналируемую БД CACHETEMP, которая к тому же чистится при [ре]старте Cache.
...
Рейтинг: 0 / 0
23.05.2018, 13:52
    #39648698
Valeriu
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Аналог сокета GT.M в Cache
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
Форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M [игнор отключен] [закрыт для гостей] / Аналог сокета GT.M в Cache / 10 сообщений из 10, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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