288 lines
10 KiB
C#
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;
|
|
|
|
}
|
|
}
|