首次提交:添加src文件夹代码
This commit is contained in:
@@ -0,0 +1,450 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user