Skip to content

Commit

Permalink
fixed rest-websockets samples
Browse files Browse the repository at this point in the history
  • Loading branch information
Arnaud Bouchez committed Jul 21, 2022
1 parent 6567323 commit 93508c0
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 58 deletions.
2 changes: 1 addition & 1 deletion ex/rest-websockets/restws.longworkshared.pas
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ interface
end;

const
PROJECT31_TRANSMISSION_KEY = 'longwork_privatekey';
LONGWORK_TRANSMISSION_KEY = 'longwork_privatekey';

implementation

Expand Down
2 changes: 1 addition & 1 deletion ex/rest-websockets/restws_chatclient.dpr
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ begin
Client := TRestHttpClientWebsockets.Create('127.0.0.1', '8888', TSQLModel.Create([]));
try
Client.Model.Owner := Client;
Client.WebSocketsUpgrade(PROJECT31_TRANSMISSION_KEY);
Client.WebSocketsUpgrade(CHAT_TRANSMISSION_KEY);
if not Client.ServerTimeStampSynchronize then
raise EServiceException.Create(
'Error connecting to the server: please run Project31ChatServer.exe');
Expand Down
2 changes: 1 addition & 1 deletion ex/rest-websockets/restws_chatinterface.pas
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ interface
end;

const
PROJECT31_TRANSMISSION_KEY = 'meow_privatekey';
CHAT_TRANSMISSION_KEY = 'meow_privatekey';


implementation
Expand Down
12 changes: 8 additions & 4 deletions ex/rest-websockets/restws_chatserver.dpr
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
/// simple SOA server using callbacks for a chat room
program restws_chatserver;

{$APPTYPE CONSOLE}
{$I mormot.defines.inc}

{$ifdef OSWINDOWS}
{$APPTYPE CONSOLE}
{$endif OSWINDOWS}

uses
{$I SynDprUses.inc} // use FastMM4 on older versions of Delphi
{$I mormot.uses.inc} // use FastMM4 on older versions of Delphi
SysUtils,
Classes,
mormot.core.base,
Expand Down Expand Up @@ -68,12 +72,12 @@ begin
ByPassAuthentication := true;
HttpServer := TSQLHttpServer.Create('8888', [Server], '+', WEBSOCKETS_DEFAULT_MODE);
try
HttpServer.WebSocketsEnable(Server, PROJECT31_TRANSMISSION_KEY)^.
HttpServer.WebSocketsEnable(Server, CHAT_TRANSMISSION_KEY)^.
SetFullLog; // full verbose logs for this demo
TextColor(ccLightGreen);
writeln('WebSockets Chat Server running on localhost:8888'#13#10);
TextColor(ccWhite);
writeln('Please compile and run Project31ChatClient.exe'#13#10);
writeln('Please compile and run restws_chatlient'#13#10);
TextColor(ccLightGray);
writeln('Press [Enter] to quit'#13#10);
TextColor(ccCyan);
Expand Down
165 changes: 123 additions & 42 deletions ex/rest-websockets/restws_longworkclient.dpr
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ program restws_longworkclient;

{$ifdef OSWINDOWS}
{$apptype console}
{$ifndef FPC}
{$R mormot.win.default.manifest.res}
{$endif}
{$endif OSWINDOWS}

uses
Expand All @@ -17,13 +19,18 @@ uses
mormot.core.base,
mormot.core.os,
mormot.core.text,
mormot.core.log,
mormot.core.interfaces,
mormot.orm.core,
mormot.soa.core,
mormot.net.ws.core,
mormot.rest.client,
mormot.rest.http.client,
restws.longworkshared in 'restws.longworkshared.pas';


{$I-} // avoid io check in writeln()

type
/// we define a class to implement the callback on client side
TLongWorkCallback = class(TInterfacedCallback, ILongWorkCallback)
Expand Down Expand Up @@ -54,69 +61,143 @@ end;

// this is the main method of this client console application

procedure Run;
type
TClient = class
private
Client: TRestHttpClientWebsockets;
public
ClientIsTerminated: Boolean;
ReconnectNeeded: Boolean;
procedure OnConnect(Sender: TRestClientUri);
procedure OnDisconnect(Sender: TObject);
procedure Run;
end;


{ TClient }

procedure TClient.Run;
var
Client: TRestHttpClientWebsockets;
workName: string;
Service: ILongWorkService;
callback: ILongWorkCallback;
begin
writeln('Connecting to the local Websockets server...');
// create a TRestClientUri instance able to upgrade to WebSockets
Client := TRestHttpClientWebsockets.Create('127.0.0.1', '8888', TOrmModel.Create([]));
try
Client.Model.Owner := Client;
// upgrade the HTTP link to WebSockets using our binary encrypted protocol
Client.WebSocketsUpgrade(PROJECT31_TRANSMISSION_KEY);

// call a simple REST method to ensure the server is actually running
if not Client.ServerTimeStampSynchronize then
raise EServiceException.Create('Error connecting to the server: please run Project31LongWorkServer.exe');

// register and resolve our ILongWorkService in our TRestClientUri instance
Client.ServiceDefine([ILongWorkService], sicShared);
if not Client.Services.Resolve(ILongWorkService, Service) then
raise EServiceException.Create('Service ILongWorkService unavailable');

// main console loop allowing to run remote long work tasks on server
TextColor(ccWhite);
writeln('Please type a work name, then press [Enter]');
writeln('Enter a void line to quit');

// we will share the very same callback on client side
callback := TLongWorkCallback.Create(Client, ILongWorkCallback);
While not ClientIsTerminated do
try
// actual main loop
repeat
TextColor(ccLightGray);
write('>');
readln(workName);
if workName = '' then
break;
Service.StartWork(workName, callback);
TextColor(ccBrown);
writeln('Service.TotalWorkCount=', Service.TotalWorkCount);
until false;
finally
// mandatory: release the service local interfaces BEFORE Client.Free!
callback := nil;
Service := nil;
// remember: this is mandatory!
if not Assigned(Client) or ReconnectNeeded then
begin
FreeAndNil(Client);
callback := nil;
Service := nil;

Writeln('Create client connection');
ReconnectNeeded:=False;
Client := TRestHttpClientWebsockets.Create('127.0.0.1', '8888', TOrmModel.Create([]),false,'','',0,0,2000);
Client.OnWebSocketsClosed := OnDisconnect;
Client.OnConnected := OnConnect;
Client.RetryOnceOnTimeout := False;
Client.Model.Owner := Client;

// upgrade the HTTP link to WebSockets using our binary encrypted protocol
Client.WebSocketsUpgrade(LONGWORK_TRANSMISSION_KEY);

// call a simple REST method to ensure the server is actually running
if not Client.ServerTimeStampSynchronize then
raise EServiceException.Create('Error connecting to the server: please run Project31LongWorkServer.exe');

// register and resolve our ILongWorkService in our TRestClientUri instance
Client.ServiceDefine([ILongWorkService], sicShared);
end;

if not Assigned(Service) then
if not Client.Services.Resolve(ILongWorkService, Service) then
raise EServiceException.Create('Service ILongWorkService unavailable');

// main console loop allowing to run remote long work tasks on server
TextColor(ccWhite);
writeln('Please type a work name, then press [Enter]');
writeln('Enter a void line to quit,');
writeln(' or enter "reset" to create a new client instance, or "break" to close the socket');

// we will share the very same callback on client side
callback := TLongWorkCallback.Create(Client, ILongWorkCallback);
try
// actual main loop
repeat
TextColor(ccLightGray);
write('>');
readln(workName);
if workName = '' then
break;
if workName = 'break' then
begin
Client.Socket.Close; // simulate a raw socket disconnection
break;
end
else if workName = 'reset' then
raise Exception.Create('Reset');
if ReconnectNeeded then
Raise Exception.Create('reconnect needed');
Service.StartWork(workName, callback);
TextColor(ccBrown);
writeln('Service.TotalWorkCount=', Service.TotalWorkCount);
until false;
finally
// mandatory: release the service local interfaces BEFORE Client.Free!
callback := nil;
Service := nil;
// remember: this is mandatory!
end;

except
on E: Exception do
begin
Writeln(E.Message);
callback := nil;
Service := nil;
FreeAndNil(Client);
end;
end;

finally
// close the connection to the server
Client.Free;
FreeAndNil(Client);
end;
end;

procedure TClient.OnConnect(Sender: TRestClientUri);
begin
Writeln('Connected !!!', Sender.GetCurrentSessionUserID);
ReconnectNeeded := False;
end;

procedure TClient.OnDisconnect(Sender: TObject);
begin
Writeln('Disconnected !!!');
ReconnectNeeded := True;
end;


var
App: TClient;
begin
with TSynLog.Family do
begin // enable logging to file and to console
Level := LOG_VERBOSE;
EchoToConsole := LOG_VERBOSE;
PerThreadLog := ptIdentifiedInOneFile;
end;
WebSocketLog := TSynLog; // verbose log of all WebSockets activity

App := TClient.Create;
try
Run;
App.Run;
except
on E: Exception do
ConsoleShowFatalException(E);
end;
end.


17 changes: 9 additions & 8 deletions ex/rest-websockets/restws_longworkserver.dpr
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ type
function TotalWorkCount: Integer;
end;

// how the background work is done in a temporary thread
/// - as initialized and run by TLongWorkService.StartWork
/// how the background work is done in a temporary thread
// - as initialized and run by TLongWorkService.StartWork
TLongWorkServiceThread = class(TRestThread)
protected
fCallback: ILongWorkCallback;
Expand All @@ -49,7 +49,8 @@ type
procedure InternalExecute; override;
public
// when Execute is finished, will trigger callback WorkFinished/WorkFailed
constructor Create(owner: TRest; const workName: string; const callback: ILongWorkCallback);
constructor Create(owner: TRest; const workName: string;
const callback: ILongWorkCallback);
end;


Expand Down Expand Up @@ -85,9 +86,9 @@ var
begin
TSynLog.Add.Log(sllInfo, '%.Execute(%) started', [self, fWorkName]);
tix := GetTickCount64;
Sleep(5000 + Random(1000)); // some hard work
if Random(100) > 20 then
fCallback.WorkFinished(fWorkName, GetTickCount64 - tix)
Sleep(5000 + Random32(1000)); // some hard work
if Random32(100) > 20 then
fCallback.WorkFinished(fWorkName, mormot.core.os.GetTickCount64 - tix)
else
fCallback.WorkFailed(fWorkName, 'expected random failure');
TSynLog.Add.Log(sllInfo, '%.Execute(%) notified', [self, fWorkName]);
Expand Down Expand Up @@ -116,7 +117,7 @@ begin
'8888', [Server], '+', WEBSOCKETS_DEFAULT_MODE);
try
// allow the HTTP server to upgrade to WebSockets with binary encryption
HttpServer.WebSocketsEnable(Server, PROJECT31_TRANSMISSION_KEY).
HttpServer.WebSocketsEnable(Server, LONGWORK_TRANSMISSION_KEY).
SetFullLog; // full verbose logs for this demo

TextColor(ccLightGreen);
Expand All @@ -143,7 +144,7 @@ begin
begin // enable logging to file and to console
Level := LOG_VERBOSE;
EchoToConsole := LOG_VERBOSE;
PerThreadLog := ptIdentifiedInOnFile;
PerThreadLog := ptIdentifiedInOneFile;
end;
WebSocketLog := TSynLog; // verbose log of all WebSockets activity

Expand Down
2 changes: 1 addition & 1 deletion src/mormot.commit.inc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
'2.0.3726'
'2.0.3727'

0 comments on commit 93508c0

Please sign in to comment.