6 major server modules (PdkFriendServer/GlobalSever/ServerCore/GameModule/GameNetModule) + game logic (GameFix/GameDAL/ServerData) + network layer (NetWorkMessage) + data layer (ObjectModel) + utilities (MrWu/Core/Config/CloudAPI/dll) + adapters (zyxAdapter/base) .NET 8.0 C# solution, 16 projects, 958 source files
226 lines
7.5 KiB
C#
226 lines
7.5 KiB
C#
using System;
|
||
using System.Collections.Concurrent;
|
||
using System.Diagnostics;
|
||
using System.IO;
|
||
using System.Threading;
|
||
using ActorCore;
|
||
using GameMessage;
|
||
using MessagePack.Formatters;
|
||
using NetWorkMessage;
|
||
using Server.Core.Extend;
|
||
using Debug = MrWu.Debug.Debug;
|
||
|
||
namespace Server.Net
|
||
{
|
||
/// <summary>
|
||
/// 这个是路由过来的用户Session用来做对象池
|
||
/// </summary>
|
||
public class UserSession : IUserSession
|
||
{
|
||
/// <summary>
|
||
/// 实例Id
|
||
/// </summary>
|
||
public long Id { get; private set; }
|
||
|
||
/// <summary>
|
||
/// 实例ID 如果Id 改变就不能用了,不再是之前的用户
|
||
/// </summary>
|
||
public long InstanceId { get; private set; }
|
||
|
||
/// <summary>
|
||
/// 登录验证码
|
||
/// </summary>
|
||
public string VerificationCode { get; set; }
|
||
|
||
public string RemoteIPAddress { get; set; }
|
||
|
||
public bool IsDisConnected { get; set; }
|
||
|
||
public SessionUserData UserData { get; private set; }
|
||
|
||
/// <summary>
|
||
/// UserData 设置的时候需要锁
|
||
/// </summary>
|
||
public readonly object DisConnectLock = new object();
|
||
|
||
// 收到链接包 -> State = Using
|
||
// 收到断开包 然后就回复断开成功的包 Session设置为断开
|
||
|
||
//UserSession 被 ProxySession 包装使用, 代理持有UserSession 那么RefCount + 1 当ProxySession 销毁那么RefCount - 1
|
||
|
||
public UserSession(long id, long instanceId)
|
||
{
|
||
this.Id = id;
|
||
this.InstanceId = instanceId;
|
||
}
|
||
|
||
public void BindUser(int userid, string uuid, int clientVer, int plat, string deviceInfo,bool isNewUser,string storeType, bool reset = false)
|
||
{
|
||
if (IsDisConnected)
|
||
{
|
||
return;
|
||
}
|
||
|
||
if (!reset && UserData != null)
|
||
{
|
||
Debug.Error("该会话已经绑定了用户数据!");
|
||
return;
|
||
}
|
||
|
||
ClearUserData();
|
||
|
||
UserData = SessionUserData.Create(userid, uuid, clientVer, plat, deviceInfo,isNewUser, storeType);
|
||
SessionUUIDManager.Instance.AddSessionUUID(uuid, UserData);
|
||
GameNetDispatcher.Instance.Dispatch(GameNetMsgId.SessionBindUser, this);
|
||
}
|
||
|
||
private const int WarningCnt = 30 * 8 * 1024;
|
||
|
||
/// <summary>
|
||
/// 发送数据给客户端
|
||
/// </summary>
|
||
/// <param name="buffer"></param>
|
||
/// <param name="messageType"></param>
|
||
public void Send(byte[] buffer, Type messageType)
|
||
{
|
||
if (buffer == null)
|
||
{
|
||
Debug.Error("不能发送空数据!");
|
||
return;
|
||
}
|
||
|
||
if (IsDisConnected)
|
||
{
|
||
Debug.Info($"链接并未在使用,不能发送! {Id} {this.InstanceId}");
|
||
return;
|
||
}
|
||
|
||
//发送给客户端
|
||
Server2ClientMessage message = Server2ClientMessage.Create();
|
||
int len = PacketUtility.MessageParseDataV1(buffer, messageType, message.MemoryStream);
|
||
byte[] data = new byte[len];
|
||
int count = message.MemoryStream.Read(data, 0, len);
|
||
if (count != len)
|
||
{
|
||
Debug.Error($"怎么会读取的数据跟要读取的长度不一致! {len} {count}");
|
||
}
|
||
|
||
if (buffer.Length > WarningCnt)
|
||
{
|
||
Debug.ImportantLog($"还有包大于240K? {messageType}");
|
||
}
|
||
|
||
message.Data = data;
|
||
Send2Router(message);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 这个只能用来发送给客户端
|
||
/// </summary>
|
||
/// <param name="messageData"></param>
|
||
public void Send(MessageData messageData)
|
||
{
|
||
if (messageData == null)
|
||
{
|
||
Debug.Error("不能发送空数据!");
|
||
return;
|
||
}
|
||
|
||
if (IsDisConnected)
|
||
{
|
||
Debug.Info($"链接并未在使用,不能发送! - {Id} {this.InstanceId}");
|
||
return;
|
||
}
|
||
|
||
//发送给客户端
|
||
Server2ClientMessage message = Server2ClientMessage.Create();
|
||
int len = PacketUtility.MessageParseDataV1(messageData, message.MemoryStream, message.CompressStream);
|
||
byte[] data = new byte[len];
|
||
int count = message.MemoryStream.Read(data, 0, len);
|
||
if (count != len)
|
||
{
|
||
Debug.Error($"怎么会读取的数据跟要读取的长度不一致! {len} {count}");
|
||
}
|
||
|
||
//Debug.Info($"压缩标记:{data[0]},opcode:{BitConverter.ToInt32(data,1)}");
|
||
message.Data = data;
|
||
Send2Router(message);
|
||
}
|
||
|
||
private IActor MainActor;
|
||
|
||
private IActor UerNetActor;
|
||
|
||
private void GetActor()
|
||
{
|
||
if (MainActor == null)
|
||
{
|
||
MainActor = ActorManager.Instance.Get(ActorTypeId.Main);
|
||
}
|
||
|
||
if (UerNetActor == null)
|
||
{
|
||
UerNetActor = ActorManager.Instance.Get(ActorTypeId.UserNet);
|
||
}
|
||
}
|
||
|
||
private void Send2Router(MessageObject message)
|
||
{
|
||
GetActor();
|
||
|
||
UserNetSendMessage userNetSendMessage = new UserNetSendMessage();
|
||
userNetSendMessage.Id = Id;
|
||
userNetSendMessage.InstanceId = InstanceId;
|
||
userNetSendMessage.MessageObject = message;
|
||
MainActor.Send(UerNetActor.ActorId,userNetSendMessage);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 断开连接
|
||
/// </summary>
|
||
public void DisConnected()
|
||
{
|
||
GetActor();
|
||
|
||
Debug.Info("UserSession 强制断开链接");
|
||
UserNetForceFinMessage userNetForceFinMessage = new UserNetForceFinMessage();
|
||
userNetForceFinMessage.Id = Id;
|
||
userNetForceFinMessage.InstanceId = InstanceId;
|
||
userNetForceFinMessage.FinCode = 0;
|
||
MainActor.Send(UerNetActor.ActorId,userNetForceFinMessage);
|
||
|
||
//提前处理用户断开
|
||
UserSessionManager.Instance.UserFin(this);
|
||
}
|
||
|
||
public void ClearUserData()
|
||
{
|
||
if (UserData != null)
|
||
{
|
||
Debug.Info($"注销绑定用户数据 Session:{Id} {UserData.Userid}");
|
||
GameNetDispatcher.Instance.Dispatch(GameNetMsgId.SessionUnBindUser, this);
|
||
SessionUUIDManager.Instance.RemoveLocalUUID(UserData.Uuid, UserData);
|
||
UserData = null;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 强制下线,强制下线也要等待1帧,因为线程不一样
|
||
/// </summary>
|
||
/// <param name="finCode"></param>
|
||
/// <param name="userId"></param>
|
||
public void ForceDiscConnect(int finCode,int userId)
|
||
{
|
||
GetActor();
|
||
|
||
UserNetForceFinMessage userNetForceFinMessage = new UserNetForceFinMessage();
|
||
userNetForceFinMessage.Id = Id;
|
||
userNetForceFinMessage.InstanceId = InstanceId;
|
||
userNetForceFinMessage.FinCode = finCode;
|
||
MainActor.Send(UerNetActor.ActorId,userNetForceFinMessage);
|
||
|
||
//提前处理用户断开
|
||
UserSessionManager.Instance.UserFin(this);
|
||
}
|
||
}
|
||
} |