Files
hjha-server/GameNetModule/GameNet/Base/UserSession.cs
xiaoou e9616125ce feat: initial commit - HJHA game server full source
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
2026-07-07 12:02:15 +08:00

226 lines
7.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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);
}
}
}