THRIFT-812 Demo of Thrift over ZeroMQ (C#)
Patch: Nils Huegelmann 


git-svn-id: https://svn.apache.org/repos/asf/thrift/trunk@1095179 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/contrib/zeromq/csharp/AssemblyInfo.cs b/contrib/zeromq/csharp/AssemblyInfo.cs
new file mode 100755
index 0000000..9ad48c6
--- /dev/null
+++ b/contrib/zeromq/csharp/AssemblyInfo.cs
@@ -0,0 +1,46 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.

+ */

+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+// Information about this assembly is defined by the following attributes. 
+// Change them to the values specific to your project.
+
+[assembly: AssemblyTitle("ZmqServer")]
+[assembly: AssemblyDescription("Zmq Examples")]
+[assembly: AssemblyConfiguration("")]

+[assembly: AssemblyCompany("The Apache Software Foundation")]
+[assembly: AssemblyProduct("")]

+[assembly: AssemblyCopyright("The Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
+// The form "{Major}.{Minor}.*" will automatically update the build and revision,
+// and "{Major}.{Minor}.{Build}.*" will update just the revision.
+
+[assembly: AssemblyVersion("1.0.*")]
+
+// The following attributes are used to specify the signing key for the assembly, 
+// if desired. See the Mono documentation for more information about signing.
+
+//[assembly: AssemblyDelaySign(false)]
+//[assembly: AssemblyKeyFile("")]
+
diff --git a/contrib/zeromq/csharp/Main.cs b/contrib/zeromq/csharp/Main.cs
new file mode 100644
index 0000000..e66cfe0
--- /dev/null
+++ b/contrib/zeromq/csharp/Main.cs
@@ -0,0 +1,60 @@
+using System;
+using System.Threading;
+using Thrift.Protocol;
+using ZMQ;
+using ZmqServer;
+using ZmqClient;
+
+namespace ZmqServer
+{
+	class MainClass
+	{
+		public static void Main (string[] args)
+		{
+			new Thread(Server.serve).Start();
+			Client.work();
+		}
+		
+		static class Server{
+			public static void serve(){
+				StorageHandler s=new StorageHandler();
+				Storage.Processor p=new Storage.Processor(s);
+				
+				ZMQ.Context c=new ZMQ.Context();
+				
+				TZmqServer tzs=new TZmqServer(p,c,"tcp://127.0.0.1:9090",ZMQ.SocketType.PAIR);
+				tzs.Serve();
+			}
+			
+			class StorageHandler:Storage.Iface{
+				int val=0;
+				
+				public void incr(int amount){
+					val+=amount;
+					Console.WriteLine("incr({0})",amount);
+				}
+				
+				public int get(){
+					return val;
+				} 
+			}
+		}
+		
+		static class Client{
+			public static void work()
+			{
+				Context ctx=new Context();
+				TZmqClient tzc=new TZmqClient(ctx,"tcp://127.0.0.1:9090",SocketType.PAIR);
+				TBinaryProtocol p=new TBinaryProtocol(tzc);
+				
+				Storage.Client client=new Storage.Client(p);
+				tzc.Open();
+				
+				Console.WriteLine(client.@get());
+				client.incr(1);
+				client.incr(41);
+				Console.WriteLine(client.@get());
+			}
+		}
+	}
+}
diff --git a/contrib/zeromq/csharp/TZmqClient.cs b/contrib/zeromq/csharp/TZmqClient.cs
new file mode 100644
index 0000000..c792882
--- /dev/null
+++ b/contrib/zeromq/csharp/TZmqClient.cs
@@ -0,0 +1,78 @@
+using System;
+using ZMQ;
+using System.IO;
+using Thrift.Transport;
+
+namespace ZmqClient
+{
+	public class TZmqClient : TTransport
+	{
+		Socket _sock;
+		String _endpoint;
+		MemoryStream _wbuf = new MemoryStream ();
+		MemoryStream _rbuf = new MemoryStream ();
+
+		void debug (string msg)
+		{
+			//Uncomment to enable debug
+//			Console.WriteLine (msg);
+		}
+
+		public TZmqClient (Context ctx, String endpoint, SocketType sockType)
+		{
+			_sock = ctx.Socket (sockType);
+			_endpoint = endpoint;
+		}
+
+		public override void Open ()
+		{
+			_sock.Connect (_endpoint);
+		}
+		
+		public override void Close ()
+		{
+			throw new NotImplementedException ();
+		}
+
+		public override bool IsOpen {
+			get {
+				throw new NotImplementedException ();
+			}
+		}
+
+		public override int Read (byte[] buf, int off, int len)
+		{
+			debug ("Client_Read");
+			if (off != 0 || len != buf.Length)
+				throw new NotImplementedException ();
+
+			if (_rbuf.Length == 0) {
+				//Fill the Buffer with the complete ZMQ Message which needs to be(?!) the complete Thrift reponse
+				debug ("Client_Read Filling buffer..");
+				byte[] tmpBuf = _sock.Recv ();
+				debug (string.Format("Client_Read filled with {0}b",tmpBuf.Length));
+				_rbuf.Write (tmpBuf, 0, tmpBuf.Length);
+				_rbuf.Position = 0;	//For reading
+			}
+			int ret = _rbuf.Read (buf, 0, len);
+			if (_rbuf.Length == _rbuf.Position)	//Finished reading
+				_rbuf.SetLength (0);
+			debug (string.Format ("Client_Read return {0}b, remaining  {1}b", ret, _rbuf.Length - _rbuf.Position));
+			return ret;
+		}
+
+		public override void Write (byte[] buf, int off, int len)
+		{
+			debug ("Client_Write");
+			_wbuf.Write (buf, off, len);
+		}
+
+		public override void Flush ()
+		{
+			debug ("Client_Flush");
+			_sock.Send (_wbuf.GetBuffer ());
+			_wbuf = new MemoryStream ();
+		}
+	}
+}
+
diff --git a/contrib/zeromq/csharp/TZmqServer.cs b/contrib/zeromq/csharp/TZmqServer.cs
new file mode 100644
index 0000000..535c623
--- /dev/null
+++ b/contrib/zeromq/csharp/TZmqServer.cs
@@ -0,0 +1,56 @@
+using System;
+using Thrift;
+using Thrift.Server;
+using Thrift.Transport;
+using Thrift.Protocol;
+using ZMQ;
+using System.IO;
+
+using System.Collections.Generic;
+
+namespace ZmqServer
+{
+	public class TZmqServer
+	{
+		Socket _socket ;
+		TProcessor _processor;
+		
+		void debug (string msg)
+		{
+			//Uncomment to enable debug
+//			Console.WriteLine (msg);
+		}
+
+		public TZmqServer (TProcessor processor, Context ctx, String endpoint, SocketType sockType)
+		{
+			new TSimpleServer (processor,null);
+			_socket = ctx.Socket (sockType);
+			_socket.Bind (endpoint);
+			_processor = processor;
+		}
+
+		public void ServeOne ()
+		{
+			debug ("Server_ServeOne");
+			Byte[] msg = _socket.Recv ();
+			MemoryStream istream = new MemoryStream (msg);
+			MemoryStream ostream = new MemoryStream ();
+			TProtocol tProtocol = new TBinaryProtocol (new TStreamTransport (istream, ostream));
+			_processor.Process (tProtocol, tProtocol);
+
+			if (ostream.Length != 0) {
+				byte[] newBuf = new byte[ostream.Length];
+				Array.Copy (ostream.GetBuffer (), newBuf, ostream.Length);
+				debug (string.Format ("Server_ServeOne sending {0}b", ostream.Length));
+				_socket.Send (newBuf);
+			}
+		}
+
+		public void Serve ()
+		{
+			while (true)
+				ServeOne ();
+		}
+	}
+}
+
diff --git a/contrib/zeromq/csharp/ThriftZMQ.csproj b/contrib/zeromq/csharp/ThriftZMQ.csproj
new file mode 100755
index 0000000..1d5f13c
--- /dev/null
+++ b/contrib/zeromq/csharp/ThriftZMQ.csproj
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="utf-8"?>

+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

+  <PropertyGroup>

+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>

+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>

+    <ProductVersion>9.0.21022</ProductVersion>

+    <SchemaVersion>2.0</SchemaVersion>

+    <ProjectGuid>{17C63B90-DFD7-42AC-A7B0-749E6876C0A1}</ProjectGuid>

+    <OutputType>Exe</OutputType>

+    <RootNamespace>ZmqServer</RootNamespace>

+    <AssemblyName>ThriftZMQ</AssemblyName>

+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>

+    <FileUpgradeFlags>

+    </FileUpgradeFlags>

+    <OldToolsVersion>3.5</OldToolsVersion>

+    <UpgradeBackupLocation />

+    <PublishUrl>publish\</PublishUrl>

+    <Install>true</Install>

+    <InstallFrom>Disk</InstallFrom>

+    <UpdateEnabled>false</UpdateEnabled>

+    <UpdateMode>Foreground</UpdateMode>

+    <UpdateInterval>7</UpdateInterval>

+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>

+    <UpdatePeriodically>false</UpdatePeriodically>

+    <UpdateRequired>false</UpdateRequired>

+    <MapFileExtensions>true</MapFileExtensions>

+    <ApplicationRevision>0</ApplicationRevision>

+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>

+    <IsWebBootstrapper>false</IsWebBootstrapper>

+    <UseApplicationTrust>false</UseApplicationTrust>

+    <BootstrapperEnabled>true</BootstrapperEnabled>

+  </PropertyGroup>

+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">

+    <DebugSymbols>true</DebugSymbols>

+    <DebugType>full</DebugType>

+    <Optimize>false</Optimize>

+    <OutputPath>bin\Debug</OutputPath>

+    <DefineConstants>DEBUG</DefineConstants>

+    <ErrorReport>prompt</ErrorReport>

+    <WarningLevel>4</WarningLevel>

+    <PlatformTarget>x86</PlatformTarget>

+    <Externalconsole>true</Externalconsole>

+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>

+  </PropertyGroup>

+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">

+    <DebugType>none</DebugType>

+    <Optimize>false</Optimize>

+    <OutputPath>bin\Release</OutputPath>

+    <ErrorReport>prompt</ErrorReport>

+    <WarningLevel>4</WarningLevel>

+    <PlatformTarget>x86</PlatformTarget>

+    <Externalconsole>true</Externalconsole>

+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>

+  </PropertyGroup>

+  <ItemGroup>

+    <Reference Include="clrzmq, Version=2.1.0.0, Culture=neutral, processorArchitecture=x86">

+      <SpecificVersion>False</SpecificVersion>

+      <HintPath>.\clrzmq.dll</HintPath>

+    </Reference>

+    <Reference Include="System" />

+    <Reference Include="Thrift, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">

+      <SpecificVersion>False</SpecificVersion>

+      <HintPath>..\..\..\lib\csharp\Thrift.dll</HintPath>

+    </Reference>

+  </ItemGroup>

+  <ItemGroup>

+    <Compile Include="Main.cs" />

+    <Compile Include="AssemblyInfo.cs" />

+    <Compile Include="TZmqServer.cs" />

+    <Compile Include="TZmqClient.cs" />

+    <Compile Include="..\gen-csharp\Storage.cs" />

+  </ItemGroup>

+  <ItemGroup>

+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">

+      <Visible>False</Visible>

+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>

+      <Install>false</Install>

+    </BootstrapperPackage>

+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">

+      <Visible>False</Visible>

+      <ProductName>.NET Framework 3.5 SP1</ProductName>

+      <Install>true</Install>

+    </BootstrapperPackage>

+    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">

+      <Visible>False</Visible>

+      <ProductName>Windows Installer 3.1</ProductName>

+      <Install>true</Install>

+    </BootstrapperPackage>

+  </ItemGroup>

+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />

+</Project>
\ No newline at end of file
diff --git a/contrib/zeromq/csharp/ThriftZMQ.sln b/contrib/zeromq/csharp/ThriftZMQ.sln
new file mode 100755
index 0000000..404a747
--- /dev/null
+++ b/contrib/zeromq/csharp/ThriftZMQ.sln
@@ -0,0 +1,42 @@
+

+Microsoft Visual Studio Solution File, Format Version 11.00

+# Visual Studio 2010

+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ThriftZMQ", "ThriftZMQ.csproj", "{17C63B90-DFD7-42AC-A7B0-749E6876C0A1}"

+EndProject

+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Thrift", "..\..\..\lib\csharp\src\Thrift.csproj", "{499EB63C-D74C-47E8-AE48-A2FC94538E9D}"

+EndProject

+Global

+	GlobalSection(SolutionConfigurationPlatforms) = preSolution

+		Debug|Any CPU = Debug|Any CPU

+		Debug|Mixed Platforms = Debug|Mixed Platforms

+		Debug|x86 = Debug|x86

+		Release|Any CPU = Release|Any CPU

+		Release|Mixed Platforms = Release|Mixed Platforms

+		Release|x86 = Release|x86

+	EndGlobalSection

+	GlobalSection(ProjectConfigurationPlatforms) = postSolution

+		{17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Debug|Any CPU.ActiveCfg = Debug|x86

+		{17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Debug|Mixed Platforms.ActiveCfg = Debug|x86

+		{17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Debug|Mixed Platforms.Build.0 = Debug|x86

+		{17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Debug|x86.ActiveCfg = Debug|x86

+		{17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Debug|x86.Build.0 = Debug|x86

+		{17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Release|Any CPU.ActiveCfg = Release|x86

+		{17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Release|Mixed Platforms.ActiveCfg = Release|x86

+		{17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Release|Mixed Platforms.Build.0 = Release|x86

+		{17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Release|x86.ActiveCfg = Release|x86

+		{17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Release|x86.Build.0 = Release|x86

+		{499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU

+		{499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Debug|Any CPU.Build.0 = Debug|Any CPU

+		{499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU

+		{499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU

+		{499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Debug|x86.ActiveCfg = Debug|Any CPU

+		{499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Release|Any CPU.ActiveCfg = Release|Any CPU

+		{499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Release|Any CPU.Build.0 = Release|Any CPU

+		{499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU

+		{499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Release|Mixed Platforms.Build.0 = Release|Any CPU

+		{499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Release|x86.ActiveCfg = Release|Any CPU

+	EndGlobalSection

+	GlobalSection(SolutionProperties) = preSolution

+		HideSolutionNode = FALSE

+	EndGlobalSection

+EndGlobal