Unity 网络编程RPC层
初学者,自用笔记
基础类
// 通用网络消息
public class NetMessage
{
public int MessageType; // 消息类型ID
public int RequestId; // 请求ID
public bool NeedResponse; // 是否需要响应
public byte[] Payload; // 业务数据
}
消息处理器
职责抽象
// 消息处理器接口:按消息类型处理
public interface IMessageHandler
{
int MessageType { get; } // 当前处理哪种消息
void Handle(NetMessage msg,int clientId); // 处理消息
}
// 处理器注册表接口
public interface IMessageHandlerRegistry
{
void Register(IMessageHandler handler); // 注册处理器
bool TryGetHandler(int messageType, out IMessageHandler handler); // 查找处理器
}
具体实现
// 处理器注册表实现
public class MessageHandlerRegistry : IMessageHandlerRegistry
{
private readonly Dictionary<int, IMessageHandler> _handlers = new Dictionary<int, IMessageHandler>();
// 注册处理器
public void Register(IMessageHandler handler)
{
if (handler == null) return;
_handlers[handler.MessageType] = handler;
}
// 查找处理器
public bool TryGetHandler(int messageType, out IMessageHandler handler)
{
return _handlers.TryGetValue(messageType, out handler);
}
}
// 示例:登录请求处理器
public class LoginRequestHandler : IMessageHandler
{
public int MessageType => 1001;
private readonly IRpcResponder _responder;
public LoginRequestHandler(IRpcResponder responder)
{
_responder = responder;
}
public void Handle(NetMessage msg,int clientId)
{
// 处理登录逻辑
var response = new NetMessage
{
MessageType = 1002,
Payload = Encoding.UTF8.GetBytes("Login OK")
};
// 回包给请求方
_responder.Reply(clientId, msg, response);
}
}
服务端
响应器
// RPC响应器接口:负责把响应发回给请求方
public interface IRpcResponder
{
void Reply(int clientId, NetMessage request, NetMessage response);
}
// RPC响应器实现
public class RpcResponder : IRpcResponder
{
private readonly IServerSessionManager _sessionManager; // 会话管理器
public RpcResponder(IServerSessionManager sessionManager)
{
_sessionManager = sessionManager;
}
// 给指定客户端回包
public void Reply(int clientId, NetMessage request, NetMessage response)
{
if (request == null || response == null) return;
// 保留原请求ID,方便客户端匹配回调
response.RequestId = request.RequestId;
response.NeedResponse = false;
_sessionManager.SendTo(clientId, response);
}
}
职责抽象
// 通用RPC服务端接口
public interface IRpcServer
{
void Broadcast(NetMessage msg); // 广播给所有客户端
void SendTo(int clientId, NetMessage msg); // 发给指定客户端
void RegisterHandler(IMessageHandler handler); // 注册处理器
void Start(string ip, int port); // 启动服务
void Stop(); // 停止服务
}
具体实现
// RPC服务端实现:负责广播、单播、消息分发
public class RpcServer : IRpcServer
{
private readonly IServerSessionManager _sessionManager; // 会话管理器
private readonly IMessageHandlerRegistry _handlerRegistry; // 处理器注册表
public RpcServer(
IServerSessionManager sessionManager,
IMessageHandlerRegistry handlerRegistry)
{
_sessionManager = sessionManager;
_handlerRegistry = handlerRegistry;
// 监听会话层收到的消息
_sessionManager.OnMessageReceived += OnSessionMessageReceived;
}
// 启动服务
public void Start(string ip, int port)
{
_sessionManager.Start(ip, port);
}
// 停止服务
public void Stop()
{
_sessionManager.Stop();
}
// 注册消息处理器
public void RegisterHandler(IMessageHandler handler)
{
_handlerRegistry.Register(handler);
}
// 广播消息给所有客户端
public void Broadcast(NetMessage msg)
{
if (msg == null) return;
msg.NeedResponse = false;
_sessionManager.Broadcast(msg);
}
// 发送消息给指定客户端
public void SendTo(int clientId, NetMessage msg)
{
if (msg == null) return;
msg.NeedResponse = false;
_sessionManager.SendTo(clientId, msg);
}
// 会话层收到消息后,交给处理器
private void OnSessionMessageReceived(object obj, int clientId)
{
if (obj is not NetMessage msg) return;
if (_handlerRegistry.TryGetHandler(msg.MessageType, out var handler))
{
handler.Handle(msg,clientId);
}
}
}
客户端
请求器
// 请求上下文:保存请求信息和回调
public class RpcRequestContext
{
public int RequestId; // 请求ID
public float SendTime; // 发送时间
public float Timeout; // 超时时间
public Action<NetMessage> Callback; // 响应回调
}
// 请求管理器接口:管理请求、响应、超时
public interface IRpcRequestManager
{
int NextRequestId(); // 获取新的请求ID
void AddRequest(int requestId, float timeout, Action<NetMessage> callback); // 添加请求
void OnResponse(NetMessage msg); // 收到响应
void Tick(float now); // 超时检查
}
// 请求管理器实现
public class RpcRequestManager : IRpcRequestManager
{
private readonly Dictionary<int, RpcRequestContext> _requests = new Dictionary<int, RpcRequestContext>();
private int _nextId = 1;
// 获取下一个请求ID
public int NextRequestId()
{
return _nextId++;
}
// 添加请求
public void AddRequest(int requestId, float timeout, Action<NetMessage> callback)
{
_requests[requestId] = new RpcRequestContext
{
RequestId = requestId,
SendTime = Time.realtimeSinceStartup,
Timeout = timeout,
Callback = callback
};
}
// 收到响应
public void OnResponse(NetMessage msg)
{
if (msg == null) return;
if (_requests.TryGetValue(msg.RequestId, out var ctx))
{
_requests.Remove(msg.RequestId);
ctx.Callback?.Invoke(msg);
}
}
// 检查超时
public void Tick(float now)
{
var timeoutList = _requests
.Where(kvp => now - kvp.Value.SendTime > kvp.Value.Timeout)
.Select(kvp => kvp.Key)
.ToList();
foreach (var requestId in timeoutList)
{
_requests.Remove(requestId);
}
}
}
职责抽象
// 通用RPC客户端接口
public interface IRpcClient
{
void Send(NetMessage msg); // 普通同步消息发送
void SendRequest(NetMessage msg, float timeout, Action<NetMessage> callback); // 请求消息发送
void RegisterHandler(IMessageHandler handler); // 注册处理器
void Connect(string ip, int port); // 连接服务端
void Disconnect(); // 断开连接
event Action<bool> OnConnectStateChanged; // 连接状态变更
}
具体实现
// RPC客户端实现:负责同步消息、请求消息、回包和处理器分发
public class RpcClient : IRpcClient
{
private readonly IClientNetworkSession _session; // 会话层
private readonly IMessageHandlerRegistry _handlerRegistry; // 处理器注册表
private readonly IRpcRequestManager _requestManager; // 请求管理器
public event Action<bool> OnConnectStateChanged;
public RpcClient(
IClientNetworkSession session,
IMessageHandlerRegistry handlerRegistry,
IRpcRequestManager requestManager)
{
_session = session;
_handlerRegistry = handlerRegistry;
_requestManager = requestManager;
// 会话层连接状态转发
_session.OnConnected += () => OnConnectStateChanged?.Invoke(true);
_session.OnDisconnected += () => OnConnectStateChanged?.Invoke(false);
// 会话层收到消息后进入 RPC 层
_session.OnMessageReceived += OnSessionMessageReceived;
}
// 连接服务端
public void Connect(string ip, int port)
{
_session.Connect(ip, port);
}
// 断开连接
public void Disconnect()
{
_session.Close();
}
// 注册业务消息处理器
public void RegisterHandler(IMessageHandler handler)
{
_handlerRegistry.Register(handler);
}
// 普通同步消息发送
public void Send(NetMessage msg)
{
if (msg == null) return;
msg.NeedResponse = false;
_session.Send(msg);
}
// 请求消息发送:带超时和回调
public void SendRequest(NetMessage msg, float timeout, Action<NetMessage> callback)
{
if (msg == null) return;
int requestId = _requestManager.NextRequestId();
msg.RequestId = requestId;
msg.NeedResponse = true;
_requestManager.AddRequest(requestId, timeout, callback);
_session.Send(msg);
}
// 会话层收到消息后统一进入这里
private void OnSessionMessageReceived(object obj)
{
if (obj is not NetMessage msg) return;
// 如果是响应消息,交给请求管理器
if (msg.RequestId > 0 && !msg.NeedResponse)
{
_requestManager.OnResponse(msg);
return;
}
// 如果是普通业务消息,按类型分发给处理器
if (_handlerRegistry.TryGetHandler(msg.MessageType, out var handler))
{
handler.Handle(msg);
}
}
// 每帧更新:检查请求超时
public void Tick(float deltaTime)
{
_requestManager.Tick(Time.realtimeSinceStartup);
}
}