Headless Client License

How can I get Servoy to use only 1 client license for the JSP Pages?

I have tried…

ISessionBean servoy_hc = (ISessionBean)session.getAttribute("servoy");
	if (servoy_hc == null)
	{
		servoy_hc = HeadlessClientFactory.createSessionBean(request,"busmod_locationHolders", null, null);
		session.setAttribute("servoy",servoy_hc);
	}

and

ISessionBean servoy_hc = (ISessionBean)session.getAttribute("servoy");
	if (servoy_hc == null)
	{
		servoy_hc = HeadlessClientFactory.createSessionBean(request,"busmod_locationHolders");
		session.setAttribute("servoy",servoy_hc);
	}

but both still show 2 clients in the Server Admin pages.

Hi Scott,

You need to bind the client to the application instead of the session like this:

ISessionBean servoy_hc = (ISessionBean)application.getAttribute("servoy"); 
if (servoy_hc == null) 
{ 
	servoy_hc = HeadlessClientFactory.createSessionBean(request,"busmod_locationHolders"); 
	application.setAttribute("servoy",servoy_hc); 
}

Thank you. that worked great.

Doing this also means that all jsp requests (visitors) are processed sequentially and everyone is using the same solution/form

Doing this also means that all jsp requests (visitors) are processed sequentially and everyone is using the same solution/form

Yes, this is okay. This solution is just a very simple query and return type. It isn’t really record based. However, I do have a related question. In order to do it that way, and just use 1 client license, my JSP page looks like this…

<%@ page import = "java.util.*" %>
<%@ page import = "com.servoy.j2db.server.headlessclient.*" %>
<%@ page import = "com.servoy.j2db.dataprocessing.IDataSet" %>
<%@ page errorPage="errorpage.jsp" %>
<%
	ISessionBean servoy_hc = (ISessionBean)application.getAttribute("servoy");
	if (servoy_hc == null)
	{
		servoy_hc = HeadlessClientFactory.createSessionBean(request,"busmod_locationHolders");
		session.setAttribute("servoy",servoy_hc);
	}
	boolean ok = servoy_hc.setMainForm("jsp_main");
	if (!ok)
	{
		out.print("error cannot work on required form");
		return;
	}
	
%>
<html>
<head>
<title>DDC Case / File Tracker</title>
</head>
<body>

<%
	String htmlDisplay = (String)servoy_hc.executeMethod("jsp_main","jsp_router", new Object[]{request});
	out.println(htmlDisplay);
%>

</body>
</html>

So, the big difference there is that I am passing the entire request object into Servoy. It allows me to have a very simple JSP page, and have Servoy do all of the work…including what to display. So, then my jsp_router method looks something like this.

var jspRequest = arguments[0]
var jspAction = jspRequest.getParameter("jspAction")

if(jspAction == "" || jspAction == null || jspAction == "home")
	return jsp_mainSearchForm();
else if(jspAction == "search")
	return jsp_caseNoSearch(jspRequest);
else if(jspAction == "showQueue")
	return jsp_showRequestQueue();
else if(jspAction == "requestFile")
	return jsp_requestFile(jspRequest);
else
	return "Invalid jspAction:" + jspAction;

So, that method just acts as a router, and then the other methods (like jsp_mainSearchForm) perform some queries and return back HTML to be displayed. Actions and variables are passed using ```


So far, this is working with multiple users. Does anyone see any problems doing it this way? I know this isn't ideal for "record based" type of solutions, but this is just a query and return type of solution. (it is actually a way to request that a box or folder be pulled from the archive warehouse and given to the requestor)

There is no problem, only that you will not be able to serve thousands of users at the same time, but only sequentially.

Could someone shed some light on this please? Will this code:

<%@ page import = “java.util." %>
<%@ page import = "com.servoy.j2db.server.headlessclient.
” %>
<%@ page import = “com.servoy.j2db.dataprocessing.IDataSet” %>
<%@ page errorPage=“errorpage.jsp” %>
<%
ISessionBean servoy_hc = (ISessionBean)application.getAttribute(“servoy”);
if (servoy_hc == null)
{
servoy_hc = HeadlessClientFactory.createSessionBean(request,“busmod_locationHolders”);
session.setAttribute(“servoy”,servoy_hc);
}
boolean ok = servoy_hc.setMainForm(“jsp_main”);
if (!ok)
{
out.print(“error cannot work on required form”);
return;
}

%>

give the same result as this one:

<%@ page import = “java.util." %>
<%@ page import = "com.servoy.j2db.server.headlessclient.
” %>
<%@ page import = “com.servoy.j2db.dataprocessing.IDataSet” %>
<%@ page errorPage=“errorpage.jsp” %>
<%
ISessionBean servoy_hc = (ISessionBean)application.getAttribute(“servoy”);
if (servoy_hc == null)
{
servoy_hc = HeadlessClientFactory.createSessionBean(request,“busmod_locationHolders”);
application.setAttribute(“servoy”,servoy_hc);
}
boolean ok = servoy_hc.setMainForm(“jsp_main”);
if (!ok)
{
out.print(“error cannot work on required form”);
return;
}

%>

If not, what would be the difference? :?:

And speaking of the possibilty, with SHC, to

serve thousands of users at the same time, but only sequentially

,

what caveats might there be in such a scenario? In other words, what happens if :

  • User A connects using SHC and views Record 1 on Form ‘Details’
  • then User B connects using the Smart or Web client and view Form ‘List’
  • then User C connects using SHC and views Record 6 on Form ‘Contacts’
  • after which User A makes a change in the DB to Record 1
  • then User C changes the record he/she is looking at

Will the changes made by User C be applied to Record 1 or to Record 6? I’m just trying to get an exact notion of what to look out for in such a situation and to get a clear feeling of what the ‘sequential’ aspect involves here.

TIA,

Ben

Hi Ben,

LOGIsoft:
If not, what would be the difference? :?:

  • Using Session then each unique visitor of your site will get it’s own instance of Servoy Headless Client.
  • Using Application each unique visitor will use the same instance of Servoy Headless Client.
    So in this situation all requests send to that instance of SHC will be handled sequential.

LOGIsoft:
And speaking of the possibilty, with SHC, to

serve thousands of users at the same time, but only sequentially

,

what caveats might there be in such a scenario? In other words, what happens if :

  • User A connects using SHC and views Record 1 on Form ‘Details’
  • then User B connects using the Smart or Web client and view Form ‘List’
  • then User C connects using SHC and views Record 6 on Form ‘Contacts’
  • after which User A makes a change in the DB to Record 1
  • then User C changes the record he/she is looking at

Will the changes made by User C be applied to Record 1 or to Record 6? I’m just trying to get an exact notion of what to look out for in such a situation and to get a clear feeling of what the ‘sequential’ aspect involves here.

When using 1 instance of SHC you need to make sure in your code that the user sending the request is updating/deleting/viewing the correct record/foundset because user B might have changed the foundset after user A, etc.
When using a session instance (thus a SHC per user) then Servoy already knows what foundset/record you are in.

Also the use of globals is of concern in a single instance approach.

I hope this helps.

Thanks Robert for your insight on this. The first part of my question had more to do with the fact I was wondering if the statements

ISessionBean servoy_hc = (ISessionBean)application.getAttribute("servoy"); 
...
application.setAttribute("servoy",servoy_hc);

and

ISessionBean servoy_hc = (ISessionBean)session.getAttribute("servoy"); 
...
session.setAttribute("servoy",servoy_hc);

constituted a pair of sorts, or if they could be interchanged somehow. I’m asking because earlier in this post you pair them, whereas later on Scott doesn’t and says his code is working, so I’m a bit confused. :? In other words, would these work also:

ISessionBean servoy_hc = (ISessionBean)application.getAttribute("servoy"); 
...
session.setAttribute("servoy",servoy_hc);
ISessionBean servoy_hc = (ISessionBean)session.getAttribute("servoy"); 
...
application.setAttribute("servoy",servoy_hc);

Also, if I understand correctly, a single-instance SHC will have shared globals (and everything else, I guess), so do you mean to say that, for each and every action taken via SHC using this approach, we have to make sure exactly where the user is and what he/she was viewing at that time? Seems next to impossible to manage in a solution involving a bit of complexity… Are there hints/tips on achieving this to be had anywhere?

Sincerely,

Ben