本文將使用一個gitHub開源的組件技術來讀寫redis數據,使用的是基於以太網的TCP/IP實現,不需要額外的組件,讀取操作只要放到后台線程就不會卡死線程,本組件支持超級方便的高性能讀寫操作
github地址:https://github.com/dathlin/HslCommunication
如果喜歡可以star或是fork,還可以打賞支持。
官網地址:http://www.hslcommunication.cn/
聯系作者及加群方式(激活碼在群里發放):http://www.hslcommunication.cn/Cooperation
Redis是什么?
這個是一個實時的數據庫技術,主要采用鍵值操作來存儲數據的。官網是 https://redis.io/ ,官方的解釋為(摘自百度百科):
安裝redis服務器
我們在使用前需要安裝服務器,一般的windows的服務器來自於微軟的項目:
https://github.com/MicrosoftArchive/redis/releases

雖然微軟的項目只更新到了 redis3.2 版本。但是已經足夠我們日常的使用了。
安裝完成后,會自動的啟動服務器。我們可以打開cmd來測試

服務器搭好后就可以使用C#來操作了。
再次隨便聊聊,C#有個還可以的redis類庫叫StackExchange.Redis
https://github.com/StackExchange/StackExchange.Redis
但是這個類庫呢,總有些莫名其妙的問題,尤其是超時問題,始終沒有得到很好的解決,所以我集成實現了redis的基本操作,給大家一個更多的選擇。支持.net framework和.net standard
當你的程序實現了redis之后,程序架構變成了:

此處的redis相當於高速的數據緩存,可以部署在服務器的電腦上,可以部署在雲端等等,任意其他的電腦上面。
接下來演示使用HSL來進行操作
從NUGET安裝
Install-Package HslCommunication
關於兩種模式
在PLC端,包括三菱,西門子,歐姆龍,AB以及Modbus Tcp客戶端的訪問器上,都支持兩種模式,短連接模式和長連接模式,現在就來解釋下什么原理。
短連接:每次讀寫都是一個單獨的請求,請求完畢也就關閉了,如果服務器的端口僅僅支持單連接,那么關閉后這個端口可以被其他連接復用,但是在頻繁的網絡請求下,容易發生異常,會有其他的請求不成功,尤其是多線程的情況下。
長連接:創建一個公用的連接通道,所有的讀寫請求都利用這個通道來完成,這樣的話,讀寫性能更快速,即時多線程調用也不會影響,內部有同步機制。如果服務器的端口僅僅支持單連接,那么這個端口就被占用了,比如三菱的端口機制,西門子的Modbus tcp端口機制也是這樣的。以下代碼默認使用長連接,性能更高,還支持多線程同步。
在短連接的模式下,每次請求都是單獨的訪問,所以沒有重連的困擾,在長連接的模式下,如果本次請求失敗了,在下次請求的時候,會自動重新連接服務器,直到請求成功為止。另外,盡量所有的讀寫都對結果的成功進行判斷。
DEMO示例:
下面的一個項目是這個組件的訪問測試項目,您可以進行初步的訪問的測試,免去了您寫測試程序的麻煩,三菱的界面和西門子的界面幾乎是一致的。可以同時參考。該項目位於本篇文章開始處的Gitbub源代碼里面的
下載地址為:HslCommunicationDemo.zip

可以用來瀏覽你的redis到底有什么數據,以及這個數據是什么,初步支持了 string,list,hash 數據類型。
當你寫入的key名字帶有:(英文狀態)時。這個瀏覽器還會對數據進行分類整理、
關於redis指令
http://doc.redisfans.com/index.html

原生的指令有很多,這個庫里也是支持了大部分的操作,如果你需要的功能還沒有支持,比如 獲取一個鍵的數據信息, 將指令參數按照空格輸入進去就行
private void button16_Click( object sender, EventArgs e )
{
OperateResult<string> read = redisClient.ReadCustomer("GET A" );
if (read.IsSuccess)
{
// read.Content 就是從服務器返回的數據 例如為 $2\r\n11\r\n 需要自己提煉真實的數據
MessageBox.Show( read.Content );
}
else
{
MessageBox.Show( read.Message );
}
}
下面列舉一些示例
簡單使用
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using HslCommunication.Enthernet.Redis;
using HslCommunication;
namespace WindowsFormsApp3
{
public partial class Form1 : Form
{
public Form1( )
{
InitializeComponent( );
}
private RedisClient redisClient = new RedisClient( "127.0.0.1", 6379, "" );
private void button1_Click( object sender, EventArgs e )
{
OperateResult<string> read = redisClient.ReadKey( "a" );
if (read.IsSuccess)
{
MessageBox.Show( read.Content );
}
else
{
MessageBox.Show( read.Message );
}
}
}
}
結果如下:

顯示的值就是我們之前寫入的操作,主要,redis區分大小寫,你讀 A 和讀 a 是不一樣的。
上述的代碼已經進行了嚴格的驗證,上面情況會讀取失敗呢?網絡異常或是 a 不存在
我們來看看寫入鍵值:
private void button2_Click( object sender, EventArgs e )
{
OperateResult write = redisClient.WriteKey( "a", "abcde" );
}
上述就沒有對寫入成功與否進行驗證,只要是網絡正常基本都是成功的。
寫完后我們再讀取一次:

如果想寫入一個有生命周期的key,比如100s后自動消失的key
private void button3_Click( object sender, EventArgs e )
{
OperateResult write = redisClient.WriteExpireKey( "b", "abcde", 100 );
}
這樣就寫入了一個帶生命周期的key了。
批量讀寫
如果想要一次性寫入或是讀取很多鍵值:
private void button4_Click( object sender, EventArgs e )
{
OperateResult<string[]> read = redisClient.ReadKey( new string[] { "a", "b" } );
if (read.IsSuccess)
{
string[] result = read.Content;
}
else
{
MessageBox.Show( read.Message );
}
}
寫入的操作如下:
private void button5_Click( object sender, EventArgs e )
{
redisClient.WriteKey( new string[] { "a", "b" }, new string[] { "abcde", "ihsdasd" } );
}
此處省略了對寫入結果的驗證,為了安全起見,你應該添加。
獲取舊值,並設置一個新的值進去
private void button6_Click( object sender, EventArgs e )
{
OperateResult<string> read = redisClient.ReadAndWriteKey( "a", "aaaaaa" );
if (read.IsSuccess)
{
MessageBox.Show( read.Content );
}
else
{
MessageBox.Show( read.Message );
}
}
遞增遞減操作。
這個基本功能也是很常見的、
我們先寫 BB 為 0

然后我們再給這個值加1,並返回1的操作。
private void button7_Click( object sender, EventArgs e )
{
OperateResult<int> read = redisClient.IncrementKey( "BB" );
if (read.IsSuccess)
{
MessageBox.Show( "Value:" + read.Content );
}
else
{
MessageBox.Show( read.Message );
}
}
同理也支持減一操作,增加指定的數據操作,減去指定的數據操作。

列表操作
redis也支持存儲數組數據信息
我們創建一個數組,並往里面塞東西,當然支持從數組的左側塞,也支持從右側塞,下面就是左側的例子
private void button8_Click( object sender, EventArgs e )
{
redisClient.ListLeftPush( "C", "123" );
}
這樣就創建了一個數組,數組數據的讀取,並不是get了,而是變成了 LRANGE 0 -1 代表讀取整個的數組

用代碼來讀取就是
private void button9_Click( object sender, EventArgs e )
{
OperateResult<string[]> read = redisClient.ListRange( "C", 0, -1 );
if (read.IsSuccess)
{
// 列表變成了一個數組信息
string[] result = read.Content;
}
else
{
MessageBox.Show( read.Message );
}
}
當然,當你的數組很大時。比如1000個長度時,你可以讀取中間任意個數組。
獲取數組長度
當你不知道一個數組的長度,不想在讀取所有的數組信息的情況下,讀取到長度
private void button10_Click( object sender, EventArgs e )
{
int length = redisClient.GetListLength( "C" ).Content; // 此處就是1
}
獲取指定索引的數據
private void button11_Click( object sender, EventArgs e )
{
string read = redisClient.ReadListByIndex( "C", 0 ).Content;
}
注意,當C不是list時,會引發錯誤。
修剪列表信息
當數組過長時,我們可以修剪數組來達到收縮的目的
private void button12_Click( object sender, EventArgs e )
{
redisClient.ListTrim( "C", 0, 9 );// 10個長度,保留0-9索引的數據
}
返回並移除開始處的列表
private void button13_Click( object sender, EventArgs e )
{
OperateResult<string> read = redisClient.ListLeftPop( "C" );
if (read.IsSuccess)
{
MessageBox.Show( read.Content );
}
else
{
MessageBox.Show( read.Message );
}
}
移除並返回測試的也是可以的。
哈希值讀寫
哈希值的意思是一個鍵的值是由多個鍵值組成的
private void button14_Click( object sender, EventArgs e )
{
redisClient.WriteHashKey( "D", "A", "1" );
redisClient.WriteHashKey( "D", "B", "2" );
redisClient.WriteHashKey( "D", "C", "3" );
}
相當於是鍵 D 的域 A 寫入1, B寫入2,C寫入3
你一次可以讀取所有的C的域集合,或是值集合,或是域+值集合,下面演示了一個示例,讀取域+值集合
private void button15_Click( object sender, EventArgs e )
{
OperateResult<string[]> read = redisClient.ReadHashKeyAll( "C" );
if (read.IsSuccess)
{
// 列表變成了一個域+值信息
// A
// 1
// B
// 2
// C
// 3
string[] result = read.Content;
}
else
{
MessageBox.Show( read.Message );
}
}
