You are not logged in.
Pages: 1
Same to me. Links broken. Can we download a zip archive?
https://synopse.info/files/html/api/mOR … l#TSQLREST
I want to use part of internal services on public side.
So i have
InternalServer.ServiceDefine([IService1, IService2, IService3]);
I want to use it on external perimeter as
ExternalClient.Create()
ExternalServer.ServiceDefine( ExternalClient, [IService1] );
Of coarce the obvious way would be
ExternalClient.Create()
ExternalClient.ServiceDefine( [IService1] );
But this makes me responsible for creation and freeing client in every call or Having single client for my instance.
So i am trying to find a nice solution.
Since I did not find a way to use such a call in the examples, I started a thread.
I guess you have something misunderstood.
Is this on server side or client side ?I think the documentation it's very very clear.
Maybe i did.
How to undestand this?
function ServiceRegister(aClient: TSQLRest; const aInterfaces: array of PTypeInfo; aInstanceCreation: TServiceInstanceImplementation=sicSingle; const aContractExpected: RawUTF8=''): boolean; overload; virtual;
Register a remote Service via its interface
- this overloaded method will register a remote Service, accessed via the supplied TSQLRest(ClientURI) instance: it can be available in the main TSQLRestServer.Services property, but execution will take place on a remote server - may be used e.g. for dedicated hosting of services (in a DMZ for instance)
Hi ab.
I am trying to use some services in DMZ and according to manual should be able to do this using TSQLRestServer.ServiceRegister(aClient: TSQLRest;
I get AV error with call "srv.ServiceRegister("
Here is my sample
climodel := ClientModule.GetModel;
RemoteClient := TSQLHttpClientWinHTTP.Create( 127.0.0.1, '333', climodel );
RemoteClient.OnAuthentificationFailed := OnAuthentificationFailed;
srv := TSQLRestServerRemoteDB.Create( RemoteClient );
srv.ServiceRegister(RemoteClient,[TypeInfo(ICABMeter)]);
What is the proper way to use this?
I see variable "aClient" has no use in implementation.
function TSQLRestServer.ServiceRegister(aClient: TSQLRest;
const aInterfaces: array of PTypeInfo;
aInstanceCreation: TServiceInstanceImplementation;
const aContractExpected: RawUTF8): boolean;
begin
result := False;
if (self=nil) or (high(aInterfaces)<0) or (aClient=nil) then
exit;
result := (ServiceContainer as TServiceContainerServer).AddInterface(
aInterfaces,aInstanceCreation,aContractExpected);
end;
Hi. Can someone please show example of using TSQLRecordInterfaced?
Hi.
I tried to use template CrossPlatform.pas.mustache to generate client module but i have empty function and procedure names
in example like this:
type
/// service implemented by TServiceDir
// - you can access this service as such:
// !var aDir: IDir;
// !begin
// ! aDir := TServiceDir.Create(aClient);
// ! // now you can use aDir methods
// !...
IDir = interface(IServiceAbstract)
['{CE9A54A2-E524-4C9F-9573-E885BD4D875E}']
function
end;
This interface is declared
IDir = interface(iinvokable)
['{CE9A54A2-E524-4C9F-9573-E885BD4D875E}']
Function Groups():RawJSON;
end;
How can i fix this?
Thank you for advice.
J := ExtDatabase.RetrieveListJSON( TMeterGroup,'',[],'');
s:=UTF8ToString(J);
works as i wanted to.
I am using
MSDBProps:=TOleDBMSSQL2012ConnectionProperties.Create(
...
VirtualTableExternalRegister(aModel,TMeterGroup,MSDBProps,'');
ExtDatabase:=TSQLRestServerDB.Create(aModel,':memory:');
I have declared table like
TMeterGroup = class (TSQLRecord)
private
fgroupID:RawUTF8;
fName:RawUTF8;
published
property groupID:RawUTF8 index 40 read fgroupID write fgroupID stored AS_UNIQUE;
property Name:RawUTF8 index 50 read fName write fName stored AS_UNIQUE;
end;
Saved one item into MSSQL
Then i am trying to read:
MeterGroup := TMeterGroup.CreateAndFillPrepare(ExtDatabase,'');
if MeterGroup.FillOne then
In that manner i can read proper cyrillic value in "Name"
Second test
J := ExtDatabase.RetrieveListJSON( TMeterGroup,'',[],'');
and my cyrilic value become something else.
What did i miss?. Help me please.
Maybe i have found a solution.
procedure
procedure TPollAsynchSockets.ProcessRead(timeoutMS: integer);
has cycle skip in case of socket read error
res := AsynchRecv(slot.socket,@temp,sizeof(temp));
if res<0 then // error - probably "may block"
break;
i think we must close connection depending on errorcode?
res := AsynchRecv(slot.socket,@temp,sizeof(temp));
if res<0 then // error - probably "may block"
begin
err:=WSAGetLastError();
case err of
WSAECONNRESET:CloseConnection;
end;
break;
end;
Hi everyone. I have noted that my server have high cpu load after a while.
After small testing i found that simple scanning may be cause of such behaviour.
when i start my server like this
Server:=TAsynchServer.Create('333',nil,nil,TMySocket,'test',TSQLLog, [] ,5);
and scanning like this
nmap -sT 192.168.4.62 -p 333
i have 100% cpu load immideatly.
Help me anyone)
Hi ab. I am trying to use TAsynchServer from SynCrtSock.
I start my test application with event "OnRead" filled with "Sender.Write(self,'Hello!');" and it hangs when i am trying to write using telnet.
Steps to reproduce
1. start application
2. open telnet session with "telnet 127.0.0.1 333"
3. write something. You have to get "Hello!" as responce.
Application code
program SocketTest;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
mormot,
SynCrtSock,
SynBidirSock;
type
TMySocket = class(TAsynchConnection)
public
function OnRead(Sender: TAsynchConnections): TPollAsynchSocketOnRead; override;
end;
var
Server:TAsynchServer;
{ TMySocket }
function TMySocket.OnRead(Sender: TAsynchConnections): TPollAsynchSocketOnRead;
begin
Sender.Write(self,'Hello!');
end;
begin
try
Server:=TAsynchServer.Create('333',nil,nil,TMySocket,'test',TSQLLog, [] ,50);
Readln(Input);
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
i think the problem is "procedure TPollAsynchSockets.ProcessRead(timeoutMS: integer);"
i just moved block
if added>0 then
try
inc(fReadCount);
inc(fReadBytes,added);
if OnRead(connection)=sorClose then
CloseConnection;
except
CloseConnection; // any exception will force socket shutdown
end;
after
finally
slot.UnLock;
end;
and everything become good)
procedure TPollAsynchSockets.ProcessRead(timeoutMS: integer);
var notif: TPollSocketResult;
connection: TObject;
slot: PPollSocketsSlot;
res,added: integer;
temp: array[0..$7fff] of byte; // read up to 32KB chunks
procedure CloseConnection;
begin
if connection=nil then
exit;
Stop(connection); // will shutdown the socket
try
OnClose(connection); // do connection.Free
except
connection := nil;
end;
slot := nil; // ignore pseClosed
end;
begin
if (self=nil) or fRead.Terminated then
exit;
InterlockedIncrement(fProcessing);
try
if not fRead.GetOne(timeoutMS,notif) then
exit;
connection := TObject(notif.tag);
slot := SlotFromConnection(connection);
if (slot=nil) or (slot.socket=0) then
exit;
if pseError in notif.events then
if not OnError(connection,notif.events) then begin // false = shutdown
CloseConnection;
exit;
end;
if pseRead in notif.events then begin
if slot.Lock then // ensure read slot not already processed in another thread
try
added := 0;
repeat
if fRead.Terminated then
exit;
res := AsynchRecv(slot.socket,@temp,sizeof(temp));
if res<0 then // error - probably "may block"
break;
if res=0 then begin // socket closed -> abort
CloseConnection;
exit;
end;
AppendData(slot.readbuf,temp,res);
inc(added,res);
until false;
// if added>0 then
// try
// inc(fReadCount);
// inc(fReadBytes,added);
// if OnRead(connection)=sorClose then
// CloseConnection;
// except
// CloseConnection; // any exception will force socket shutdown
// end;
finally
slot.UnLock;
end;
if added>0 then
try
inc(fReadCount);
inc(fReadBytes,added);
if OnRead(connection)=sorClose then
CloseConnection;
except
CloseConnection; // any exception will force socket shutdown
end;
end;
if (slot<>nil) and (pseClosed in notif.events) then begin
CloseConnection;
exit;
end;
finally
InterlockedDecrement(fProcessing);
end;
end;
I checked and it works on:
2012
2014
2016
unfortunatelly last 2008 server i knew was upgraded to 2016 so i cant test 2008.
Don't know any 2005 server also.
Hi ab.
When i use mormot for storing data to external MSSQL database i have annoying message "Index already exists".
it is happened because column INDEX_COUNT always =0 (module SynDB function TSQLDBConnectionProperties.SQLGetField)
dMSSQL,dMySQL, dPostgreSQL: FMT :=
'select COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION,'+
' NUMERIC_SCALE, 0 INDEX_COUNT'+ // INDEX_COUNT=0 here (done via OleDB)
' from INFORMATION_SCHEMA.COLUMNS'+
' where UPPER(TABLE_SCHEMA) = ''%'' and UPPER(TABLE_NAME) = ''%''';
i suggest use my variant of query for MSSQL
dMSSQL: FMT:=
' select '+
' sys.all_columns.name as COLUMN_NAME,'+
' sys.types.name as DATA_TYPE,'+
' iif(is_ansi_padded=1,sys.all_columns.max_length,null) as CHARACTER_MAXIMUM_LENGTH, '+
' iif(is_ansi_padded=0,sys.all_columns.precision,null) as NUMERIC_PRECISION, '+
' iif(is_ansi_padded=0,sys.all_columns.scale,null) as NUMERIC_PRECISION,'+
' count(sys.index_columns.object_id) as INDEX_COUNT'+
' from '+
' sys.all_columns join sys.types on sys.all_columns.user_type_id=sys.types.user_type_id'+
' left join sys.index_columns on sys.all_columns.object_id = sys.index_columns.object_id and sys.all_columns.column_id = sys.index_columns.column_id'+
' where sys.all_columns.object_id=object_id(''%.%'')'+
' group by '+
' sys.all_columns.name,'+
' sys.types.name,'+
' iif(is_ansi_padded=1,sys.all_columns.max_length,null), '+
' iif(is_ansi_padded=0,sys.all_columns.precision,null), '+
' iif(is_ansi_padded=0,sys.all_columns.scale,null)';
thank you
Found this in demo project "mORMot.REST-master"
https://github.com/GitStorageOne/mORMot.REST
Possible reson is deadlock entering criticalsection "GlobalThreadLock" in module SynLog.
Conditions:
1. TSQLLog.Family.Level := [sllTrace,sllEnter]
2. create TSQLHttpServer with "TSQLHttpServerSecurity.secSSL"
Can someone check this bug?
Pages: 1