You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

306 lines
12 KiB
C#

using HslCommunication.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
namespace HslCommunication.Enthernet.Redis
{
/// <summary>
/// 提供了redis辅助类的一些方法
/// </summary>
public class RedisHelper
{
#region Socket Helper
/// <summary>
/// 接收一行命令数据
/// </summary>
/// <param name="socket">网络套接字</param>
/// <returns>带有结果对象的数据信息</returns>
public static OperateResult<byte[]> ReceiveCommandLine( Socket socket )
{
return NetSupport.ReceiveCommandLineFromSocket( socket, (byte)'\n' );
}
/// <summary>
/// 接收一行字符串的信息
/// </summary>
/// <param name="socket">网络套接字</param>
/// <param name="length">字符串的长度</param>
/// <returns>带有结果对象的数据信息</returns>
public static OperateResult<byte[]> ReceiveCommandString( Socket socket, int length )
{
try
{
List<byte> bufferArray = new List<byte>( );
bufferArray.AddRange( NetSupport.ReadBytesFromSocket( socket, length ) );
OperateResult<byte[]> commandTail = ReceiveCommandLine( socket );
if (!commandTail.IsSuccess) return commandTail;
bufferArray.AddRange( commandTail.Content );
return OperateResult.CreateSuccessResult( bufferArray.ToArray( ) );
}
catch (Exception ex)
{
return new OperateResult<byte[]>( ex.Message );
}
}
/// <summary>
/// 从网络接收一条redis消息
/// </summary>
/// <param name="socket">网络套接字</param>
/// <returns>接收的结果对象</returns>
public static OperateResult<byte[]> ReceiveCommand( Socket socket )
{
List<byte> bufferArray = new List<byte>( );
OperateResult<byte[]> readCommandLine = ReceiveCommandLine( socket );
if (!readCommandLine.IsSuccess) return readCommandLine;
bufferArray.AddRange( readCommandLine.Content );
if (readCommandLine.Content[0] == '+' || readCommandLine.Content[0] == '-' || readCommandLine.Content[0] == ':')
{
// 状态回复,错误回复,整数回复
return OperateResult.CreateSuccessResult( bufferArray.ToArray( ) );
}
else if (readCommandLine.Content[0] == '$')
{
// 批量回复允许最大512M字节
OperateResult<int> lengthResult = GetNumberFromCommandLine( readCommandLine.Content );
if (!lengthResult.IsSuccess) return OperateResult.CreateFailedResult<byte[]>( lengthResult );
if (lengthResult.Content < 0) return OperateResult.CreateSuccessResult( bufferArray.ToArray( ) );
// 接收字符串信息
OperateResult<byte[]> receiveContent = ReceiveCommandString( socket, lengthResult.Content );
if (!receiveContent.IsSuccess) return receiveContent;
bufferArray.AddRange( receiveContent.Content );
return OperateResult.CreateSuccessResult( bufferArray.ToArray( ) );
}
else if (readCommandLine.Content[0] == '*')
{
// 多参数的回复
OperateResult<int> lengthResult = GetNumberFromCommandLine( readCommandLine.Content );
if (!lengthResult.IsSuccess) return OperateResult.CreateFailedResult<byte[]>( lengthResult );
for (int i = 0; i < lengthResult.Content; i++)
{
OperateResult<byte[]> receiveCommand = ReceiveCommand( socket );
if (!receiveCommand.IsSuccess) return receiveCommand;
bufferArray.AddRange( receiveCommand.Content );
}
return OperateResult.CreateSuccessResult( bufferArray.ToArray( ) );
}
else
{
return new OperateResult<byte[]>( "Not Supported HeadCode: " + readCommandLine.Content[0] );
}
}
#endregion
#region Prase Helper
/// <summary>
/// 将字符串数组打包成一个redis的报文信息
/// </summary>
/// <param name="commands">字节数据信息</param>
/// <returns>结果报文信息</returns>
public static byte[] PackStringCommand( string[] commands )
{
StringBuilder sb = new StringBuilder( );
sb.Append( '*' );
sb.Append( commands.Length.ToString( ) );
sb.Append( "\r\n" );
for (int i = 0; i < commands.Length; i++)
{
sb.Append( '$' );
sb.Append( Encoding.UTF8.GetBytes( commands[i] ).Length.ToString( ) );
sb.Append( "\r\n" );
sb.Append( commands[i] );
sb.Append( "\r\n" );
}
return Encoding.UTF8.GetBytes( sb.ToString( ) );
}
/// <summary>
/// 从原始的结果数据对象中提取出数字数据
/// </summary>
/// <param name="commandLine">原始的字节数据</param>
/// <returns>带有结果对象的数据信息</returns>
public static OperateResult<int> GetNumberFromCommandLine( byte[] commandLine )
{
try
{
string command = Encoding.UTF8.GetString( commandLine ).TrimEnd( '\r', '\n' );
return OperateResult.CreateSuccessResult( Convert.ToInt32( command.Substring( 1 ) ) );
}
catch (Exception ex)
{
return new OperateResult<int>( ex.Message );
}
}
/// <summary>
/// 从原始的结果数据对象中提取出数字数据
/// </summary>
/// <param name="commandLine">原始的字节数据</param>
/// <returns>带有结果对象的数据信息</returns>
public static OperateResult<long> GetLongNumberFromCommandLine( byte[] commandLine )
{
try
{
string command = Encoding.UTF8.GetString( commandLine ).TrimEnd( '\r', '\n' );
return OperateResult.CreateSuccessResult( Convert.ToInt64( command.Substring( 1 ) ) );
}
catch (Exception ex)
{
return new OperateResult<long>( ex.Message );
}
}
/// <summary>
/// 从结果的数据对象里提取字符串的信息
/// </summary>
/// <param name="commandLine">原始的字节数据</param>
/// <returns>带有结果对象的数据信息</returns>
public static OperateResult<string> GetStringFromCommandLine( byte[] commandLine )
{
try
{
if (commandLine[0] != '$') return new OperateResult<string>( Encoding.UTF8.GetString( commandLine ) );
// 先找到换行符
int index_start = -1;
int index_end = -1;
// 下面的判断兼容windows系统及linux系统
for (int i = 0; i < commandLine.Length; i++)
{
if (commandLine[i] == '\r' || commandLine[i] == '\n')
{
index_start = i;
}
if (commandLine[i] == '\n')
{
index_end = i;
break;
}
}
int length = Convert.ToInt32( Encoding.UTF8.GetString( commandLine, 1, index_start - 1 ) );
if (length < 0) return new OperateResult<string>( "(nil) None Value" );
return OperateResult.CreateSuccessResult( Encoding.UTF8.GetString( commandLine, index_end + 1, length ) );
}
catch (Exception ex)
{
return new OperateResult<string>( ex.Message );
}
}
/// <summary>
/// 从redis的结果数据中分析出所有的字符串信息
/// </summary>
/// <param name="commandLine">结果数据</param>
/// <returns>带有结果对象的数据信息</returns>
public static OperateResult<string[]> GetStringsFromCommandLine( byte[] commandLine )
{
try
{
List<string> lists = new List<string>( );
if (commandLine[0] != '*') return new OperateResult<string[]>( Encoding.UTF8.GetString( commandLine ) );
int index = 0;
for (int i = 0; i < commandLine.Length; i++)
{
if (commandLine[i] == '\r' || commandLine[i] == '\n')
{
index = i;
break;
}
}
int length = Convert.ToInt32( Encoding.UTF8.GetString( commandLine, 1, index - 1 ) );
for (int i = 0; i < length; i++)
{
// 提取所有的字符串内容
int index_end = -1;
for (int j = index; j < commandLine.Length; j++)
{
if (commandLine[j] == '\n')
{
index_end = j;
break;
}
}
index = index_end + 1;
if (commandLine[index] == '$')
{
// 寻找子字符串
int index_start = -1;
for (int j = index; j < commandLine.Length; j++)
{
if (commandLine[j] == '\r' || commandLine[j] == '\n')
{
index_start = j;
break;
}
}
int stringLength = Convert.ToInt32( Encoding.UTF8.GetString( commandLine, index + 1, index_start - index - 1 ) );
if (stringLength >= 0)
{
for (int j = index; j < commandLine.Length; j++)
{
if (commandLine[j] == '\n')
{
index_end = j;
break;
}
}
index = index_end + 1;
lists.Add( Encoding.UTF8.GetString( commandLine, index, stringLength ) );
index = index + stringLength;
}
else
{
lists.Add( null );
}
}
else
{
int index_start = -1;
for (int j = index; j < commandLine.Length; j++)
{
if (commandLine[j] == '\r' || commandLine[j] == '\n')
{
index_start = j;
break;
}
}
lists.Add( Encoding.UTF8.GetString( commandLine, index, index_start - index - 1 ) );
}
}
return OperateResult.CreateSuccessResult( lists.ToArray( ) );
}
catch (Exception ex)
{
return new OperateResult<string[]>( ex.Message );
}
}
#endregion
}
}