Jump to content

Client Notifications


Ruslan

Recommended Posts

What I have:

1. Some background threads which work at server and post log information to DB

2. Users which need to see information from log after it added

 

How to provide information to user? I can start timer on Client and every 5 sec check DB - but if will 20 clients - it will be too many requests to DB. Can I start timer at server (1 for all users) and send information to client browser if exists message for this client? How to verify at server which user connected and send message to him?

Link to comment
Share on other sites

There is no websocket component in Unigui yet, but you may be able to use socket.io with node.js:

const
  socketToken = 'mySpecialToken';

procedure TMainForm.myHtmlFrameAjaxEvent(Sender: TComponent; EventName: string;
  Params: TUniStrings);
begin  
  if eventname='doSocketAuth' then 
  begin
    UniSession.AddJS('socket.emit("authenticate", {token: "' + socketToken + '"});');
  end;
  if eventname='gotData' then 
  begin
    //myData:=strtointdef(Params.Values['mydata'], 0);
    //do something with it
  end;
end;

//to broadcast some data
procedure TMainForm.socketPush(myData:integer);
begin
   UniSession.AddJS('if(socket !== undefined)socket.emit("'+companyName+'", ' + inttostr(myData) + ');');
end;

//some JS to run somewhere to setup the socket connection and catch the incoming data
if(socket === undefined){
  var socket = io('http://127.0.0.1:3000/?company=' + companyName, {
  reconnection: true, 
  reconnectionDelay: 3000, 
  reconnectionAttempts: 20, 
  forceNew: false,
  secure: true
});
}

socket.on('connect', function(){
  ajaxRequest(MainForm.myHtmlFrame, ["doSocketAuth"], { });
});

socket.on(companyName, function(data){ 
  ajaxRequest(MainForm.myHtmlFrame, ["gotData"], { mydata : data }); 
});
  
//node.js script to run an https socket io server
var fs = require('fs');
var https = require('https');
var app = require('express')();
var options = {
  key: fs.readFileSync('c:/my.key'),
  cert: fs.readFileSync('c:/my.crt')
};
var serverPort = 3000;
var server = https.createServer(options, app);
var io = require('socket.io')(server);

io.on('connection', function(socket){
  companyName=socket.handshake.query.company;
  socket.auth = false;
  socket.on('authenticate', function(data){
    if(data.token == 'mySpecialToken'){
      socket.auth = true;
    }
  });
 
  setTimeout(function(){
    if (!socket.auth) {
      socket.disconnect('unauthorized');
    }
  }, 1000);
	
  socket.on(companyName, function(msg){
    if (socket.auth)io.emit(companyName, msg);
  });
});

server.listen(serverPort, function(){
  console.log('Socket.io https server listening on port ' + serverPort);
});

You will also need to add socket.io.js to the CustomFiles in servermodule and of course set up the node server.

  • Upvote 2
Link to comment
Share on other sites

There is no websocket component in Unigui yet, but you may be able to use socket.io with node.js:

const
  socketToken = 'mySpecialToken';

procedure TMainForm.myHtmlFrameAjaxEvent(Sender: TComponent; EventName: string;
  Params: TUniStrings);
begin  
  if eventname='doSocketAuth' then 
  begin
    UniSession.AddJS('socket.emit("authenticate", {token: "' + socketToken + '"});');
  end;
  if eventname='gotData' then 
  begin
    //myData:=strtointdef(Params.Values['mydata'], 0);
    //do something with it
  end;
end;

//to broadcast some data
procedure TMainForm.socketPush(myData:integer);
begin
   UniSession.AddJS('if(socket !== undefined)socket.emit("'+companyName+'", ' + inttostr(myData) + ');');
end;

//some JS to run somewhere to setup the socket connection and catch the incoming data
if(socket === undefined){
  var socket = io('http://127.0.0.1:3000/?company=' + companyName, {
  reconnection: true, 
  reconnectionDelay: 3000, 
  reconnectionAttempts: 20, 
  forceNew: false,
  secure: true
});
}

socket.on('connect', function(){
  ajaxRequest(MainForm.myHtmlFrame, ["doSocketAuth"], { });
});

socket.on(companyName, function(data){ 
  ajaxRequest(MainForm.myHtmlFrame, ["gotData"], { mydata : data }); 
});
  
//node.js script to run an https socket io server
var fs = require('fs');
var https = require('https');
var app = require('express')();
var options = {
  key: fs.readFileSync('c:/my.key'),
  cert: fs.readFileSync('c:/my.crt')
};
var serverPort = 3000;
var server = https.createServer(options, app);
var io = require('socket.io')(server);

io.on('connection', function(socket){
  companyName=socket.handshake.query.company;
  socket.auth = false;
  socket.on('authenticate', function(data){
    if(data.token == 'mySpecialToken'){
      socket.auth = true;
    }
  });
 
  setTimeout(function(){
    if (!socket.auth) {
      socket.disconnect('unauthorized');
    }
  }, 1000);
	
  socket.on(companyName, function(msg){
    if (socket.auth)io.emit(companyName, msg);
  });
});

server.listen(serverPort, function(){
  console.log('Socket.io https server listening on port ' + serverPort);
});

You will also need to add socket.io.js to the CustomFiles in servermodule and of course set up the node server.

 

Would you have any examples?

Link to comment
Share on other sites

There is no websocket component in Unigui yet, but you may be able to use socket.io with node.js:


You will also need to add socket.io.js to the CustomFiles in servermodule and of course set up the node server.

 

Thank you very much! how to use this from EXE file on another server where just only exe-file without unigui? Will I able to connect node.js server from internet? Also I do not quite understand how to check which MainForm shoud show this message and which not (if message only for several active clients from all). It would be greate to have demo application - unigui + separate exe-file with button "send message to unigui client N1". I can pay for this work.

Link to comment
Share on other sites

Thank you very much! how to use this from EXE file on another server where just only exe-file without unigui? Will I able to connect node.js server from internet? Also I do not quite understand how to check which MainForm shoud show this message and which not (if message only for several active clients from all). It would be greate to have demo application - unigui + separate exe-file with button "send message to unigui client N1". I can pay for this work.

 

The node.js server listens on a port, and when you open up the firewall it is exposed and will be able to take client connections.

 

The form which should show the message, is the form with the uniHtmlFrame running the JS code.

You can process the message in the htmlFrame, as a chat box, or you can send it to the server and

show it from there, save it etc.

 

Since the socket.io client is written in JS, which runs only in the browser or in node.js, you have to

go through one of these. You can push messages locally into the node.js server in different ways,

but that would be the way to go, if you cannot send it from one of the clients.

 

In the example above, the client should of course only connect to localhost when testing, and

be pointed to the actual IP or domain of the live server when in production.

Link to comment
Share on other sites

can I connect in the same way to any socket server, not only node.js?

 

To any socket.io server, yes, but I do not know of any other implementations of socket.io servers

than the node.js one. Have not found any windows binaries.

 

Socket.io is not pure websocket protocol, not at all, but it starts there and downgrades to longpolling if the

browser do not support websockets. So it provides for greater compatibility across browser versions.

 

Pure websocket components are available for Delphi, from at least one guy.

Link to comment
Share on other sites

The node.js server listens on a port, and when you open up the firewall it is exposed and will be able to take client connections.

 

The form which should show the message, is the form with the uniHtmlFrame running the JS code.

You can process the message in the htmlFrame, as a chat box, or you can send it to the server and

show it from there, save it etc.

 

Since the socket.io client is written in JS, which runs only in the browser or in node.js, you have to

go through one of these. You can push messages locally into the node.js server in different ways,

but that would be the way to go, if you cannot send it from one of the clients.

 

In the example above, the client should of course only connect to localhost when testing, and

be pointed to the actual IP or domain of the live server when in production.

 

looks like I will process which message show to this client on client side? but it will be thousands messages from different client and only 1 from 100 I should show to client. Also it maybe not secure to send all messages to client which should not know any information from this messages.

Link to comment
Share on other sites

looks like I will process which message show to this client on client side? but it will be thousands messages from different client and only 1 from 100 I should show to client. Also it maybe not secure to send all messages to client which should not know any information from this messages.

 

You can have different channels, like you see I have using the handshake.query parameter,

where I use the company name to make sure only those in the same company get it.

 

In addition you can filter out messages according to all kind of criteria before they are shown to

the user on the client side.

Link to comment
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
×
×
  • Create New...