Execute Redis command with LUA script in C #
To directly post the code to implement the Lua script method, the Third-party class library used is Stackexchange.redis (nuget) Note: The following code is simplified, the actual use to modify,
Using System;
Using System.Collections.Generic;
Using System.Linq;
Using System.Net;
Using System.Threading.Tasks;
Using Stackexchange.redis; Namespace TL. CLOUD.KV {public class Kv:ikv {private Configurationoptions _redisconfig;//= new Confi
Gurationoptions private Idatabaseasync _db;//=connection.getdatabase ();
Private Iserver _server;//= Getserver ();
private string _keyprefix;/////<summary>///each micro-service one KV cloud instance, or shared cloud instance (without independent prefix, service key name needs to prevent conflict) </summary>///<param name= "Hostservicename" > Host Micro Service </param> public Kv (PUBLICCL
Oudkvconfig config) {Init (config); } private void Init (Publiccloudkvconfig config) {//unique distinguished dev/100 prefix, online can be without _ke Yprefix = string. Isnullorwhitespace (config. keyprefix)? Null:config. Keyprefix.trim ().
ToLower () + ': ';/lowercase with colon split Ali kv var kvurl = config.
Kvurl;
_redisconfig = Configurationoptions.parse (Kvurl); _redisconfig.password = config.
Kvpassword; _redisconfig.setdefaultports ();
Automatically populate default port var connection = Connectionmultiplexer.connect (_redisconfig); _db = connection.
Getdatabase ();
_server = Getserver ();
Private Iserver Getserver () {var config = new Configurationoptions { KeepAlive = 0, endpoints = {_redisconfig.endpoints[0]}, Abortonconnectfail = Fals
E, allowadmin = true};
var conn = connectionmultiplexer.connect (config); Return Conn. Getserver (config.
Endpoints[0]);
Public task<redisresult> Evallua (string lua, ilist<rediskey> keys, ilist<redisvalue> values)
{if (_keyprefix!= null) Keys = keys. Select (P => p.prepend (_keyprefix)). ToList ()//plus prefix return _db. Scriptevaluateasync (Lua, keys.) ToArray (), values.
ToArray ()); Public async task<redisresult> Evallua (byte[) luaSha1, ilist<rediskey> keys, Ilist<redi Svalue> values) {if (_keyprefix!= null) keys = keys. Select (P => p.prepend (_keyprefix)). ToList ()//plus prefix return await _db. Scriptevaluateasync (LUASHA1, keys.) ToArray (), values.
ToArray ()); Public Async task<byte[]> Loadluatoserverasync (string lua) {var SHA1 = Lua. CALCLUASHA1 ()//local COMPUTE if (!await _server). Scriptexistsasync (SHA1))//server does not exist SHA1 = await _server.
Scriptloadasync (LUA);/should be the same return SHA1 as computed; }
}
}
The following is a test snippet
The following is the test code
[test] public
async Task Loadluatoserverasync ()
{
var key = "TestEvalLua10010";
var fieldcontent = "testlua10011";
Const string LUA =
"Redis.call (' SET ', keys[1], argv[1]) \ n" +
"return Redis.call (' Get ', keys[1]) \ n";
var SHA2 = Lua. CALCLUASHA1 ();
var SHA1 = await _kv. Loadluatoserverasync (LUA);
Assert.AreEqual, SHA1. Length);
for (var i = 0; i < i++)
assert.areequal (Sha1[i],sha2[i]);
var keys = new List<rediskey> {key};
var values = new List<redisvalue> {fieldcontent};
var result = await _kv. Evallua (SHA1, keys, values);
Assert.AreEqual (Fieldcontent, (string) result);
The method used to calculate SHA1
Calculates the SHA1 result of LUA as the parameter public static byte[] CALCLUASHA1 for LUA (this string lua)
{
SHA1 SHA1 = new SHA1CryptoServiceProvider ();
var bytessha1in = Encoding.Default.GetBytes (LUA);
Return Sha1.computehash (bytessha1in);
}