Waste/Waste.Socket/MyPackageFilter.cs

354 lines
12 KiB
C#
Raw Permalink Normal View History

2021-05-27 16:58:40 +08:00
using SuperSocket.ProtoBase;
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Waste.Socket
{
public class MyPackageFilter : FixedHeaderPipelineFilter<MyPackage>
{
/// <summary>
/// Header size is 2
/// </summary>
public MyPackageFilter()
: base(2) //包头的大小是2字节所以将2传如基类的构造方法中去
{
}
/// <summary>
/// 从数据包的头部返回包体的大小
/// </summary>
/// <param name="buffer"></param>
/// <returns></returns>
protected override int GetBodyLengthFromHeader(ref ReadOnlySequence<byte> buffer)
{
int len = 0;
var reader = new SequenceReader<byte>(buffer);
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
string key = reader.ReadString(Encoding.GetEncoding("GB2312"));
if (key != "A9")
{
}
else
{
len = (int)buffer.Length - 2;
}
return len;
}
/// <summary>
/// 将数据包解析成 MyPackage 的实例
/// </summary>
/// <param name="buffer"></param>
/// <returns></returns>
protected override MyPackage DecodePackage(ref ReadOnlySequence<byte> buffer)
{
var package = new MyPackage();
var reader = new SequenceReader<byte>(buffer);
var _reader = reader;
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
2021-11-23 17:49:40 +08:00
package.Str = Tools.GetString(buffer);
2021-05-27 16:58:40 +08:00
reader.TryRead(out byte keyByte);
string key = keyByte.ByteToHexStr();
if (key != "A9")
{
var len = buffer.Length;
string msg = key;
for (var i = 1; i < len; i++)
{
reader.TryRead(out byte msgByte);
msg += msgByte.ByteToHexStr();
}
package.IsChecked = false;
package.Body = msg;
}
else
{
package.Key = key;
package.Len = (int)buffer.Length - 2;
string body = "";
byte[] bytes = new byte[package.Len];
for (var i = 0; i < package.Len; i++)
{
reader.TryRead(out byte val);
bytes[i] = val;
}
if (bytes.Length == 1 && bytes[0] == 0)
{
return null;
}
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
body = bytes.BytesToString().Replace("\n", "").Replace("\r", "");
package.Body = body;
var arr = body.Split('|');
#region ,IMEI|GPS
if (arr.Length == 2)
{
package.IsHeart = true;
package.IMEI = arr[0];
var gpsarr = arr[1].Split(',');
if (gpsarr.Length == 2)
{
package.Longitude = gpsarr[0];
package.Latitude = gpsarr[1];
}
}
else if (arr.Length == 7)
{
package.ICCID = arr[0];
package.IMEI = arr[1];
package.IMSI = arr[2];
package.GSLQ = arr[3];
package.Time = $"{arr[4]}{arr[5]}";
//九方城@前门@厨余垃圾@7.91
var measurearr = arr[6].Split('@');
if (measurearr.Length == 4)
{
package.City = measurearr[0];
package.Area = measurearr[1];
package.WasteType = measurearr[2];
package.Weight = measurearr[3];
}
}
#endregion
}
return package;
}
}
/// <summary>
/// 转换工具
/// </summary>
public static class Tools
{
2021-11-23 17:49:40 +08:00
public static string GetString(in this ReadOnlySequence<byte> payload,
Encoding encoding = null)
{
encoding ??= Encoding.UTF8;
return payload.IsSingleSegment ? encoding.GetString(payload.FirstSpan)
: GetStringSlow(payload, encoding);
static string GetStringSlow(in ReadOnlySequence<byte> payload, Encoding encoding)
{
// linearize
int length = checked((int)payload.Length);
var oversized = ArrayPool<byte>.Shared.Rent(length);
try
{
payload.CopyTo(oversized);
return encoding.GetString(oversized, 0, length);
}
finally
{
ArrayPool<byte>.Shared.Return(oversized);
}
}
}
2021-05-27 16:58:40 +08:00
/// <summary>
///
/// </summary>
/// <param name="bt"></param>
/// <returns></returns>
public static string ByteToHexStr(this byte bt)
{
return ((int)bt).ToString("X2");
}
/// <summary>
/// byte转int
/// </summary>
/// <param name="bt"></param>
/// <returns></returns>
public static int ByteToInt(this byte bt)
{
return Convert.ToInt32(((int)bt).ToString("X2"), 16);
}
/// <summary>
/// 字节数组转16进制
/// </summary>
/// <param name="bt"></param>
/// <returns></returns>
public static string BytesToHexStr(this byte[] bt)
{
string returnStr = "";
if (bt != null)
{
for (int i = 0; i < bt.Length; i++)
{
returnStr += bt[i].ToString("X2") + " ";
}
}
return returnStr;
}
/// <summary>
/// 字节数组转字符串
/// </summary>
/// <param name="bt"></param>
/// <returns></returns>
2021-11-23 17:49:40 +08:00
public static string BytesToString(this byte[] bytes)
2021-05-27 16:58:40 +08:00
{
string returnStr = "";
2021-11-23 17:49:40 +08:00
if (bytes != null)
2021-05-27 16:58:40 +08:00
{
2021-11-23 17:49:40 +08:00
returnStr = Encoding.GetEncoding("GB2312").GetString(bytes);
2021-05-27 16:58:40 +08:00
}
return returnStr;
}
2021-11-23 17:49:40 +08:00
/// <summary>
/// 字节数据转中文
/// </summary>
/// <param name="bytes"></param>
/// <returns></returns>
public static string BytesToChsString(this byte[] bytes)
{
string hex = BytesToHexStr(bytes);
if (hex == null)
return "";
if (hex.Length % 2 != 0)
{
hex += "20";//空格
}
for (int i = 0; i < bytes.Length; i++)
{
try
{
// 每两个字符是一个 byte。
bytes[i] = byte.Parse(hex.Substring(i * 2, 2),
System.Globalization.NumberStyles.HexNumber);
}
catch
{
}
}
// 获得 GB2312Chinese Simplified。
Encoding chs = Encoding.GetEncoding("gb2312");
return chs.GetString(bytes);
}
2021-05-27 16:58:40 +08:00
}
/// <summary>
/// 垃圾分类格式解析,传输过来的数据格式类似于:九方城@前门@厨余垃圾@7.91
/// </summary>
public class WastePackageFilter : PipelineFilterBase<MyPackage>
{
public override MyPackage Filter(ref SequenceReader<byte> reader)
{
try
{
if(reader.Length <= 0)
{
return null;
}
var package = new MyPackage();
var _reader = reader;
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
package.Str = _reader.ReadString(Encoding.GetEncoding("GB2312"));
string key = "";
int keylen = 1;
#region A9
if(reader.Length >= 2)
{
keylen = 2;
byte[] keys = new byte[2];
reader.TryRead(out byte key1Byte);
keys[0] = key1Byte;
reader.TryRead(out byte key2Byte);
keys[1] = key2Byte;
key = keys.BytesToString();
}
else
{
byte[] keys = new byte[1];
reader.TryRead(out byte key1Byte);
keys[0] = key1Byte;
key = keys.BytesToString();
}
#endregion
if (key != "A9")
{
var len = reader.Length;
string msg = "";
reader.Rewind(keylen);
for (var i = 0; i < len; i++)
{
reader.TryRead(out byte msgByte);
msg += msgByte.ByteToHexStr();
}
package.IsChecked = false;
package.Body = msg;
}
else
{
package.Key = key;
package.Len = (int)reader.Length - 2;
string body = "";
byte[] bytes = new byte[package.Len];
for (var i = 0; i < package.Len; i++)
{
reader.TryRead(out byte val);
bytes[i] = val;
}
if (bytes.Length == 1 && bytes[0] == 0)
{
return null;
}
body = bytes.BytesToString().Replace("\r", "").Replace("\n", "");
package.Body = bytes.BytesToHexStr();
var arr = body.Split('|');
#region ,IMEI|GPS
if (arr.Length == 2)
{
package.IsHeart = true;
package.IMEI = arr[0];
var gpsarr = arr[1].Split(',');
if (gpsarr.Length == 2)
{
package.Longitude = gpsarr[0];
package.Latitude = gpsarr[1];
}
}
else if (arr.Length == 7)
{
package.ICCID = arr[0];
package.IMEI = arr[1];
package.IMSI = arr[2];
var gslq = Encoding.GetEncoding("GB2312").GetBytes(arr[3]);
if(gslq.Length == 2)
{
package.GSLQ = Convert.ToInt32(gslq[1]).ToString();
}
else
{
package.GSLQ = gslq.BytesToHexStr();
}
package.Time = $"{arr[4]}{arr[5]}".Replace("-","").Replace(":","");
//九方城@前门@厨余垃圾@7.91
var measurearr = arr[6].Split('@');
if (measurearr.Length == 4)
{
package.City = measurearr[0];
package.Area = measurearr[1];
package.WasteType = measurearr[2];
package.Weight = measurearr[3];
package.IsWeight = true;
}
else
{
package.City = arr[6];//临时存放传递过来的数据
}
}
#endregion
}
return package;
}
catch (Exception ex)
{
Console.WriteLine($"数据处理发生异常:{ex.Message}");
return new MyPackage();
}
}
}
}