You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@thrift.apache.org by jf...@apache.org on 2012/10/11 02:35:51 UTC

svn commit: r1396883 - in /thrift/site: content/tutorial/csharp.md content/tutorial/delphi.md publish/tutorial/csharp/index.html publish/tutorial/delphi/index.html

Author: jfarrell
Date: Thu Oct 11 00:35:51 2012
New Revision: 1396883

URL: http://svn.apache.org/viewvc?rev=1396883&view=rev
Log:
Thrift-1725: Tutorial web pages for Delphi and C#
Client: website
Patch: Jens Geyer

Added tutorials markup for Delphi and C# based on existing tutorials code.


Modified:
    thrift/site/content/tutorial/csharp.md
    thrift/site/content/tutorial/delphi.md
    thrift/site/publish/tutorial/csharp/index.html
    thrift/site/publish/tutorial/delphi/index.html

Modified: thrift/site/content/tutorial/csharp.md
URL: http://svn.apache.org/viewvc/thrift/site/content/tutorial/csharp.md?rev=1396883&r1=1396882&r2=1396883&view=diff
==============================================================================
--- thrift/site/content/tutorial/csharp.md (original)
+++ thrift/site/content/tutorial/csharp.md Thu Oct 11 00:35:51 2012
@@ -7,12 +7,182 @@ library_lang: "csharp"
 ### Prerequisites 
 
 ### Client
+The client uses the generated code to set up the connection and call the server. Our tutorial uses the binary protocol via sockets.
 
-<pre><code class="language-c">	
+<pre><code class="language-c">
+public static void Main()
+{
+    try
+    {
+        TTransport transport = new TSocket("localhost", 9090);
+        TProtocol protocol = new TBinaryProtocol(transport);
+        Calculator.Client client = new Calculator.Client(protocol);
+    
+        transport.Open();
+    
+        client.ping();
+        Console.WriteLine("ping()");
+    
+        int sum = client.add(1, 1);
+        Console.WriteLine("1+1={0}", sum);
+    
+        Work work = new Work();
+    
+        work.Op = Operation.DIVIDE;
+        work.Num1 = 1;
+        work.Num2 = 0;
+        try
+        {
+            int quotient = client.calculate(1, work);
+            Console.WriteLine("Whoa we can divide by 0");
+        }
+        catch (InvalidOperation io)
+        {
+            Console.WriteLine("Invalid operation: " + io.Why);
+        }
+    
+        work.Op = Operation.SUBTRACT;
+        work.Num1 = 15;
+        work.Num2 = 10;
+        try
+        {
+            int diff = client.calculate(1, work);
+            Console.WriteLine("15-10={0}", diff);
+        }
+        catch (InvalidOperation io)
+        {
+            Console.WriteLine("Invalid operation: " + io.Why);
+        }
+    
+        SharedStruct log = client.getStruct(1);
+        Console.WriteLine("Check log: {0}", log.Value);
+    
+        transport.Close();
+    }
+    catch (TApplicationException x)
+    {
+        Console.WriteLine(x.StackTrace);
+    }
+
+}
 </code></pre>
 
 ### Server
+The server main code typically sets up the service endpoint as designed by the developer. The setup is quite similar to the client, except that we use the TServerSocket and need an interface handler instance which will handle the incoming requests.
+<pre><code class="language-c">
+public static void Main()
+{
+    try
+    {
+        CalculatorHandler handler = new CalculatorHandler();
+        Calculator.Processor processor = new Calculator.Processor(handler);
+        TServerTransport serverTransport = new TServerSocket(9090);
+        TServer server = new TSimpleServer(processor, serverTransport);
+        Console.WriteLine("Starting the server...");
+        server.Serve();
+    }
+    catch (Exception x)
+    {
+        Console.WriteLine(x.StackTrace);
+    }
+    Console.WriteLine("done.");
+}
+</code></pre>
+
+### Server Handler
+The server handler class CalculatorHandler implements the communication endpoint interface. The Calculator.Iface interface implemented here is again created by the Thrift compiler from the IDL.
+
+<pre><code class="language-c">    
+public class CalculatorHandler : Calculator.Iface
+{
+    Dictionary<int, SharedStruct> log;
+
+    public CalculatorHandler()
+    {
+        log = new Dictionary<int, SharedStruct>();
+    }
+    
+    public void ping()
+    {
+        Console.WriteLine("ping()");
+    }
+    
+    public int add(int n1, int n2)
+    {
+        Console.WriteLine("add({0},{1})", n1, n2);
+        return n1 + n2;
+    }
+    
+    public int calculate(int logid, Work work)
+    {
+        Console.WriteLine("calculate({0}, [{1},{2},{3}])", logid, work.Op, work.Num1, work.Num2);
+        int val = 0;
+        switch (work.Op)
+        {
+            case Operation.ADD:
+                val = work.Num1 + work.Num2;
+                break;
+    
+            case Operation.SUBTRACT:
+                val = work.Num1 - work.Num2;
+                break;
+    
+            case Operation.MULTIPLY:
+                val = work.Num1 * work.Num2;
+                break;
+    
+            case Operation.DIVIDE:
+                if (work.Num2 == 0)
+                {
+                    InvalidOperation io = new InvalidOperation();
+                    io.What = (int)work.Op;
+                    io.Why = "Cannot divide by 0";
+                    throw io;
+                }
+                val = work.Num1 / work.Num2;
+                break;
+    
+            default:
+                {
+                    InvalidOperation io = new InvalidOperation();
+                    io.What = (int)work.Op;
+                    io.Why = "Unknown operation";
+                    throw io;
+                }
+        }
+    
+        SharedStruct entry = new SharedStruct();
+        entry.Key = logid;
+        entry.Value = val.ToString();
+        log[logid] = entry;
+    
+        return val;
+    }
+    
+    public SharedStruct getStruct(int key)
+    {
+        Console.WriteLine("getStruct({0})", key);
+        return log[key];
+    }
+    
+    public void zip()
+    {
+        Console.WriteLine("zip()");
+    }
+}
+</code></pre>
 
 
 ## Additional Information
 
+Thrift offers a lot more options. For example, in order to use a multithreaded server that can serve multiple requests in parallel, replace the line
+<pre><code class="language-c">    
+    TServer server = new TSimpleServer(processor, serverTransport);
+</code></pre>
+
+with this code: 
+
+<pre><code class="language-c">    
+    TServer server = new TThreadPoolServer(processor, serverTransport);
+</code></pre>
+

Modified: thrift/site/content/tutorial/delphi.md
URL: http://svn.apache.org/viewvc/thrift/site/content/tutorial/delphi.md?rev=1396883&r1=1396882&r2=1396883&view=diff
==============================================================================
--- thrift/site/content/tutorial/delphi.md (original)
+++ thrift/site/content/tutorial/delphi.md Thu Oct 11 00:35:51 2012
@@ -5,13 +5,168 @@ library_lang: "delphi"
 <%= render 'tutorial_intro' %>
 
 ### Prerequisites 
+* Thrift requires at least Delphi 2010. Earlier versions and FPC will not work due to the lack of Generics.
 
 ### Client
+The client uses the generated code to set up the connection and call the server. Our tutorial uses the binary protocol via sockets.
 
 <pre><code class="language-delphi">	
+class procedure DelphiTutorialClient.Main;
+var transport : ITransport;
+    protocol  : IProtocol;
+    client    : TCalculator.Iface;
+    work      : IWork;
+    sum, quotient, diff : Integer;
+    log       : ISharedStruct;
+begin
+  try
+    transport := TSocketImpl.Create( 'localhost', 9090);
+    protocol  := TBinaryProtocolImpl.Create( transport);
+    client    := TCalculator.TClient.Create( protocol);
+
+    transport.Open;
+
+    client.ping;
+    Console.WriteLine('ping()');
+
+    sum := client.add( 1, 1);
+    Console.WriteLine( Format( '1+1=%d', [sum]));
+
+    work := TWorkImpl.Create;
+
+    work.Op   := TOperation.DIVIDE;
+    work.Num1 := 1;
+    work.Num2 := 0;
+    try
+      quotient := client.calculate(1, work);
+      Console.WriteLine( 'Whoa we can divide by 0');
+      Console.WriteLine( Format('1/0=%d',[quotient]));
+    except
+      on io: TInvalidOperation
+      do Console.WriteLine( 'Invalid operation: ' + io.Why);
+    end;
+
+    work.Op   := TOperation.SUBTRACT;
+    work.Num1 := 15;
+    work.Num2 := 10;
+    try
+      diff := client.calculate( 1, work);
+      Console.WriteLine( Format('15-10=%d', [diff]));
+    except
+      on io: TInvalidOperation
+      do Console.WriteLine( 'Invalid operation: ' + io.Why);
+    end;
+
+    log := client.getStruct(1);
+    Console.WriteLine( Format( 'Check log: %s', [log.Value]));
+
+    transport.Close();
+
+  except
+    on e : Exception
+    do Console.WriteLine( e.ClassName+': '+e.Message);
+  end;
+end;
 </code></pre>
 
 ### Server
+The server main code typically sets up the service endpoint as designed by the developer. The setup is quite similar to the client, except that we use the TServerSocketImpl and need an interface handler instance which will handle the incoming requests.
+
+<pre><code class="language-delphi">	
+class procedure DelphiTutorialServer.Main;
+var handler   : TCalculator.Iface;
+    processor : IProcessor;
+    transport : IServerTransport;
+    server    : IServer;
+begin
+  try
+    handler   := TCalculatorHandler.Create;
+    processor := TCalculator.TProcessorImpl.Create( handler);
+    transport := TServerSocketImpl.Create( 9090);
+    server    := TSimpleServer.Create( processor, transport);
+
+    Console.WriteLine( 'Starting the server...');
+    server.Serve();
+
+  except
+    on e: Exception do Console.WriteLine( e.Message);
+  end;
+
+  Console.WriteLine('done.');
+end;
+</code></pre>
+
+### Server Handler
+The server handler class TCalculatorHandler implements the communication endpoint interface. The TCalculator.Iface interface implemented here is again created by the Thrift compiler from the IDL.
+
+<pre><code class="language-delphi">	
+type
+  TCalculatorHandler = class( TInterfacedObject, TCalculator.Iface)
+  protected
+    // TSharedService.Iface
+    function  getStruct(key: Integer): ISharedStruct;
+
+    // TCalculator.Iface
+    procedure ping();
+    function  add(num1: Integer; num2: Integer): Integer;
+    function  calculate(logid: Integer; const w: IWork): Integer;
+    procedure zip();
+
+    // ... more code ...
+  end;
+  
+  
+procedure TCalculatorHandler.ping;
+begin
+  Console.WriteLine( 'ping()');
+end;
+
+
+function TCalculatorHandler.add(num1: Integer; num2: Integer): Integer;
+begin
+  Console.WriteLine( Format( 'add( %d, %d)', [num1, num2]));
+  result := num1 + num2;
+end;
+
+
+function TCalculatorHandler.calculate(logid: Integer; const w: IWork): Integer;
+var entry : ISharedStruct;
+begin
+  try
+    Console.WriteLine( Format('calculate( %d, [%d,%d,%d])', [logid, Ord(w.Op), w.Num1, w.Num2]));
+
+    case w.Op of
+      TOperation.ADD      :  result := w.Num1 + w.Num2;
+      TOperation.SUBTRACT :  result := w.Num1 - w.Num2;
+      TOperation.MULTIPLY :  result := w.Num1 * w.Num2;
+      TOperation.DIVIDE   :  result := Round( w.Num1 / w.Num2);
+    else
+      raise TInvalidOperation.Create( Ord(w.Op), 'Unknown operation');
+    end;
+
+  except
+    on e:Thrift.TException do raise;  // let Thrift Exceptions pass through
+    on e:Exception do raise TInvalidOperation.Create( Ord(w.Op), e.Message);  // repackage all other
+  end;
+
+  entry := TSharedStructImpl.Create;
+  entry.Key   := logid;
+  entry.Value := IntToStr( result);
+  FLog.AddOrSetValue( logid, entry);
+end;
+
+function TCalculatorHandler.getStruct(key: Integer): ISharedStruct;
+begin
+  Console.WriteLine( Format( 'getStruct(%d)', [key]));
+  result := FLog[key];
+end;
+
+
+procedure TCalculatorHandler.zip;
+begin
+  Console.WriteLine( 'zip()');
+end;
+</code></pre>
 
 
 ## Additional Information

Modified: thrift/site/publish/tutorial/csharp/index.html
URL: http://svn.apache.org/viewvc/thrift/site/publish/tutorial/csharp/index.html?rev=1396883&r1=1396882&r2=1396883&view=diff
==============================================================================
--- thrift/site/publish/tutorial/csharp/index.html (original)
+++ thrift/site/publish/tutorial/csharp/index.html Thu Oct 11 00:35:51 2012
@@ -85,11 +85,175 @@
 
 <h3>Client</h3>
 
-<pre><code class="language-c"></code></pre>
+<p>The client uses the generated code to set up the connection and call the server. Our tutorial uses the binary protocol via sockets.</p>
+
+<pre><code class="language-c">public <span style="color:#088;font-weight:bold">static</span> <span style="color:#088;font-weight:bold">void</span> Main()
+{
+    try
+    {
+        TTransport transport = new TSocket(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">localhost</span><span style="color:#710">"</span></span>, <span style="color:#00D">9090</span>);
+        TProtocol protocol = new TBinaryProtocol(transport);
+        Calculator.Client client = new Calculator.Client(protocol);
+    
+        transport.Open();
+    
+        client.ping();
+        Console.WriteLine(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">ping()</span><span style="color:#710">"</span></span>);
+    
+        <span style="color:#0a5;font-weight:bold">int</span> sum = client.add(<span style="color:#00D">1</span>, <span style="color:#00D">1</span>);
+        Console.WriteLine(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">1+1={0}</span><span style="color:#710">"</span></span>, sum);
+    
+        Work work = new Work();
+    
+        work.Op = Operation.DIVIDE;
+        work.Num1 = <span style="color:#00D">1</span>;
+        work.Num2 = <span style="color:#00D">0</span>;
+        try
+        {
+            <span style="color:#0a5;font-weight:bold">int</span> quotient = client.calculate(<span style="color:#00D">1</span>, work);
+            Console.WriteLine(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">Whoa we can divide by 0</span><span style="color:#710">"</span></span>);
+        }
+        catch (InvalidOperation io)
+        {
+            Console.WriteLine(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">Invalid operation: </span><span style="color:#710">"</span></span> + io.Why);
+        }
+    
+        work.Op = Operation.SUBTRACT;
+        work.Num1 = <span style="color:#00D">15</span>;
+        work.Num2 = <span style="color:#00D">10</span>;
+        try
+        {
+            <span style="color:#0a5;font-weight:bold">int</span> diff = client.calculate(<span style="color:#00D">1</span>, work);
+            Console.WriteLine(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">15-10={0}</span><span style="color:#710">"</span></span>, diff);
+        }
+        catch (InvalidOperation io)
+        {
+            Console.WriteLine(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">Invalid operation: </span><span style="color:#710">"</span></span> + io.Why);
+        }
+    
+        SharedStruct log = client.getStruct(<span style="color:#00D">1</span>);
+        Console.WriteLine(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">Check log: {0}</span><span style="color:#710">"</span></span>, log.Value);
+    
+        transport.Close();
+    }
+    catch (TApplicationException x)
+    {
+        Console.WriteLine(x.StackTrace);
+    }
+
+}</code></pre>
 
 <h3>Server</h3>
 
+<p>The server main code typically sets up the service endpoint as designed by the developer. The setup is quite similar to the client, except that we use the TServerSocket and need an interface handler instance which will handle the incoming requests.
+</p><pre><code class="language-c">public <span style="color:#088;font-weight:bold">static</span> <span style="color:#088;font-weight:bold">void</span> Main()
+{
+    try
+    {
+        CalculatorHandler handler = new CalculatorHandler();
+        Calculator.Processor processor = new Calculator.Processor(handler);
+        TServerTransport serverTransport = new TServerSocket(<span style="color:#00D">9090</span>);
+        TServer server = new TSimpleServer(processor, serverTransport);
+        Console.WriteLine(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">Starting the server...</span><span style="color:#710">"</span></span>);
+        server.Serve();
+    }
+    catch (Exception x)
+    {
+        Console.WriteLine(x.StackTrace);
+    }
+    Console.WriteLine(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">done.</span><span style="color:#710">"</span></span>);
+}</code></pre>
+
+<h3>Server Handler</h3>
+
+<p>The server handler class CalculatorHandler implements the communication endpoint interface. The Calculator.Iface interface implemented here is again created by the Thrift compiler from the IDL.</p>
+
+<pre><code class="language-c">public class CalculatorHandler : Calculator.Iface
+{
+    Dictionary log;
+
+    public CalculatorHandler()
+    {
+        log = new Dictionary();
+    }
+    
+    public <span style="color:#088;font-weight:bold">void</span> ping()
+    {
+        Console.WriteLine(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">ping()</span><span style="color:#710">"</span></span>);
+    }
+    
+    public <span style="color:#0a5;font-weight:bold">int</span> add(<span style="color:#0a5;font-weight:bold">int</span> n1, <span style="color:#0a5;font-weight:bold">int</span> n2)
+    {
+        Console.WriteLine(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">add({0},{1})</span><span style="color:#710">"</span></span>, n1, n2);
+        <span style="color:#080;font-weight:bold">return</span> n1 + n2;
+    }
+    
+    public <span style="color:#0a5;font-weight:bold">int</span> calculate(<span style="color:#0a5;font-weight:bold">int</span> logid, Work work)
+    {
+        Console.WriteLine(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">calculate({0}, [{1},{2},{3}])</span><span style="color:#710">"</span></span>, logid, work.Op, work.Num1, work.Num2);
+        <span style="color:#0a5;font-weight:bold">int</span> val = <span style="color:#00D">0</span>;
+        <span style="color:#080;font-weight:bold">switch</span> (work.Op)
+        {
+            <span style="color:#080;font-weight:bold">case</span> Operation.ADD:
+                val = work.Num1 + work.Num2;
+                <span style="color:#080;font-weight:bold">break</span>;
+    
+            <span style="color:#080;font-weight:bold">case</span> Operation.SUBTRACT:
+                val = work.Num1 - work.Num2;
+                <span style="color:#080;font-weight:bold">break</span>;
+    
+            <span style="color:#080;font-weight:bold">case</span> Operation.MULTIPLY:
+                val = work.Num1 * work.Num2;
+                <span style="color:#080;font-weight:bold">break</span>;
+    
+            <span style="color:#080;font-weight:bold">case</span> Operation.DIVIDE:
+                <span style="color:#080;font-weight:bold">if</span> (work.Num2 == <span style="color:#00D">0</span>)
+                {
+                    InvalidOperation io = new InvalidOperation();
+                    io.What = (<span style="color:#0a5;font-weight:bold">int</span>)work.Op;
+                    io.Why = <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">Cannot divide by 0</span><span style="color:#710">"</span></span>;
+                    throw io;
+                }
+                val = work.Num1 / work.Num2;
+                <span style="color:#080;font-weight:bold">break</span>;
+    
+            <span style="color:#080;font-weight:bold">default</span>:
+                {
+                    InvalidOperation io = new InvalidOperation();
+                    io.What = (<span style="color:#0a5;font-weight:bold">int</span>)work.Op;
+                    io.Why = <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">Unknown operation</span><span style="color:#710">"</span></span>;
+                    throw io;
+                }
+        }
+    
+        SharedStruct entry = new SharedStruct();
+        entry.Key = logid;
+        entry.Value = val.ToString();
+        log[logid] = entry;
+    
+        <span style="color:#080;font-weight:bold">return</span> val;
+    }
+    
+    public SharedStruct getStruct(<span style="color:#0a5;font-weight:bold">int</span> key)
+    {
+        Console.WriteLine(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">getStruct({0})</span><span style="color:#710">"</span></span>, key);
+        <span style="color:#080;font-weight:bold">return</span> log[key];
+    }
+    
+    public <span style="color:#088;font-weight:bold">void</span> zip()
+    {
+        Console.WriteLine(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">zip()</span><span style="color:#710">"</span></span>);
+    }
+}</code></pre>
+
 <h2>Additional Information</h2>
+
+<p>Thrift offers a lot more options. For example, in order to use a multithreaded server that can serve multiple requests in parallel, replace the line
+</p><pre><code class="language-c">    TServer server = new TSimpleServer(processor, serverTransport);</code></pre>
+
+<p>with this code: </p>
+
+<pre><code class="language-c">    TServer server = new TThreadPoolServer(processor, serverTransport);</code></pre>
 	</div>
 	<div class="container">
 	<hr>

Modified: thrift/site/publish/tutorial/delphi/index.html
URL: http://svn.apache.org/viewvc/thrift/site/publish/tutorial/delphi/index.html?rev=1396883&r1=1396882&r2=1396883&view=diff
==============================================================================
--- thrift/site/publish/tutorial/delphi/index.html (original)
+++ thrift/site/publish/tutorial/delphi/index.html Thu Oct 11 00:35:51 2012
@@ -83,12 +83,166 @@
 <li><p>Followed all prerequesets listed </p></li>
 </ol><h3>Prerequisites</h3>
 
-<h3>Client</h3>
+<ul>
+<li>Thrift requires at least Delphi 2010. Earlier versions and FPC will not work due to the lack of Generics.</li>
+</ul><h3>Client</h3>
 
-<pre><code class="language-delphi"></code></pre>
+<p>The client uses the generated code to set up the connection and call the server. Our tutorial uses the binary protocol via sockets.</p>
+
+<pre><code class="language-delphi"><span style="color:#080;font-weight:bold">class</span> <span style="color:#080;font-weight:bold">procedure</span> DelphiTutorialClient.Main;
+<span style="color:#080;font-weight:bold">var</span> transport : ITransport;
+    protocol  : IProtocol;
+    client    : TCalculator.Iface;
+    work      : IWork;
+    sum, quotient, diff : Integer;
+    log       : ISharedStruct;
+<span style="color:#080;font-weight:bold">begin</span>
+  <span style="color:#080;font-weight:bold">try</span>
+    transport := TSocketImpl.Create( <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">'</span><span style="color:#D20">localhost</span><span style="color:#710">'</span></span>, <span style="color:#00D">9090</span>);
+    protocol  := TBinaryProtocolImpl.Create( transport);
+    client    := TCalculator.TClient.Create( protocol);
+
+    transport.Open;
+
+    client.ping;
+    Console.WriteLine(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">'</span><span style="color:#D20">ping()</span><span style="color:#710">'</span></span>);
+
+    sum := client.add( <span style="color:#00D">1</span>, <span style="color:#00D">1</span>);
+    Console.WriteLine( Format( <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">'</span><span style="color:#D20">1+1=%d</span><span style="color:#710">'</span></span>, [sum]));
+
+    work := TWorkImpl.Create;
+
+    work.Op   := TOperation.DIVIDE;
+    work.Num1 := <span style="color:#00D">1</span>;
+    work.Num2 := <span style="color:#00D">0</span>;
+    <span style="color:#080;font-weight:bold">try</span>
+      quotient := client.calculate(<span style="color:#00D">1</span>, work);
+      Console.WriteLine( <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">'</span><span style="color:#D20">Whoa we can divide by 0</span><span style="color:#710">'</span></span>);
+      Console.WriteLine( Format(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">'</span><span style="color:#D20">1/0=%d</span><span style="color:#710">'</span></span>,[quotient]));
+    <span style="color:#080;font-weight:bold">except</span>
+      <span style="color:#088;font-weight:bold">on</span> io: TInvalidOperation
+      <span style="color:#080;font-weight:bold">do</span> Console.WriteLine( <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">'</span><span style="color:#D20">Invalid operation: </span><span style="color:#710">'</span></span> + io.Why);
+    <span style="color:#080;font-weight:bold">end</span>;
+
+    work.Op   := TOperation.SUBTRACT;
+    work.Num1 := <span style="color:#00D">15</span>;
+    work.Num2 := <span style="color:#00D">10</span>;
+    <span style="color:#080;font-weight:bold">try</span>
+      diff := client.calculate( <span style="color:#00D">1</span>, work);
+      Console.WriteLine( Format(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">'</span><span style="color:#D20">15-10=%d</span><span style="color:#710">'</span></span>, [diff]));
+    <span style="color:#080;font-weight:bold">except</span>
+      <span style="color:#088;font-weight:bold">on</span> io: TInvalidOperation
+      <span style="color:#080;font-weight:bold">do</span> Console.WriteLine( <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">'</span><span style="color:#D20">Invalid operation: </span><span style="color:#710">'</span></span> + io.Why);
+    <span style="color:#080;font-weight:bold">end</span>;
+
+    log := client.getStruct(<span style="color:#00D">1</span>);
+    Console.WriteLine( Format( <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">'</span><span style="color:#D20">Check log: %s</span><span style="color:#710">'</span></span>, [log.Value]));
+
+    transport.Close();
+
+  <span style="color:#080;font-weight:bold">except</span>
+    <span style="color:#088;font-weight:bold">on</span> e : Exception
+    <span style="color:#080;font-weight:bold">do</span> Console.WriteLine( e.ClassName+<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">'</span><span style="color:#D20">: </span><span style="color:#710">'</span></span>+e.Message);
+  <span style="color:#080;font-weight:bold">end</span>;
+<span style="color:#080;font-weight:bold">end</span>;</code></pre>
 
 <h3>Server</h3>
 
+<p>The server main code typically sets up the service endpoint as designed by the developer. The setup is quite similar to the client, except that we use the TServerSocketImpl and need an interface handler instance which will handle the incoming requests.</p>
+
+<pre><code class="language-delphi"><span style="color:#080;font-weight:bold">class</span> <span style="color:#080;font-weight:bold">procedure</span> DelphiTutorialServer.Main;
+<span style="color:#080;font-weight:bold">var</span> handler   : TCalculator.Iface;
+    processor : IProcessor;
+    transport : IServerTransport;
+    server    : IServer;
+<span style="color:#080;font-weight:bold">begin</span>
+  <span style="color:#080;font-weight:bold">try</span>
+    handler   := TCalculatorHandler.Create;
+    processor := TCalculator.TProcessorImpl.Create( handler);
+    transport := TServerSocketImpl.Create( <span style="color:#00D">9090</span>);
+    server    := TSimpleServer.Create( processor, transport);
+
+    Console.WriteLine( <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">'</span><span style="color:#D20">Starting the server...</span><span style="color:#710">'</span></span>);
+    server.Serve();
+
+  <span style="color:#080;font-weight:bold">except</span>
+    <span style="color:#088;font-weight:bold">on</span> e: Exception <span style="color:#080;font-weight:bold">do</span> Console.WriteLine( e.Message);
+  <span style="color:#080;font-weight:bold">end</span>;
+
+  Console.WriteLine(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">'</span><span style="color:#D20">done.</span><span style="color:#710">'</span></span>);
+<span style="color:#080;font-weight:bold">end</span>;</code></pre>
+
+<h3>Server Handler</h3>
+
+<p>The server handler class TCalculatorHandler implements the communication endpoint interface. The TCalculator.Iface interface implemented here is again created by the Thrift compiler from the IDL.</p>
+
+<pre><code class="language-delphi"><span style="color:#080;font-weight:bold">type</span>
+  TCalculatorHandler = <span style="color:#080;font-weight:bold">class</span>( TInterfacedObject, TCalculator.Iface)
+  <span style="color:#088;font-weight:bold">protected</span>
+    <span style="color:#777">// TSharedService.Iface</span>
+    <span style="color:#080;font-weight:bold">function</span>  getStruct(key: Integer): ISharedStruct;
+
+    <span style="color:#777">// TCalculator.Iface</span>
+    <span style="color:#080;font-weight:bold">procedure</span> ping();
+    <span style="color:#080;font-weight:bold">function</span>  add(num1: Integer; num2: Integer): Integer;
+    <span style="color:#080;font-weight:bold">function</span>  calculate(logid: Integer; <span style="color:#080;font-weight:bold">const</span> w: IWork): Integer;
+    <span style="color:#080;font-weight:bold">procedure</span> zip();
+
+    <span style="color:#777">// ... more code ...</span>
+  <span style="color:#080;font-weight:bold">end</span>;
+  
+  
+<span style="color:#080;font-weight:bold">procedure</span> TCalculatorHandler.ping;
+<span style="color:#080;font-weight:bold">begin</span>
+  Console.WriteLine( <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">'</span><span style="color:#D20">ping()</span><span style="color:#710">'</span></span>);
+<span style="color:#080;font-weight:bold">end</span>;
+
+
+<span style="color:#080;font-weight:bold">function</span> TCalculatorHandler.add(num1: Integer; num2: Integer): Integer;
+<span style="color:#080;font-weight:bold">begin</span>
+  Console.WriteLine( Format( <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">'</span><span style="color:#D20">add( %d, %d)</span><span style="color:#710">'</span></span>, [num1, num2]));
+  result := num1 + num2;
+<span style="color:#080;font-weight:bold">end</span>;
+
+
+<span style="color:#080;font-weight:bold">function</span> TCalculatorHandler.calculate(logid: Integer; <span style="color:#080;font-weight:bold">const</span> w: IWork): Integer;
+<span style="color:#080;font-weight:bold">var</span> entry : ISharedStruct;
+<span style="color:#080;font-weight:bold">begin</span>
+  <span style="color:#080;font-weight:bold">try</span>
+    Console.WriteLine( Format(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">'</span><span style="color:#D20">calculate( %d, [%d,%d,%d])</span><span style="color:#710">'</span></span>, [logid, Ord(w.Op), w.Num1, w.Num2]));
+
+    <span style="color:#080;font-weight:bold">case</span> w.Op <span style="color:#080;font-weight:bold">of</span>
+      TOperation.ADD      :  result := w.Num1 + w.Num2;
+      TOperation.SUBTRACT :  result := w.Num1 - w.Num2;
+      TOperation.MULTIPLY :  result := w.Num1 * w.Num2;
+      TOperation.DIVIDE   :  result := Round( w.Num1 / w.Num2);
+    <span style="color:#080;font-weight:bold">else</span>
+      <span style="color:#080;font-weight:bold">raise</span> TInvalidOperation.Create( Ord(w.Op), <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">'</span><span style="color:#D20">Unknown operation</span><span style="color:#710">'</span></span>);
+    <span style="color:#080;font-weight:bold">end</span>;
+
+  <span style="color:#080;font-weight:bold">except</span>
+    <span style="color:#088;font-weight:bold">on</span> e:Thrift.TException <span style="color:#080;font-weight:bold">do</span> <span style="color:#080;font-weight:bold">raise</span>;  <span style="color:#777">// let Thrift Exceptions pass through</span>
+    <span style="color:#088;font-weight:bold">on</span> e:Exception <span style="color:#080;font-weight:bold">do</span> <span style="color:#080;font-weight:bold">raise</span> TInvalidOperation.Create( Ord(w.Op), e.Message);  <span style="color:#777">// repackage all other</span>
+  <span style="color:#080;font-weight:bold">end</span>;
+
+  entry := TSharedStructImpl.Create;
+  entry.Key   := logid;
+  entry.Value := IntToStr( result);
+  FLog.AddOrSetValue( logid, entry);
+<span style="color:#080;font-weight:bold">end</span>;
+
+<span style="color:#080;font-weight:bold">function</span> TCalculatorHandler.getStruct(key: Integer): ISharedStruct;
+<span style="color:#080;font-weight:bold">begin</span>
+  Console.WriteLine( Format( <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">'</span><span style="color:#D20">getStruct(%d)</span><span style="color:#710">'</span></span>, [key]));
+  result := FLog[key];
+<span style="color:#080;font-weight:bold">end</span>;
+
+
+<span style="color:#080;font-weight:bold">procedure</span> TCalculatorHandler.zip;
+<span style="color:#080;font-weight:bold">begin</span>
+  Console.WriteLine( <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">'</span><span style="color:#D20">zip()</span><span style="color:#710">'</span></span>);
+<span style="color:#080;font-weight:bold">end</span>;</code></pre>
+
 <h2>Additional Information</h2>
 	</div>
 	<div class="container">