Here I am with another post about DataSnap 2010. This time we will to talk about HTTP Tunneling which allows you to implement redundant solutions like Failover and Load Balancing in DataSnap applications. Questions about this subject are very frequent and I will give you, as an example, an overview using Failover. After reading this post you will be able to understand how you can implement Failover in your DataSnap applications and then use that to implement other redundant solution, like Load Balancing.
When we started to think about application servers as part of our N-tier development we had many goals like centralized processes, business rules, hardware investments, updates, etc. When we think about a centralized process, we also need to think about redundancy, which is the duplication of critical components of a system with the intention of increasing reliability , usually via a backup or fail-safe.
Before Delphi 2010, failover or load balance was not easy to implement, but now it is another story.
DataSnap 2010 brings a feature named HTTP Tunneling which allow you to have control of the data sent and received between the client and the server. HTTP Tunneling communicates through the HTTP protocol. Thus, you have to use that for the communication between client and server, which is not a problem.
When you implement Load Balancing or Failover, it means you will need a middleware application to control things. This application will be responsible for receiving the data from the client application, analyzing it, and forwarding it to the appropriate Server.
Translating that to the DataSnap world, theclient application connects to the Failover Server which is our proxy and it will forward the connection to the appropriate DataSnap Server in case of the primary connection fail. This post will simulate a client application sending/receiving data, while at some point the main DataSnap Server will crash, and you will see the Failover Server redirecting the connection to a secondary DataSnap Server.
If you are looking to implement this solution in your current DataSnap project and worried about what changes are necessary to support that, don’t worry. You will only need two changes on the client application:
- Define HTTP as connection protocol in your SQL Connection
- Start to connect on the Failover Server and not directly in your DataSnap Server
Beside that you need to create your Failover Server, and you can use this demo code as a start.
The Failover Server needs two components, the DSHTTPService which represent your server and is connected to the DSHTTPServiceAuthenticationManager for the authentication process, only authorized users can connect on the server.
To enable the HTTP Tunneling feature will you need to implement the follow events the HTTP Service Tunnel Service, which are:
These events are executed during the communication process. The event names explain what they do, and the sample used on this post implements all of them. The sample has a log which will help you to see what is happening during the communication.
In the case of the Failover solution, all the events need to be implemented. The events OnErrorXXX will be executed when something goes wrong. These events will allow you identify and decide what to do with the bytes transferred. I will focus on the event OnErrorOpenSession which will redirect the connection in case of error during the opening session.
The follow code implements a method named Redirect which is associated with the event OnErrorOpenSession. You can see how the session data is represented by parameters on this method, and how it includes everything you need to redirect the data.
In this sample we use the Session.UserFlag to control if the connection was already redirected.We are only allowing one redirection, and in case that the Sender parameter becomes anException, we will save the error message in our log. After that we created an instance of DBXProperties which has the new redirection server information. I’m using the same HostName and changed the port to 213, differentiating it from the other DataSnap Server on the same machine, for demo purposes.
After that just reopen the session passing the new properties as parameter and it’s done — that is all you need.
procedure TForm6.Redirect(Sender: TObject; Session: TDSTunnelSession; Content: TBytes; var Count: Integer); var DBXProperties: TDBXDatasnapProperties; Msg: String; begin if Sender is Exception then Msg := Exception(Sender).Message; Log('>>' + Msg); if Session.UserFlag = 1 then Raise Exception.Create('Backup session cannot be redirected once more.' + Msg); DBXProperties := TDBXDatasnapProperties.Create(nil); DBXProperties.Values[TDBXPropertyNames.DriverName] := 'Datasnap'; DBXProperties.Values[TDBXPropertyNames.HostName] := 'localhost'; DBXProperties.Values[TDBXPropertyNames.Port] := '213'; try try Session.Reopen(DBXProperties); Session.UserFlag := 1; Msg := 'Flow commuted to alternate resource.'; Log('>>' + Msg); except Raise Exception.Create(Msg + '. Commuting to alternate resource failed.'); end; finally DBXProperties.free; end; end;
In case you are want to run the sample code in your machine, here the steps you need for that.
The sample includes two projects: Failover Server and DataSnap Server. We will use DataExplorer as our client application. Using the follow steps you will be able to see the Failover Server in action.
- Open and execute the Failover server, the sample use HTTP protocol and port 8080
- Execute the DataSnap Server twice, one using port 211 and other one port 213. The server using the port 213 will work as the backup server
- Create a DataSnap alias in your Data Explorer, remembering to configure it to use HTTP as protocol and port 8080
- On the Stored Procedure node, find the method EchoString, pass the value Delphi 2010 as parameter and execute. The return value will be Delphi 2010 (Server 211)
- Close the DataSnap Server that runs on the port 211
- Repeat the step 4 and look the return value, which should be Delphi 2010 (Server 213)
- Now look the log on the Failover Server, you will see the exception error and the redirection log information
Also, I prepared a short video where I present how to execute this sample.
You can download the source code here