using LiteNetLib;
using LiteNetLib.Utils;
using MessagePack;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel;
namespace LiteNetServer
{
public partial class Form1 : Form
{
public LiteNetService NetService = new LiteNetService();
public Form1()
{
InitializeComponent();
if (NetService.server.IsRunning) MT.ps(listBox1, "Server starting... Port:" + NetService.server.LocalPort);
Task.Run(Thread1);
}
//发对象
private void button2_Click(object sender, EventArgs e)
{
List<OBJ01> playerList = new();
for (int i = 0; i< 100000; i++)
playerList.Add(new OBJ01 { id = 1, aaa = "哈哈哈哈", x = 100, y = 100 });
MT.SendListToClient(NetService.clients, int.Parse(textBox1.Text), MsgType.OBJ01, playerList);
MT.ps(listBox1, "向客户端ID:" + textBox1.Text + " 发送对象player");
}
private void button3_Click(object sender, EventArgs e)
{
List<OBJ02> items = new();
for (int i = 0; i< 10000; i++)
items.Add(new OBJ02 { id = 1001, bbb = "物品1", z = 10 });
MT.SendListToClient(NetService.clients, int.Parse(textBox1.Text), MsgType.OBJ02, items);
MT.ps(listBox1, "向客户端ID:" + textBox1.Text + " 发送对象item");
}
void Thread1()
{
while (true)
{
Task.Delay(200).Wait();
// 连接请求
var reqs = NetService?.FetchAndClearConnectionRequests();
if (reqs.Count > 0)
{
foreach (var r in reqs)
MT.ps(listBox1, $"收到连接请求 {r.RemoteEndPoint} 时间:{r.Timestamp:HH:mm:ss}");
}
// 连接成功
var conns = NetService?.FetchAndClearPeerConnectedMessages();
if (conns.Count > 0)
{
foreach (var p in conns)
MT.ps(listBox1, $"客户端已连接,ID:{p.Id} 时间:{p.Timestamp:HH:mm:ss}");
}
// 连接断开
var disconns = NetService?.FetchAndClearPeerDisconnectedMessages();
if (disconns.Count > 0)
{
foreach (var d in disconns)
MT.ps(listBox1, $"客户端断开,ID:{d.Id} 原因:{d.Reason} 时间:{d.Timestamp:HH:mm:ss}");
}
// 收到消息
var recvs = NetService?.FetchAndClearObj01Lists();
if (recvs.Count>0)
{
List<OBJ01> usblist = recvs.First();
MT.ps(listBox1, $"收到客户端OBJ01:{recvs.Count}, usblist数量:{usblist.Count}");
}
var recvs2 = NetService?.FetchAndClearObj02Lists();
if (recvs2.Count>0)
{
List<OBJ02> usblist = recvs2.First();
MT.ps(listBox1, $"收到客户端OBJ02:{recvs2.Count}, usblist数量:{usblist.Count}");
}
}
}
}
}
复制代码
LiteNetService
cs复制代码
using LiteNetLib;
using LiteNetLib.Utils;
using MessagePack;
using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
namespace LiteNetServer
{
public class LiteNetService : IDisposable
{
public static EventBasedNetListener listener = new EventBasedNetListener();
public NetManager server = new NetManager(listener);
public Dictionary<int, NetPeer> clients = new();
// 事件消息队列(并行安全)
public ConcurrentQueue<ConnectionRequestMsg> ConnectionRequests { get; } = new();
public ConcurrentQueue<PeerConnectedMsg> PeerConnectedMessages { get; } = new();
public ConcurrentQueue<PeerDisconnectedMsg> PeerDisconnectedMessages { get; } = new();
// 新增:接收到的 OBJ01 列表队列(并行安全)
public ConcurrentQueue<List<OBJ01>> Obj01Messages { get; } = new();
public ConcurrentQueue<List<OBJ02>> Obj02Messages { get; } = new();
// 公开事件,保留但可不订阅
public event Action<ConnectionRequest> ConnectionRequestEvent;
public event Action<NetPeer> PeerConnectedEvent;
public event Action<NetPeer, DisconnectInfo> PeerDisconnectedEvent;
public event Action<NetPeer, NetPacketReader, byte, DeliveryMethod> NetworkReceiveEvent;
// Fetch 方法:从并发队列中取出并返回当前所有元素
public List<ConnectionRequestMsg> FetchAndClearConnectionRequests()
{
var list = new List<ConnectionRequestMsg>();
while (ConnectionRequests.TryDequeue(out var item))
list.Add(item);
return list;
}
public List<PeerConnectedMsg> FetchAndClearPeerConnectedMessages()
{
var list = new List<PeerConnectedMsg>();
while (PeerConnectedMessages.TryDequeue(out var item))
list.Add(item);
return list;
}
public List<PeerDisconnectedMsg> FetchAndClearPeerDisconnectedMessages()
{
var list = new List<PeerDisconnectedMsg>();
while (PeerDisconnectedMessages.TryDequeue(out var item))
list.Add(item);
return list;
}
// 取出所有 OBJ01 消息(每个元素是一次从网络反序列化得到的 List<OBJ01>)
public List<List<OBJ01>> FetchAndClearObj01Lists()
{
var list = new List<List<OBJ01>>();
while (Obj01Messages.TryDequeue(out var item))
list.Add(item);
return list;
}
public List<List<OBJ02>> FetchAndClearObj02Lists()
{
var list = new List<List<OBJ02>>();
while (Obj02Messages.TryDequeue(out var item))
list.Add(item);
return list;
}
// 构造函数:初始化监听器、服务器,并订阅事件
public LiteNetService()
{
listener.ConnectionRequestEvent += OnConnectionRequestHandler;
listener.PeerConnectedEvent += OnPeerConnectedHandler;
listener.PeerDisconnectedEvent += OnPeerDisconnectedHandler;
listener.NetworkReceiveEvent += OnNetworkReceiveHandler;
server.Start(1435);
Task.Run(Thread2);
}
void Thread2()
{
while (true)
{
Task.Delay(200).Wait();
if (server == null) continue;
server.PollEvents();
}
}
// 使用命名方法替代 lambda,便于理解
private void OnConnectionRequestHandler(ConnectionRequest request)
{
try
{
request.AcceptIfKey("KEY20260601");
ConnectionRequests.Enqueue(new ConnectionRequestMsg
{
RemoteEndPoint = request.RemoteEndPoint?.ToString(),
Timestamp = DateTime.Now
});
}
catch { }
ConnectionRequestEvent?.Invoke(request);
}
private void OnPeerConnectedHandler(NetPeer peer)
{
clients[peer.Id] = peer;
PeerConnectedMessages.Enqueue(new PeerConnectedMsg
{
Id = peer.Id,
EndPoint = peer.Id.ToString(),
Timestamp = DateTime.Now
});
PeerConnectedEvent?.Invoke(peer);
}
private void OnPeerDisconnectedHandler(NetPeer peer, DisconnectInfo info)
{
if (clients.ContainsKey(peer.Id))
clients.Remove(peer.Id);
PeerDisconnectedMessages.Enqueue(new PeerDisconnectedMsg
{
Id = peer.Id,
Reason = info.Reason.ToString(),
Timestamp = DateTime.Now
});
PeerDisconnectedEvent?.Invoke(peer, info);
}
private void OnNetworkReceiveHandler(NetPeer peer, NetPacketReader reader, byte channel, DeliveryMethod method)
{
MsgType type = (MsgType)reader.GetByte();
byte[] data = reader.GetRemainingBytes();
if (type == MsgType.OBJ01)
{
Obj01Messages.Enqueue(MessagePackSerializer.Deserialize<List<OBJ01>>(data));
}
else if (type == MsgType.OBJ02)
{
Obj02Messages.Enqueue(MessagePackSerializer.Deserialize<List<OBJ02>>(data));
}
reader.Recycle();
}
public void Dispose()
{
server.Stop();
server = null;
listener = null;
clients.Clear();
}
}
// 事件消息对象
public class ConnectionRequestMsg
{
public string RemoteEndPoint { get; set; }
public DateTime Timestamp { get; set; }
}
public class PeerConnectedMsg
{
public int Id { get; set; }
public string EndPoint { get; set; }
public DateTime Timestamp { get; set; }
}
public class PeerDisconnectedMsg
{
public int Id { get; set; }
public string Reason { get; set; }
public DateTime Timestamp { get; set; }
}
}
cs复制代码
using LiteNetLib;
using LiteNetLib.Utils;
using MessagePack;
using System;
using System.Collections.Generic;
using System.Text;
namespace LiteNetServer
{
partial class MT
{
public static void ps(ListBox listBox1, string text)
{
if (listBox1.InvokeRequired)
{
listBox1.Invoke(new Action(() => listBox1.Items.Add("[" + DateTime.Now.ToString("HH:mm:ss") + "] " + text)));
}
else
{
listBox1.Items.Add("[" + DateTime.Now.ToString("HH:mm:ss") + "] " + text);
}
}
public static void SendListToClient<T>(Dictionary<int, NetPeer> clients, int clientid, MsgType msgType, List<T> ObjList)
{
if (clients.TryGetValue(clientid, out NetPeer peer) && peer.ConnectionState == ConnectionState.Connected)
{
var writer = new NetDataWriter();
writer.Put((byte)msgType);
writer.Put(MessagePackSerializer.Serialize(ObjList));
peer.Send(writer, DeliveryMethod.ReliableOrdered);
}
else
{
}
}
}
}
cs复制代码
using LiteNetLib.Utils;
using MessagePack;
using System;
using System.Collections.Generic;
using System.Text;
namespace LiteNetServer
{
internal class MO
{
}
// 必须加这个特性!MessagePack 序列化用
[MessagePackObject]
public class OBJ01
{
// 用 Key 标记序列化顺序(必须唯一)
[Key(0)] public int id { get; set; }
[Key(1)] public string aaa { get; set; }
[Key(2)] public int x { get; set; }
[Key(3)] public int y { get; set; }
}
[MessagePackObject]
public class OBJ02
{
[Key(0)] public int id { get; set; }
[Key(1)] public string bbb { get; set; }
[Key(2)] public int z { get; set; }
}
// 消息ID
public enum MsgType : byte
{
OBJ01 = 1,
OBJ02 = 2
}
}