Application Design for local/LAN/WAN

Posts   
 
    
davisg avatar
davisg
User
Posts: 113
Joined: 27-Feb-2005
# Posted on: 13-Jul-2005 21:40:21   

Hi All,

I am designing an application for the public sector using LLBLGen Pro (of course simple_smile ) and want it to connect to it's database in a variety of different ways so I am wondering if others out there can give me some tips/advice on the best way to accomplish this.

Basically the application must be able to connect to a database either locally, via the LAN or over WAN. So I need the application to talk through LLBLGen Pro to the database directly, through remoting or via a web service if I was to use the recommended technologies.

What I am trying to avoid is set up hell for the user though so I was thinking whether or not I could just get away with using web services hosted in a Windows Service application for all scenarios. I know that asmx files can be run without IIS. (Cassini for example) but is that a recommended way?

My thoughts on how the application would be installed and the scenarios for it's use are as follows:

Installation

a) Application - The client application that will connect to the windows service hosting a customised Cassini server, call this WSCS from now on (Not trademarked that yet wink ) This can be installed on it's own to allow connection to a remote WSCS via LAN or WAN.

b) Server - The WSCS application. This can be installed on it's own to allow local or other remote clients to connect to it.

Scenarios

  1. Single User

Connects to the WSCS via http://127.0.0.1:8500

  1. LAN User

Configuration changes can be made in the application to allow the application to connect to a LAN based WSCS on http://192.168.0.1:8500

  1. WAN User

Configuration changes can be made in the application to allow the application to connect to a WAN based WSCS via the internet on http://10.0.0.0:8500

I have probably missed a lot of gotcha's here but it would be good to hear from others who might have already delved into this territory and put me on the straight and narrow on how it should be done or even give me loads of pointers stuck_out_tongue_winking_eye

I know that Cassini can only run under 2000 and XP so no 98/Me support but would that be considered a bad thing for example knowing that the application is going to the public sector?

Thanks for listening.

Geoff.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39801
Joined: 17-Aug-2003
# Posted on: 14-Jul-2005 10:17:44   

I think the easiest way is to setup a remoting service for all situations, UNLESS you need webservice support for other clients, like java clients. Remoting has the advantage that you don't have to fight with vs.net's generated proxy classes when you refresh a webreference.

Frans Bouma | Lead developer LLBLGen Pro
davisg avatar
davisg
User
Posts: 113
Joined: 27-Feb-2005
# Posted on: 14-Jul-2005 10:24:17   

Otis wrote:

I think the easiest way is to setup a remoting service for all situations, UNLESS you need webservice support for other clients, like java clients. Remoting has the advantage that you don't have to fight with vs.net's generated proxy classes when you refresh a webreference.

Frans, I was under the impression that remoting should only be used for the LAN, would it work well for WAN access as well?

Geoff.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39801
Joined: 17-Aug-2003
# Posted on: 14-Jul-2005 13:05:08   

WAN with slow connections? That could be slower indeed, but if you want to make that performant, you have to define your own XML messages which can be small, and setup a contract-first XML webservice. (thus not passing around entities or datatables, but messages).

Frans Bouma | Lead developer LLBLGen Pro
davisg avatar
davisg
User
Posts: 113
Joined: 27-Feb-2005
# Posted on: 14-Jul-2005 14:39:24   

Otis wrote:

WAN with slow connections? That could be slower indeed, but if you want to make that performant, you have to define your own XML messages which can be small, and setup a contract-first XML webservice. (thus not passing around entities or datatables, but messages).

Frans, thanks for your suggestions. simple_smile

Although I don't see any problem with the UI connecting to a remoting server locally or on the LAN, the WAN will need some further research. I think it is proof of concept time and write me a small app to see how well this can be achieved. Connecting through the WAN would be the least used function of the program IMO but needs to be offered for allowing users to connect to their office from home.

On a side-note I have decided that no data will come to the client unless the user has asked for it abeit this being different to my competitors but then again they are all single user applications anyway and can afford the luxury of displaying 1000's of lines in a tree control directly from a local DB. I don't want a different UI for each scenario either so I think it is best to adopt the 'User want do you want to search for' routine. Hope this is what others would do for distributed apps. wink

Wonder if devildog has any experience using WAN distributed apps? devildog? frowning

Geoff.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39801
Joined: 17-Aug-2003
# Posted on: 15-Jul-2005 10:11:22   

davisg wrote:

Otis wrote:

WAN with slow connections? That could be slower indeed, but if you want to make that performant, you have to define your own XML messages which can be small, and setup a contract-first XML webservice. (thus not passing around entities or datatables, but messages).

Frans, thanks for your suggestions. simple_smile

Although I don't see any problem with the UI connecting to a remoting server locally or on the LAN, the WAN will need some further research. I think it is proof of concept time and write me a small app to see how well this can be achieved. Connecting through the WAN would be the least used function of the program IMO but needs to be offered for allowing users to connect to their office from home.

So that would mean the user has to be able to use the same client from different locations. To ease your work, I'd opt for 1 general solution for all clients, so just 1 transport format.

On a side-note I have decided that no data will come to the client unless the user has asked for it abeit this being different to my competitors but then again they are all single user applications anyway and can afford the luxury of displaying 1000's of lines in a tree control directly from a local DB. I don't want a different UI for each scenario either so I think it is best to adopt the 'User want do you want to search for' routine. Hope this is what others would do for distributed apps. wink

Heh simple_smile Yeah the first thing to do when you want to kill a distributed app is by using it as if the remote resource is local

Frans Bouma | Lead developer LLBLGen Pro
davisg avatar
davisg
User
Posts: 113
Joined: 27-Feb-2005
# Posted on: 15-Jul-2005 10:48:39   

Otis wrote:

So that would mean the user has to be able to use the same client from different locations. To ease your work, I'd opt for 1 general solution for all clients, so just 1 transport format.

Exactly simple_smile , same client for different locations whether that be locally, LAN or WAN. Remoting seems to be the more favourable scenario. Each installation will consist of a client and a server application, the client can connect to it's local server or connect to LAN or WAN server.

I haven't yet decided on how to tackle the licensing for this scenario yet, i.e. server can only have a number of connections based on a license, etc... What I do want though is if a user purchased a single user license; I would like them to be able to connect to the database locally or over the internet as well. hmmm, think I have just answered that myself, number of connections based on license. That way anybody can download the client to connect to a server, interesting... Does that sound good to you or can you see something I am overlooking here?

Otis wrote:

Heh simple_smile Yeah the first thing to do when you want to kill a distributed app is by using it as if the remote resource is local

Yeah, changes the whole UI look and feel based on competitors but I think it will be worth it providing I can give the users some really good filter presets simple_smile

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39801
Joined: 17-Aug-2003
# Posted on: 16-Jul-2005 14:02:40   

davisg wrote:

Otis wrote:

So that would mean the user has to be able to use the same client from different locations. To ease your work, I'd opt for 1 general solution for all clients, so just 1 transport format.

Exactly simple_smile , same client for different locations whether that be locally, LAN or WAN. Remoting seems to be the more favourable scenario. Each installation will consist of a client and a server application, the client can connect to it's local server or connect to LAN or WAN server.

I haven't yet decided on how to tackle the licensing for this scenario yet, i.e. server can only have a number of connections based on a license, etc... What I do want though is if a user purchased a single user license; I would like them to be able to connect to the database locally or over the internet as well. hmmm, think I have just answered that myself, number of connections based on license. That way anybody can download the client to connect to a server, interesting... Does that sound good to you or can you see something I am overlooking here?

You then do need encryption to send the license key to check on the server. I'm not sure if that's easy to do, but it can be an option.

Frans Bouma | Lead developer LLBLGen Pro
Devildog74
User
Posts: 719
Joined: 04-Feb-2004
# Posted on: 17-Jul-2005 16:15:11   

Do you have a presentation layer that can connect to different end points of a service hosted on a server, or does the service application live on the cleints and simply needs to change the connection string used by llblgen at runtime?

If you are trying to acheive the first, I would next ask , 1. are all clients .NET based?, 2. do clients get to choose how and when they will connect? 3. How can I acheive this and reduce the number of moving parts in the solution? 4. how will clients learn about the end points? 5. how can I easily publish the service contract (i.e. interfaces) to the client when the service layer changes

In one of my applications, which was pure a .NET client and a .NET services layer, I created a load balancing solution that may assist you in helping the client determine the endpoint to use. I created a web service that tracked end points and returned the "best endpoint" to the client. Basically, it was a web service that had registration methods for remote services to invoke, and it had methods for clients to invoke, which would return the end point for the client to use. There was logic tied into the web method invoked by the cleint that would determine the end point to use. Once the client received the end point, they simply used the endpoint information to begin invoking the remote services layer.

If you host a services layer in IIS, it should be easily available over the LAN and WAN.

If your answer to #1 is yes, then I would reccomend remoting. In the future if you need a new client, i.e. a jsp consumer or something, just wrap the services layer in a web service.

Regardless of the answer to #2, you would need to figure out the answer to #4.

Regarding question 3, In my opinion, choosing an across the board approach for all clients out of the box will make your life easier. If you need it done simple and fast and are willing to sacrafice extensibility and flexibility, then web services might be better. I personally would choose remoting, because if the core service is remoting based, you can always extend it and build upon it later, i.e. a web services facade.

Regarding question #5, if youre using web services, and the service layer changes, the client needs to get a new copy of the code generated by the wsdl. If you are using remoting, the client would need to get a new copy of the assemblies that contain the interfaces. No matter which approach you choose, I would make sure that code generated from wsdl, or the published interfaces for the remoting layer, lived in a seperate assembly outside of the client assembly.

I hope this makes sense.

Rogelio
User
Posts: 221
Joined: 29-Mar-2005
# Posted on: 17-Jul-2005 17:16:55   

Hi,

I have done the following with my applications:

  • All BusinessClasses have an Interface, example ICustomerBusiness.

  • A business-service interface, IBusinessService, that define functions to return business-object and a business-service classes (LocalService, RemotingService, WebService) that implement IBusinessService:


Public Class LocalService
Implement IBusinessService

           Public Function GetCustomerBusiness() as ICustomerBusiness Implements IBusinessService.GetCustomerBusiness
                 Return CustomerBusiness.Instance
           End Function
     End Class

All the business classes are services with the singleton pattern; but that could be change to return a new instance. The Instance property allow to change the business class from return a single instance to return a new instance, without changing the code that consume it.

  • A business-service factory that return the instace of the business-object factory to use, depending of the configuration. BusinessFactory.GetBusinessService

The GetBusinessService function return the instance of: LocalService or RemotingService or WebService.

All of this allow:

       Dim customerBS as ICustomerBusiness = BusinessFactory.GetBusinessService.GetCustomerBusiness
      Dim customer as CustomerEntity
    
      customer = customerBS.GetByPK(pk)


Devildog74
User
Posts: 719
Joined: 04-Feb-2004
# Posted on: 17-Jul-2005 18:00:38   

Rogelio, is this a correct statement, you have an abstract factory that returns a a type, and the type returned contains the concrete implementation for communicating with the services layere?

If thats what you are doing that is pretty sweet, because that would imply that you could create different mechanisms to detect endpoints.

davisg avatar
davisg
User
Posts: 113
Joined: 27-Feb-2005
# Posted on: 18-Jul-2005 10:42:23   

Devildog74 wrote:

Do you have a presentation layer that can connect to different end points of a service hosted on a server, or does the service application live on the cleints and simply needs to change the connection string used by llblgen at runtime?

Forgive me as I don't really know what an end point of a service hosted on a server really means but I will try and explain a little more on what I am trying to achieve hopefully in an attempt to answer this question:

I am writing an application that will allow a user to catalogue items into a database. I want the user to be able to connect to the database through his local machine, over the LAN or via the internet.

Because I have been spending a lot of time thinking about how I am going to license this product it has really answered a lot of the questions as to which way it will need to be developed, if that makes sense.

I now know that I need a client and a server application to cater for all connection methods. Both the client and the server will be .NET based and it looks like .NET remoting is the way to go. The reason for this is the licensing, I think.

I don't want to license the client application at all. In fact the client application would be available to anybody but it's totally useless on it's own, it needs to connect to a server.

The server license will be tied to the machine it's running on and will have some kind of concurrent user/number of client license creation restriction. The server will have the ability to generate a client license to which the user will send to the end user. It's this license that will determine if the client can connect to the server. The client on startup reads all client license files and builds a 'Which server would you like to connect to?' listbox for example. Well thats my theory.

There are a couple of things I need to work on like what is to stop a single client license generated being sent to 1000's of users to get connection to the server at the same time. Should I care? I have already been paid for the server license but if possible I only want one client license to be able to connect to the server at any one time no matter who the user sends it to. Also there will be a facility to revoke a client license too.

So to summarise: a single user licensed server can generate one active client license and this license can be used locally or over the internet.

Devildog74 wrote:

If you are trying to acheive the first, I would next ask , 1. are all clients .NET based?, 2. do clients get to choose how and when they will connect? 3. How can I acheive this and reduce the number of moving parts in the solution? 4. how will clients learn about the end points? 5. how can I easily publish the service contract (i.e. interfaces) to the client when the service layer changes

  1. Yes
  2. Yes
  3. Hopefully through remoting, just 1 client and 1 server application for all scenarios.
  4. Through the client license. Haven't decided if I want to tie the server and port information into the client license yet. The server application might send the end user an email of the server and port information when it sends them a client license. Needs more thought.
  5. This is a difficult one and the one I have spent least time thinking about but I suppose I will use some sort of auto update in both the server and the client from my own website to try and keep the product sync'd.

Devildog74 wrote:

In one of my applications, which was pure a .NET client and a .NET services layer, I created a load balancing solution that may assist you in helping the client determine the endpoint to use. I created a web service that tracked end points and returned the "best endpoint" to the client. Basically, it was a web service that had registration methods for remote services to invoke, and it had methods for clients to invoke, which would return the end point for the client to use. There was logic tied into the web method invoked by the cleint that would determine the end point to use. Once the client received the end point, they simply used the endpoint information to begin invoking the remote services layer.

This is brill stuff but I don't think this will fit my solution.

Devildog74 wrote:

If you host a services layer in IIS, it should be easily available over the LAN and WAN.

Worried about end users abilities.

Devildog74 wrote:

If your answer to #1 is yes, then I would reccomend remoting. In the future if you need a new client, i.e. a jsp consumer or something, just wrap the services layer in a web service.

Regardless of the answer to #2, you would need to figure out the answer to #4.

Regarding question 3, In my opinion, choosing an across the board approach for all clients out of the box will make your life easier. If you need it done simple and fast and are willing to sacrafice extensibility and flexibility, then web services might be better. I personally would choose remoting, because if the core service is remoting based, you can always extend it and build upon it later, i.e. a web services facade.

Regarding question #5, if youre using web services, and the service layer changes, the client needs to get a new copy of the code generated by the wsdl. If you are using remoting, the client would need to get a new copy of the assemblies that contain the interfaces. No matter which approach you choose, I would make sure that code generated from wsdl, or the published interfaces for the remoting layer, lived in a seperate assembly outside of the client assembly.

I hope this makes sense.

Many thanks for your comments, you have given me plenty to think about and much appreciated.

Geoff.

davisg avatar
davisg
User
Posts: 113
Joined: 27-Feb-2005
# Posted on: 18-Jul-2005 10:44:10   

Rogelio wrote:

Hi,

I have done the following with my applications:

  • All BusinessClasses have an Interface, example ICustomerBusiness.

  • A business-service interface, IBusinessService, that define functions to return business-object and a business-service classes (LocalService, RemotingService, WebService) that implement IBusinessService:


Public Class LocalService
Implement IBusinessService

           Public Function GetCustomerBusiness() as ICustomerBusiness Implements IBusinessService.GetCustomerBusiness
                 Return CustomerBusiness.Instance
           End Function
     End Class

All the business classes are services with the singleton pattern; but that could be change to return a new instance. The Instance property allow to change the business class from return a single instance to return a new instance, without changing the code that consume it.

  • A business-service factory that return the instace of the business-object factory to use, depending of the configuration. BusinessFactory.GetBusinessService

The GetBusinessService function return the instance of: LocalService or RemotingService or WebService.

All of this allow:

       Dim customerBS as ICustomerBusiness = BusinessFactory.GetBusinessService.GetCustomerBusiness
      Dim customer as CustomerEntity
    
      customer = customerBS.GetByPK(pk)


Rogelio,

Wow, thanks for the heads-up, i'll look into that.

Geoff.

Rogelio
User
Posts: 221
Joined: 29-Mar-2005
# Posted on: 18-Jul-2005 12:37:52   

Devildog74 wrote:

Rogelio, is this a correct statement, you have an abstract factory that returns a a type, and the type returned contains the concrete implementation for communicating with the services layere?

If thats what you are doing that is pretty sweet, because that would imply that you could create different mechanisms to detect endpoints.

Yes, the idea is to prepare for any future way to connect to endpoints, for example right now I am only using the LocalService and the RemotingService; but in future if I need to use other way, for example WebService or any other, then that will be easy to implement without changing the code that consume the business objects. This facades also allow me to do extra cleaning after returning the object from the RemotingService, for example if the object returned implement IDisposable then I call the Dispose method inside the Finally of a Try..Catch..Finally.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39801
Joined: 17-Aug-2003
# Posted on: 18-Jul-2005 13:35:18   

Very clever, Rogelio! simple_smile

Frans Bouma | Lead developer LLBLGen Pro
Rogelio
User
Posts: 221
Joined: 29-Mar-2005
# Posted on: 18-Jul-2005 14:47:23   

Otis wrote:

Very clever, Rogelio! simple_smile

Thank you.

Rogelio
User
Posts: 221
Joined: 29-Mar-2005
# Posted on: 18-Jul-2005 15:08:44   

Hi,

Now that we are talking about Remoting and WebService.

Actually I have a RemotingService that call the real RemoteService that is hosted by a Windows service application. The RemotingService expose a public method for each Business object and I have a RemoteService for each Business object; but I was thinking to use only one RemoteService and to change it to expose only one function and to use the concept of message:

      Public Function ProcessMessage(entityType as EntityType,action as Object) as Object
             // instace the business object and return based in action
     End Function

The idea is to avoid expose hundred of RemoteService. This idea could avoid to have to update the WebService's wsdl if I have to implement it.

What do you think?

davisg avatar
davisg
User
Posts: 113
Joined: 27-Feb-2005
# Posted on: 18-Jul-2005 16:13:17   

I know that I am spinning away from the main questions but it's related to my distributed design. This is how I think the licensing will work, comments appreciated as to whether this would or would not work in a Local, LAN or WAN environment.

What I am definately trying to achieve here is that I want an user who bought my application with one user license to be able to connect to the server locally, via the LAN or via the WAN but not concurrently. Also security must be taken into consideration when doing so.

Server

The server application will be licensed and tied to the machine it is running on using XHEO licensing. To make it more interesting the license must also be activated through an XHEO activation server running on my website.

The server license dictates how many client licenses (called it client licenses but I suppose it can be called anything, tokens perhaps, I don't know) can be generated through the server application. The client license generated will contain some information about the server license as well as the following attributes for instance:

  1. description (i.e. internet access)
  2. username and password (optional)
  3. read-only access (optional)
  4. server ip address (optional)
  5. port number (optional)

So a single user server license (What I get paid for!!!) can only generate one client license but the license can be given to whoever they like and this is then copied into the client application license directory or there is a facility in the client that reads it in and makes a copy in the client application license directory.

Likewise a five user server license can generate five client licenses, etc, etc....

Client

The client reads its license directory and builds a list of available servers that it can connect to.

When selecting a server to connect to and depending on the client license attributes it will ask for a username and password (It will only check the username and password against an encrypted value in the license file, no connection to the server will be made) and/or the server ip address and port number (only the server ip address and the port number can be saved in the client configuration).

The client then attempts to connect to the server and checks to see if the client is valid. (Checks client license information against server license information) If it isn’t no connection can be made and a message will be displayed to the client. This can also happen if the server application has revoked the client license for instance. Other attributes could be implemented which triggers this too like ‘hours that client can connect’ or ‘just allow a client license to be valid for a number of days’, etc…

If the client license is valid; the server checks to see if the client license is already logged into the server by checking its internal memory list. If it is no connection can be made a message will be displayed to the client as only one client license can connect to the server at any one time. Want more then buy a larger server license to allow you to generate more client licenses smile

If the server is restarted the internal memory list will be lost but it will start to be populated again as clients request data. I.e. No database cleanup routines needed for using older techniques stuck_out_tongue_winking_eye

To accomodate the internal memory list the server will also disconnect a client license after a timeout value specified on the server configuration in the event that a user has not logged out of the client or the client license can be booted from within the server application.

The timeout value will not be made too small to stop people from taking the piss, say 20 mins, if more than one person has the same client license and trying to use it at the same time I don't mind them waiting this long to post their transaction for the sake of $10 wink

What do you think? Will this work?

Cheers,

Geoff.

Devildog74
User
Posts: 719
Joined: 04-Feb-2004
# Posted on: 18-Jul-2005 19:43:47   

Regarding End Points: An end point is is simply how the client knows where to go to communicate with the services layer. If you imported a WSDL into VS.NET, the code that is created has a pointer to the URL hosting the web service. If you use remoting, you need to know the URL / IP scheme of the remote service host.

In my load balancing scenario, service hosts registered their end points with a web service. Clients would ask the web service for an enpoint before they started communicating with the services layer.

Regarding your licensing scheme: I have used XHEO and I am familiar with the approach you are taking. From what I understand, XHEO provides a service for concurrency that can be run on your web server. As clients become active, they phone home and their license info is saved in a db until they are done with the application. This is how concurrent useage is enforced. Atleast this is my understanding of what is provided with XHEO, but I havent tested it indepth.

What you are trying to do is acheivable.

Instead of storing where a client is allowed to connect on the clients machine, I might make the client figure out where they can connect to at runtime. This allows your customers to move the server side logic around their infrastructure without having to re-configure clients.

You might also consider serializing active clients to disk so that if the service / server gets bounced, you can reload the client tokens into the servers memory when it restarts.

davisg avatar
davisg
User
Posts: 113
Joined: 27-Feb-2005
# Posted on: 18-Jul-2005 20:30:28   

Devildog74 wrote:

Regarding End Points: An end point is is simply how the client knows where to go to communicate with the services layer. If you imported a WSDL into VS.NET, the code that is created has a pointer to the URL hosting the web service. If you use remoting, you need to know the URL / IP scheme of the remote service host.

In my load balancing scenario, service hosts registered their end points with a web service. Clients would ask the web service for an enpoint before they started communicating with the services layer.

Ah right, I understand that terminology now. Good stuff simple_smile

Devildog74 wrote:

Regarding your licensing scheme: I have used XHEO and I am familiar with the approach you are taking. From what I understand, XHEO provides a service for concurrency that can be run on your web server. As clients become active, they phone home and their license info is saved in a db until they are done with the application. This is how concurrent useage is enforced. Atleast this is my understanding of what is provided with XHEO, but I havent tested it indepth.

What you are trying to do is acheivable.

I'll look into that more closely thanks. What I was trying to explain is that the server side application generates a signed XML license that can be dished out to anybody. The client will read the license file for information regarding the server application, not my license server if that makes more sense. This way the client doesn't have to be licensed at all, in fact it could be given away free, this also means that the client doesn't have to contact an external source when working locally or on the LAN. Might have missed something with your approach here so forgive me if i'm going down a wrong route.

Devildog74 wrote:

Instead of storing where a client is allowed to connect on the clients machine, I might make the client figure out where they can connect to at runtime. This allows your customers to move the server side logic around their infrastructure without having to re-configure clients.

I was going to get this information from the XML signed client license that was generated by the server application. My approach here was that the customer can specify the ip address/dns of where the server lives together with the port number in the signed XML license file but if there isn't such information, the client will ask for it's location on attempting to connect and will save this information in an encrypted configuration file for quick connecting next time they run. If the customer moves their infrastructure around then they will have to generate new client license files.

Devildog74 wrote:

You might also consider serializing active clients to disk so that if the service / server gets bounced, you can reload the client tokens into the servers memory when it restarts.

Good point!