RaUI/Source/MyDb/Msg/MsgMain.cs
2020-11-28 15:03:57 +08:00

288 lines
10 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace QuickMsg
{
/// <summary>
/// 消息服务端类
/// </summary>
public class MsgMain
{
readonly CustomMsg MSG;
/// <summary>
/// 判断当前消息主服务器是否创建成功
/// </summary>
public bool IsOk
{
get;private set;
}
/// <summary>
/// 当收到消息时激发
/// </summary>
public event CustomMsg.MsgEventHandler OnMsg;
/// <summary>
/// 当收到自定义消息时(非系统消息)激发
/// </summary>
public event CustomMsg.MsgEventHandler OnCustomMsg;
/// <summary>
/// 有消息客户端发起连接请求时激发
/// </summary>
public event CustomMsg.MsgEventHandler OnConnect;
/// <summary>
/// 有消息客户端连接成功时激发
/// </summary>
public event CustomMsg.MsgEventHandler OnConnected;
/// <summary>
/// 有消息客户端断开连接时激发
/// </summary>
public event CustomMsg.MsgEventHandler OnDisConnect;
private readonly Form form=null;
/// <summary>
///
/// </summary>
/// <param name="id">服务端ID,需要唯一性,共客户端识别</param>
/// <param name="_form">服务端</param>
public MsgMain(string id,Form _form)
{
object mainHandle = RyMemoryShare.ReadFromMemory(1024, typeof(Int64), id);
if (mainHandle == null)
{
RyMemoryShare.WriteToMemory(1024, _form.Handle.ToInt64(), id);
form = _form;
MSG = new CustomMsg(_form);//创建消息通道
MSG.OnMsg += MSG_OnMsg;
IsOk = true;
}
else { IsOk = false; }
}
/// <summary>
/// 释放资源
/// </summary>
public void Free()
{
if(form!=null)
{
// RyMemoryShare.WriteToMemory(1024, form.Handle.ToInt64(), id);
}
}
/// <summary>
/// 判断是否包含指定客户端
/// </summary>
/// <param name="handle"></param>
/// <returns></returns>
public bool HaveClient(IntPtr handle)
{
bool isHave = false;
for (int i = 0; i < Client_list.Count; i++)
{
if (Client_list[i].Handle == handle) { isHave = true; break; }
}
return isHave;
}
/// <summary>
///
/// </summary>
public List<ClientItem> Client_list { get;private set; } = new List<ClientItem>();
/// <summary>
/// 设置客户端大小
/// </summary>
public void Resize(int width,int height)
{
ryCommon.Storage Stor = new ryCommon.Storage();
Stor.SelectNodeBySet();
Stor.SetAttrValue("op", "resize");
Stor.SetAttrValue("width", width);
Stor.SetAttrValue("height", height);
SendAll(MyDb.RyWin32.Sys_chanel_id, "xml"+Stor.XMLText);
}
/// <summary>
/// 根据客户端ID,获取客户端对象
/// </summary>
/// <param name="ClientId"></param>
/// <returns></returns>
public ClientItem GetClientItem(string ClientId)
{
for (int i = Client_list.Count - 1; i >= 0; i--)
{
if (Client_list[i].ClientId == ClientId)
{
return Client_list[i];
}
}
return null;
}
/// <summary>
/// 根据客户端句柄,获取客户端对象
/// </summary>
/// <param name="Handle"></param>
/// <returns></returns>
public ClientItem GetClientItem(IntPtr Handle)
{
for (int i = Client_list.Count - 1; i >= 0; i--)
{
if (Client_list[i].Handle == Handle)
{
return Client_list[i];
}
}
return null;
}
/// <summary>
/// 关闭所有客户端
/// </summary>
public void CloseClient()
{
SendAll(MyDb.RyWin32.Sys_chanel_id, "close");
Client_list.Clear();
}
/// <summary>
/// 关闭指定客户端
/// </summary>
/// <param name="handle"></param>
public void CloseClient(IntPtr handle)
{
MSG.Send(handle, MyDb.RyWin32.Sys_chanel_id, "close");
}
/// <summary>
/// 关闭指定客户端
/// </summary>
/// <param name="item"></param>
public void CloseClient(ClientItem item)
{
MSG.Send(item.Handle, MyDb.RyWin32.Sys_chanel_id, "close");
for (int i = Client_list.Count-1; i >=0; i--)
{
if(Client_list[i].Handle== item.Handle)
{
Client_list.RemoveAt(i);
}
}
}
/// <summary>
/// 向所有客户端发送消息,单线程
/// </summary>
/// <param name="wParam"></param>
/// <param name="msg"></param>
public void SendAll(int wParam, string msg)
{
for (int i = 0; i < Client_list.Count; i++)
{
MSG.Send2(Client_list[i].Handle, wParam, msg);//发送消息
}
}
/// <summary>
/// 向指定客户端发送消息
/// </summary>
/// <param name="handle"></param>
/// <param name="wParam"></param>
/// <param name="msg"></param>
public void Send(IntPtr handle, int wParam, string msg)
{
MSG.Send(handle, wParam, msg);//发送消息
}
/// <summary>
/// 关闭在指定时间前失去响应的子客户端
/// </summary>
/// <param name="dt"></param>
public void CloseLoseClient(DateTime dt)
{
for (int i = Client_list.Count - 1; i >= 0; i--)
{
if (Client_list[i].HeartTime<= dt)
{ Client_list.RemoveAt(i); }
}
}
private void MSG_OnMsg(object sender, MsgArgs e)
{
OnMsg?.Invoke(this,e);
if(e.WParam== MyDb.RyWin32.Sys_chanel_id) //如果是系统通道请求
{
switch(e.Msg_text)
{
case "disconnect"://断开连接
#region
for (int i = Client_list.Count - 1; i >= 0; i--)
{
if (Client_list[i].Handle == e.From_handle) { Client_list.RemoveAt(i); break; }
}
OnDisConnect?.Invoke(this, e);
break;
#endregion
case "heart"://心跳包
#region
MSG.Send(e.From_handle, MyDb.RyWin32.Sys_chanel_id,"heart");//回应给客户端
for (int i = Client_list.Count - 1; i >= 0; i--)
{
if (Client_list[i].Handle == e.From_handle)
{ Client_list[i].HeartTime=DateTime.Now; break; }
}
break;
#endregion
default:
#region xml消息
if (e.Msg_text.StartsWith("xml"))
{
ryCommon.Storage Stor = new ryCommon.Storage(e.Msg_text.Substring(3));
Stor.SelectNodeBySet();
switch (Stor.GetAttrValue("op"))
{
case "connect"://连接请求
#region
OnConnect?.Invoke(this, e);
if (!e.Cancel)//如果允许连接
{
bool isHave = false;
for (int i = 0; i < Client_list.Count; i++)
{
if (Client_list[i].Handle == e.From_handle) { Client_list[i].ConnectTime = DateTime.Now; isHave = true; break; }
}
if (!isHave)
{
Client_list.Add(new ClientItem() { Handle = e.From_handle, ClientId= Stor.GetAttrValue("clientid") });//加入到客户端列表里
}
MSG.Send(e.From_handle, e.WParam, "connected");//发送连接成功的通知
OnConnected?.Invoke(this, e);
}
break;
#endregion
}
}
break;
#endregion
}
}
else
{
OnCustomMsg?.Invoke(this, e);
}
}
}
/// <summary>
/// 客户端信息
/// </summary>
public class ClientItem
{
/// <summary>
/// 客户端句柄
/// </summary>
public IntPtr Handle { get; set; } = IntPtr.Zero;
/// <summary>
/// 客户端ID
/// </summary>
public string ClientId { get; set; } ="";
/// <summary>
/// 客户端连接时间
/// </summary>
public DateTime ConnectTime { get; set; } = DateTime.Now;
/// <summary>
/// 心跳时间
/// </summary>
public DateTime HeartTime { get; set; } = DateTime.Now;
}
}