Phants Client for Redis™*
|
Phants Client for Redis is a Redis client implementation written in C# for Unity. What is Redis?
From redis.io:
Redis is an open source (BSD licensed), in-memory data structure store, used as a database, cache and message broker. It supports data structures such as strings, hashes, lists, sets, sorted sets with range queries, bitmaps, hyperloglogs, geospatial indexes with radius queries and streams. Redis has built-in replication, Lua scripting, LRU eviction, transactions and different levels of on-disk persistence, and provides high availability via Redis Sentinel and automatic partitioning with Redis Cluster.
From a Redis server's perspective, clients have two fundamentally different states or modes of operation:
While it is certainly possible to create one client that jumps between these modes, we opted for a simpler approach: use SubscriptionClient if you want subscription events, and use CommandClient if you want to send commands.
These pages serve only to document the API provided by the client software, which simply creates a (nearly one-to-one) mapping between C# methods and Redis server commands. Here you will find, for example, everything you need to know to call the BzpopMin() method, but the behavior of the BZPOPMIN command itself is not described.
You are encouraged to check out the Redis Command Reference, as well as Redis Pub/Sub to get the most out of this package. To learn more about the underlying Redis data types, see the Redis Protocol specification.
First thing's first, you're going to need a Redis server of some sort. This is often as simple as using apt-get
on a Linux box. This client has been tested against Redis servers running on Ubuntu server, Raspberry Pi, and the Windows 10 WSL. If you are using this client, you probably already have some idea of what you need and how you want to run it.
New commands are added with each version of Redis. Each entry in the Command Reference notes the version where the command became available (e.g. "BITFIELD - Available since 3.2.0."). While Phants Client for Redis implements nearly every command up to version 5.0, your server may not. If this is the case, some commands (and hence, CommandClient methods) will not work; the server simply will not recognize them as valid commands.
You may have difficulty connecting if there is a firewall involved. This is especially true when running a Redis server on Windows, as the Windows firewall typically prevents access to port 6379 by default. You may have to open access to this port.
With your server up and running, you should be able to connect any number of ways with simple tools like netcat or telnet. This will allow you to try out some raw Redis commands to ensure that everything is ready to go. This is likely an easier way to test rather than jumping right into Unity. In any event, you'll connect to Redis on port number 6379. This is the standard Redis port; if you've changed the defaults, you'll obviously have to adjust for your setup.
Once this is working, take the client for a spin. We have a regular MonoBehaviour script attached to an empty object in the scene. On Awake()
, we create the client and try to connect. A connect callback is provided by the caller; it will be called when the connection attempt has completed. If the connection was successful, error will be null.
Other code that has access to a client object can register for connection events as well, but such events are only fired when a connection is successful.
Disconnects are done in the same fashion. The caller can provide a callback to Disconnect()
, and other interested parties can register for disconnect events.
Every command method in Phants Client for Redis is asynchronous, meaning you'll essentially provide a callback responsible for processing the result. They're not exactly callbacks though. Rather, they are interfaces designed to handle the set of data types that Redis supports. For lack of a better name, we call these the Sink interfaces (as in source/sink). Sinks are composed of two or more Parser interfaces. In each Sink, one of the interfaces is always an ErrorParser, since most/all Redis commands can return an error. The other Parsers in the Sink are called upon to process the data returned from a command. It may seem a bit abstract, so perhaps an example is in order:
The SCARD command returns a RESP Integer reply, so naturally, the Scard() method takes an object that implements the IntegerSink interface. This interface brings together an IntegerParser and the obligatory ErrorParser. The Sink object must implement void Integer(long)
, which will be called with the value that was returned:
Now imagine your Redis server has a Set named scard_test_key, you would execute SCARD against it like so:
This is easy enough, but defining a custom class for every response type or method of interest is far from ideal. It was designed this way so you could define one if you needed to, but for typical use, Sink Adapter classes for each RESP type have been implemented and included with this package. Returning to the SCARD example, you can use an IntegerSinkAdapter and implement the callbacks inline with your code (or anywhere else, however you want to do it).
The RESP protocol separates arguments with whitespace, so any strings containing whitespace must be quoted, or the server will interpret them incorrectly. This goes for string values (such as the value in a key/value pair), but it also goes for key names, as well as Lua scripts, or any other argument that could potentially contain whitespace. The client does not provide quotation automatically, as this would introduce unnecessary computation in situations where it is not necessary (e.g. the user wisely chooses key names that are whitespace free). However, there is a static utility method provided, QuoteWrap(string), that will return a quoted string. When in doubt, use this method to produce safe argument strings.
As mentioned above, Redis has a subscriber mode. In this mode, a client subscribes to one or more channels and waits indefinitely for messages to arrive. Here, an example is provided to demonstrate how to make use of this facility.
Once the SubscriptionClient is running, it will receive messages on the given channels. This can be tested with any Redis client (netcat, etc). Of course, the Publish() method of CommandClient works as well: