LaJiFenLei/Waste.Socket/MyPackageFilter.cs

354 lines
12 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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);
package.Str = Tools.GetString(buffer);
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
{
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);
}
}
}
/// <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>
public static string BytesToString(this byte[] bytes)
{
string returnStr = "";
if (bytes != null)
{
returnStr = Encoding.GetEncoding("GB2312").GetString(bytes);
}
return returnStr;
}
/// <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);
}
}
/// <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();
}
}
}
}