using HslCommunication.Core; using System; using System.Collections.Generic; 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 } }