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
151 lines
5.2 KiB
C#
151 lines
5.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.Specialized;
|
|
using System.IO;
|
|
using System.Net;
|
|
using System.Net.Sockets;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using MrWu.Debug;
|
|
using WebSocketSharp;
|
|
using WebSocketSharp.Server;
|
|
using ErrorEventArgs = WebSocketSharp.ErrorEventArgs;
|
|
|
|
namespace Server.Net
|
|
{
|
|
/// <summary>
|
|
/// WebSocket 单个链接的通道
|
|
/// </summary>
|
|
public class WChannel: BaseWChannel
|
|
{
|
|
public long SessionId { get; set; }
|
|
|
|
/// <summary>
|
|
/// 链接成功事件
|
|
/// </summary>
|
|
public static event Action<WChannel> OnConnectedEvt;
|
|
|
|
/// <summary>
|
|
/// 收到包事件
|
|
/// </summary>
|
|
public static event Action<WChannel, byte[]> OnReceivedEvt;
|
|
|
|
/// <summary>
|
|
/// 断开连接事件
|
|
/// </summary>
|
|
public static event Action<WChannel> OnDisconnectedEvt;
|
|
|
|
/// <summary>
|
|
/// 发送错误事件
|
|
/// </summary>
|
|
public static event Action<WChannel, Exception> OnErrorEvt;
|
|
|
|
//未收齐的字节,写入内存字节
|
|
private MemoryStream _memoryStream = new MemoryStream();
|
|
|
|
private byte[] lengthBytes = new byte[4];
|
|
private bool waitReceiveHead = true;
|
|
private int waitReceiveLength;
|
|
|
|
public NameValueCollection WHeaders {
|
|
get
|
|
{
|
|
return this.Headers;
|
|
}
|
|
}
|
|
|
|
protected override void OnMessage(MessageEventArgs e)
|
|
{
|
|
base.OnMessage(e);
|
|
|
|
lock (_memoryStream)
|
|
{
|
|
_memoryStream.Write(e.RawData,0,e.RawData.Length);
|
|
_memoryStream.Seek(0, SeekOrigin.Begin);
|
|
//Debug.Info($"OnMessage,{e.RawData.Length},{_memoryStream.Position},{_memoryStream.Length}");
|
|
while (true)
|
|
{
|
|
long byteLength = _memoryStream.Length - _memoryStream.Position;
|
|
|
|
//Debug.Log("缓存区长度:" + _memoryStream.Length);
|
|
if (waitReceiveHead)
|
|
{
|
|
// 没收到 包头
|
|
if (byteLength < 4)
|
|
{
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
//收到了包头
|
|
_memoryStream.Read(lengthBytes, 0, 4);
|
|
waitReceiveLength = BitConverter.ToInt32(lengthBytes, 0);
|
|
waitReceiveHead = false;
|
|
|
|
if (waitReceiveLength > GameNetManager.MaxMessageSize)
|
|
{
|
|
Debug.Error("包体过大:" + waitReceiveLength);
|
|
throw new Exception("Message Size :" + waitReceiveLength);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//还没有收齐,不处理
|
|
if (byteLength < waitReceiveLength)
|
|
{
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
byte[] bodyData = new byte[waitReceiveLength];
|
|
_memoryStream.Read(bodyData, 0, waitReceiveLength);
|
|
//Debug.Info($"收到包体:{_memoryStream.Position},{_memoryStream.Length},bodyLength:{waitReceiveLength}");
|
|
waitReceiveHead = true;
|
|
OnReceivedEvt?.Invoke(this, bodyData);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
//未读取的长度
|
|
int noReadLength = (int)(_memoryStream.Length - _memoryStream.Position);
|
|
//Debug.Info($"剩余长度:{noReadLength}");
|
|
if (noReadLength > 0)
|
|
{
|
|
byte[] noReadBytes = new byte[noReadLength];
|
|
_memoryStream.Read(noReadBytes, 0, noReadLength);
|
|
_memoryStream.Seek(0, SeekOrigin.Begin);
|
|
_memoryStream.SetLength(0);
|
|
_memoryStream.Write(noReadBytes, 0, noReadLength);
|
|
}
|
|
else
|
|
{
|
|
_memoryStream.Seek(0, SeekOrigin.Begin);
|
|
_memoryStream.SetLength(0);
|
|
}
|
|
//Debug.Info($"重置收包:{_memoryStream.Position},{_memoryStream.Length}");
|
|
}
|
|
}
|
|
|
|
protected override void OnClose(CloseEventArgs e)
|
|
{
|
|
base.OnClose(e);
|
|
OnDisconnectedEvt?.Invoke(this);
|
|
}
|
|
|
|
protected override void OnError(ErrorEventArgs e)
|
|
{
|
|
base.OnError(e);
|
|
OnErrorEvt?.Invoke(this, e.Exception);
|
|
}
|
|
|
|
protected override void OnOpen()
|
|
{
|
|
base.OnOpen();
|
|
OnConnectedEvt?.Invoke(this);
|
|
}
|
|
|
|
|
|
}
|
|
} |