Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / PHP

WinMemcached - A C# Key/Value Server

4.89/5 (4 votes)
27 Feb 2015CPOL4 min read 17.5K   181  
WinMemcached is a C# key/value multi threaded server. Its purpose is to act as a test server for developers who want to develop Memcache related projects on a Windows machine but deploy in a Linux environment.

Introduction

WinMemcached is a Windows key/value multi threaded server. Its purpose it to act as a test server for developers who want to develop in Windows but deploy in a Linux environment.

Memcached is a key/value server that stores small pieces of arbitrary data in memory. Its usage can be applied to many types of applications but commonly it's used in web applications primarily to store session data. Reading and writing to memory is much faster than reading and writing to disk, which is why high volume websites tend to use Memcache in some capacity.

Installing and configuring Memcached on Linux takes no longer than making a bad cup of tea, but on Windows it can be a frustrating task if you have to compile from source. There are binary versions of both 32 bit and 64 bit floating around in the web universe but most are broken as I found out. My situation was that I needed to develop on Windows but deploy on a Linux environment. After hours of downloading various binary versions from different sources and replacing DLL files, I began to wonder if there was another solution I could use.

Since I only required Memcached for testing purposes, I thought it might be easier to create a mock Memcache client library that would write to the file system instead. When I deployed to the production server, I would simply ignore the mock Memcache library from my git commit, which would result in the real Memcache client library being used in production. The whole point was to use Memcached to store data in memory and in my development environment, I could substitute the process of storing to memory with storing to the file system.

Developing the mock Memcache library in PHP was very simple. All I needed to do was create a class named Memcache and implement a few of the commonly used methods such as connect, add, set, get and flush.

PHP
class Memcache {

	public function connect($host, $port = null){
		// Let's fake it and open a file for reading
		// and load it with an empty key/value array
	}
	
	public function add($key, $value){
		// Add the item if the key doesn't exists in the array
	}
	
	public function set($key, $value){
		// Add the item, no need to check if it exists
	}
	
	public function get($key){
		// Check item exists in array and return it
	}
	
	public function delete($key){
		// Delete item from array
	}
	
	public function flush(){
		// Remove all elements from the array
	}
	
	public function close(){
		// Close the file
	}
}

The mock Memcache class simply opened a file for reading and writing. The Key/value data was stored in an array which was serialized and saved to file. I wrote a few tests, which passed on my Windows development server. I then deployed to live and ignored the mock Memcache class from my git commit and the code executed as expected.

Whilst this approach worked fine, I decided to take the idea one step further and develop a mock Memcached C# server. A multi threaded server that uses a command based protocol to set and get values stored in memory. After a few hours of hacking away, I finally put together a basic console server.

The server listens for client connections on a user selected port. Once a connection is established, a new thread is created to service the client. The client sends the server commands that are in XML. The parent XML node is the command type, while child nodes are command arguments.

Example Commands

This section describes all of the commands supported by the server.

XML
<a><k>customer</k><v>John Smith</v></a>

The XML command contains a parent a element and two child elements, k,v. The a command tells the server to store the value v with its key k. The server will check that the key does not exist before adding to the internal collection. On success, the server responses with a 200.Added message. If the key already exists, the server responds with a 204.Duplicate Key message.

XML
<s><k>customer</k><v>John Smith</v></s>

Identical to the a command, the s command does not check if the key exists before adding to the collection. This command is used to add and update the collection. The server responses with a 200.Added message on success.

XML
<g><k>customer</k></g>

The g command requests a value from the collection. It has a single argument k, which specifies the key name. On success, the server responds with a 200.followed by the key value. If the requested key does not exists the server responds with a 204.Not found message.

XML
<r><k>customer</k></r>

The r command removes the item in the collection with the given key name. On success, the server responds with a 200.Removed message. If the requested key does not exist, the server responds with a 204.Not found message.

XML
<c></c>

The c command removes all items from the collection. It takes no arguments. On success, the server responds with a 200.Cleared message.

XML
<st></st>

The st command asks the server to return information about how long it's been running and how many keys are currently in the collection.

XML
<q></q>

The q command informs the server that the client wants to disconnect. The server responds with a 200.Good bye message.

If a bad command is sent to the server, the server responds with a 400.Unknown Command message.

With the server up and running, I modified the Memcache PHP class to connect to the server instead of opening a file for reading and writing. The result was a solution that mimicked Memcache the client library and Memcached the server.

The download includes the WinMemcached server and demos for both C# and PHP.

History

  • 27th February, 2015: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)