Files
6078/src/StandardDomeNewApp/Communication/Sockets/SingleSocketServer.cs

451 lines
17 KiB
C#
Raw 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.SocketBase;
using SuperSocket.SocketBase.Protocol;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace StandardDomeNewApp.Communication.Sockets
{
public class SingleSocketServer
{
public SingleSocketServer(string encoding = null)
{
this.encoding = string.IsNullOrEmpty(encoding) ? Encoding.Default : Encoding.GetEncoding(encoding);
}
/// <summary>
/// 服务类型 1是supersocket 2是iocp
/// </summary>
private int serverType { set; get; }
/// <summary>
/// 解码方式
/// </summary>
public Encoding encoding { private set; get; }
/// <summary>
/// 服务对象
/// </summary>
private AppServer appServer { set; get; }
/// <summary>
///
/// </summary>
private socket.core.Server.TcpPushServer iocpServer { set; get; }
/// <summary>
///
/// </summary>
private Regex regex { set; get; } = new Regex(@"^%.*|.*%$");
/// <summary>
/// 会话字典
/// </summary>
public Dictionary<string, string> SessionIDDic { private set; get; } = new Dictionary<string, string>();
/// <summary>
/// 消息委托
/// </summary>
public Action<string, bool, Core.SysEnumInfon.MessageLogType> ShowMessageAction { set; get; }
/// <summary>
/// 接收消息委托 二进制数组的
/// </summary>
public Action<string, string> RequestReceivedAction { set; get; }
/// <summary>
/// 会话进来
/// </summary>
public Action<string> OnSessionAccept { set; get; }
/// <summary>
/// 会话结束
/// </summary>
public Action<string> OnSessionClose { set; get; }
public bool IsOpenServer { private set; get; }
public string ServerName { private set; get; }
/// <summary>
/// 是否允许接收字典
/// </summary>
public ConcurrentDictionary<string, bool> IsAllowReceiveDic { set; get; } = new ConcurrentDictionary<string, bool>();
/// <summary>
/// 会话数据字典
/// </summary>
public ConcurrentDictionary<string, string> SessionDataDic { set; get; } = new ConcurrentDictionary<string, string>();
#region
/// <summary>
/// 启动服务
/// </summary>
/// <param name="port">服务端口</param>
/// <param name="enddata">servertype为2时才有意义 结尾符</param>
public void StartServer(string serverkey, int port, byte[] enddata = null)
{
ServerName = serverkey;
if (enddata == null)
{
//当为空时使用iocp的方式
serverType = 2;
iocpServer = new socket.core.Server.TcpPushServer(100, 1024 * 2, 0);
if (ushort.TryParse(port.ToString(), out ushort port2))
{
try
{
iocpServer.Start(port);
}
catch (Exception ex)
{
ShowMessageAction?.Invoke("启动失败!" + ex.Message, false, Core.SysEnumInfon.MessageLogType.Warn);
}
IsOpenServer = true;
iocpServer.OnAccept += IocpServer_OnAccept;
iocpServer.OnClose += IocpServer_OnClose;
iocpServer.OnReceive += IocpServer_OnReceive;
}
else
{
ShowMessageAction?.Invoke("端口输入范围在0-65535的值", false, Core.SysEnumInfon.MessageLogType.Warn);
}
return;
}
//使用supersocket组件
serverType = 1;
if (enddata.Length < 1)
{
appServer = new AppServer();
}
else
{
appServer = new AppServer(new TerminatorReceiveFilterFactory(encoding.GetString(enddata)));
}
appServer.NewRequestReceived += AppServer_NewRequestReceived;
appServer.NewSessionConnected += AppServer_NewSessionConnected;
appServer.SessionClosed += AppServer_SessionClosed;
var serverconfig = new SuperSocket.SocketBase.Config.ServerConfig();
serverconfig.Port = port;
serverconfig.TextEncoding = encoding.EncodingName;
if (ushort.TryParse(port.ToString(), out ushort port1))
{
if (!appServer.Setup(serverconfig))
{
ShowMessageAction?.Invoke("设置错误!", false, Core.SysEnumInfon.MessageLogType.Warn);
return;
}
if (!appServer.Start())
{
ShowMessageAction?.Invoke("启动失败!", false, Core.SysEnumInfon.MessageLogType.Warn);
return;
}
IsOpenServer = true;
}
else
{
ShowMessageAction?.Invoke("端口输入范围在0-65535的值", false, Core.SysEnumInfon.MessageLogType.Warn);
}
}
/// <summary>
/// 结束服务
/// </summary>
public void StopServer()
{
if (!IsOpenServer)
{
ShowMessageAction?.Invoke("当前状态不需要断开监听!", false, Core.SysEnumInfon.MessageLogType.Info);
return;
}
if (serverType == 1)
{
appServer.Stop();
appServer.Dispose();
appServer = null;
}
else if (serverType == 2)
{
var dic = new Dictionary<int, string>(iocpServer.ClientList);
foreach (var item in dic)
{
iocpServer.Close(item.Key);
}
}
IsOpenServer = false;
}
/// <summary>
/// 会话发送
/// </summary>
/// <param name="datas"></param>
/// <param name="sessionid">为空时为广播</param>
public void SessionSend(byte[] datas, string sessionid = null)
{
if (datas == null || datas.Length < 1)
{
ShowMessageAction?.Invoke("数据为空,无效发送!", false, Core.SysEnumInfon.MessageLogType.Info);
return;
}
if (string.IsNullOrEmpty(sessionid))
{
if (serverType == 1)
{
var allsessions = appServer.GetAllSessions();
foreach (var item in allsessions)
{
item.Send(encoding.GetString(datas));
}
}
else if (serverType == 2)
{
foreach (var item in iocpServer.ClientList)
{
iocpServer.Send(item.Key, datas, 0, datas.Length);
}
}
}
else
{
if (serverType == 1)
{
var one = appServer.GetSessionByID(sessionid);
if (one != null)
{
one.Send(encoding.GetString(datas));
}
else
{
ShowMessageAction?.Invoke("请检查传入的会话ID是否有效当前无法查询到相关会话信息无效发送", false, Core.SysEnumInfon.MessageLogType.Info);
}
}
else if (serverType == 2)
{
if (int.TryParse(sessionid, out int num) && iocpServer.ClientList.ContainsKey(num))
{
iocpServer.Send(num, datas, 0, datas.Length);
}
else
{
ShowMessageAction?.Invoke("请检查传入的会话ID是否有效当前无法查询到相关会话信息无效发送", false, Core.SysEnumInfon.MessageLogType.Info);
}
}
}
}
/// <summary>
/// 会话发送
/// </summary>
/// <param name="datas"></param>
/// <param name="sessionid">为空时为广播</param>
public void SessionSend(string datas, string sessionid = null)
{
if (string.IsNullOrEmpty(datas))
{
ShowMessageAction?.Invoke("数据为空,无效发送!", false, Core.SysEnumInfon.MessageLogType.Info);
return;
}
if (string.IsNullOrEmpty(sessionid))
{
if (serverType == 1)
{
var allsessions = appServer.GetAllSessions();
foreach (var item in allsessions)
{
item.Send(datas);
}
}
else if (serverType == 2)
{
foreach (var item in iocpServer.ClientList)
{
iocpServer.Send(item.Key, encoding.GetBytes(datas), 0, datas.Length);
}
}
}
else
{
if (serverType == 1)
{
var one = appServer.GetSessionByID(sessionid);
if (one != null)
{
one.Send(datas);
}
else
{
ShowMessageAction?.Invoke("请检查传入的会话ID是否有效当前无法查询到相关会话信息无效发送", false, Core.SysEnumInfon.MessageLogType.Info);
}
}
else if (serverType == 2)
{
if (int.TryParse(sessionid, out int num) && iocpServer.ClientList.ContainsKey(num))
{
iocpServer.Send(num, encoding.GetBytes(datas), 0, datas.Length);
}
else
{
ShowMessageAction?.Invoke("请检查传入的会话ID是否有效当前无法查询到相关会话信息无效发送", false, Core.SysEnumInfon.MessageLogType.Info);
}
}
}
}
/// <summary>
/// 返回地址对应的sessionid 可能返回为空
/// </summary>
/// <param name="ipaddress"></param>
/// <returns></returns>
public string GetSessionID(string ipaddress)
{
string sessionid = null;
var datas = SessionIDDic.Where(d => d.Value == ipaddress);
if (datas != null)
{
var list = datas.ToList();
if (list.Count > 0)
{
var oneitem = list.ElementAt(0);
sessionid = oneitem.Key;
}
}
return sessionid;
}
/// <summary>
/// 返回id对应的地址 可能返回为空
/// </summary>
/// <param name="sessionid"></param>
/// <returns></returns>
public string GetIpAddress(string sessionid)
{
if (SessionIDDic.ContainsKey(sessionid))
{
return SessionIDDic[sessionid];
}
return null;
}
#endregion
#region
/// <summary>
/// 会话关闭
/// </summary>
/// <param name="session"></param>
/// <param name="value"></param>
private void AppServer_SessionClosed(AppSession session, CloseReason value)
{
if (SessionIDDic.ContainsKey(session.SessionID))
{
SessionIDDic.Remove(session.SessionID);
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append("会话:");
stringBuilder.Append(session.SessionID);
stringBuilder.Append("(");
stringBuilder.Append(session.RemoteEndPoint.Address);
stringBuilder.Append(":");
stringBuilder.Append(session.RemoteEndPoint.Port.ToString());
stringBuilder.Append(")");
stringBuilder.Append("关闭!关闭原因:");
stringBuilder.Append(value.ToString());
ShowMessageAction?.Invoke(stringBuilder.ToString(), false, Core.SysEnumInfon.MessageLogType.Info);
OnSessionClose?.Invoke(session.SessionID);
}
}
private void IocpServer_OnClose(int obj)
{
if (SessionIDDic.ContainsKey(obj.ToString()))
{
SessionIDDic.Remove(obj.ToString());
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append("会话:");
stringBuilder.Append(obj.ToString());
stringBuilder.Append("(");
if (iocpServer.ClientList.ContainsKey(obj))
{
stringBuilder.Append(iocpServer.ClientList[obj]);
}
stringBuilder.Append(")");
stringBuilder.Append("关闭!关闭原因:用户退出!");
ShowMessageAction?.Invoke(stringBuilder.ToString(), false, Core.SysEnumInfon.MessageLogType.Info);
OnSessionClose?.Invoke(obj.ToString());
}
}
/// <summary>
/// 会话新连接
/// </summary>
/// <param name="session"></param>
private void AppServer_NewSessionConnected(AppSession session)
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append(session.RemoteEndPoint.Address);
stringBuilder.Append(":");
stringBuilder.Append(session.RemoteEndPoint.Port.ToString());
string info = stringBuilder.ToString();
//记录会话id与物理地址的关系
SessionIDDic[session.SessionID] = info;
stringBuilder.Remove(0, stringBuilder.Length);
stringBuilder.Append("新进会话:");
stringBuilder.Append(session.SessionID);
stringBuilder.Append("(");
stringBuilder.Append(info);
stringBuilder.Append(")");
ShowMessageAction?.Invoke(stringBuilder.ToString(), false, Core.SysEnumInfon.MessageLogType.Info);
OnSessionAccept?.Invoke(session.SessionID);
}
/// <summary>
/// 新的会话进来
/// </summary>
/// <param name="obj"></param>
private void IocpServer_OnAccept(int obj)
{
StringBuilder stringBuilder = new StringBuilder();
if (!iocpServer.ClientList.ContainsKey(obj))
{
return;
}
stringBuilder.Append(iocpServer.ClientList[obj]);
string info = stringBuilder.ToString();
//记录会话id与物理地址的关系
SessionIDDic[obj.ToString()] = info;
stringBuilder.Remove(0, stringBuilder.Length);
stringBuilder.Append("新进会话:");
stringBuilder.Append(obj.ToString());
stringBuilder.Append("(");
stringBuilder.Append(info);
stringBuilder.Append(")");
ShowMessageAction?.Invoke(stringBuilder.ToString(), false, Core.SysEnumInfon.MessageLogType.Info);
OnSessionAccept?.Invoke(obj.ToString());
}
/// <summary>
/// 会话信息接收
/// </summary>
/// <param name="session"></param>
/// <param name="requestInfo"></param>
private void AppServer_NewRequestReceived(AppSession session, StringRequestInfo requestInfo)
{
var sessionid = session.SessionID;
var bdatas = requestInfo.Key + "%" + requestInfo.Body;
if (string.IsNullOrEmpty(bdatas))
{
//空数据不解析
return;
}
if (regex.IsMatch(bdatas))
{
//如果有%在头或者尾
bdatas = bdatas.Replace("%", "").Trim();
}
RequestReceivedAction(sessionid, bdatas);
}
/// <summary>
/// 接收消息
/// </summary>
/// <param name="arg1"></param>
/// <param name="arg2"></param>
private void IocpServer_OnReceive(int arg1, byte[] arg2)
{
RequestReceivedAction(arg1.ToString(), encoding.GetString(arg2));
}
#endregion
}
}