DofKcpDemo/Assets/Scripts/KcpDofClient.cs

152 lines
4.2 KiB
C#

using System;
using System.IO;
using System.Net;
using DotNetty.Buffers;
using dotNetty_kcp;
using UnityEngine;
using Guru;
using Dof;
public class KcpDofClient : KcpListener
{
public Action OnConnected;
public Action<ServerMessage> OnServerMessage;
private Ukcp _ukcp;
private KcpClient _kcpClient;
private MemoryStream _localRecvMs = new MemoryStream(1024 * 1024 * 1);
private MemoryStream _localSendMs = new MemoryStream(1024 * 1024 * 1);
public long Cid { get; private set; }
public KcpDofClient()
{
// 指定DotNetty日志的显示级别
DotNetty.Unity.UnityLoggerFactory.Default.Level = DotNetty.Unity.Level.ERROR;
}
public async void Connect(string ip_str, int port)
{
var channelConfig = new ChannelConfig();
channelConfig.initNodelay(true, 40, 2, true);
channelConfig.Sndwnd = 512;
channelConfig.Rcvwnd = 512;
channelConfig.Mtu = 512;
channelConfig.FecDataShardCount = 10;
channelConfig.FecParityShardCount = 3;
channelConfig.AckNoDelay = true;
channelConfig.Crc32Check = false;
channelConfig.UseConvChannel = true;
//channelConfig.Conv = UnityEngine.Random.Range(1, int.MaxValue);
channelConfig.TimeoutMillis = 10000;
_kcpClient = new KcpClient();
_kcpClient.init(channelConfig);
var remoteAddress = new IPEndPoint(IPAddress.Parse(ip_str), port);
var task = _kcpClient.BindLocal();
await task;
var channel = task.Result;
_ukcp = _kcpClient.connect(channel, remoteAddress, channelConfig, this);
}
public void Send(ClientMessage msg)
{
_localSendMs.SetLength(0);
_localSendMs.Position = 0;
ProtobufHelper.ToStream(msg, _localSendMs);
var dataBuf = Unpooled.DirectBuffer(1024 * 1024 * 1);
dataBuf.WriteBytes(_localSendMs.GetBuffer(), 0, (int)_localSendMs.Length);
_ukcp.write(dataBuf);
dataBuf.Release();
}
public void onConnected(Ukcp ukcp)
{
Debug.Log($"[KcpDofClient]onConnected");
if (OnConnected != null)
{
Loom.QueueOnMainThread(() =>
{
OnConnected.Invoke();
});
}
}
/// <summary>
/// kcp 接收到消息的回调函数
/// </summary>
/// <param name="byteBuf">接收到的消息buffer</param>
/// <param name="ukcp">kcp连接</param>
public void handleReceive(IByteBuffer byteBuf, Ukcp ukcp)
{
Debug.Log("[KcpDofClient]handleReceive");
_localRecvMs.SetLength(0);
_localRecvMs.Position = 0;
var data_len = byteBuf.ReadableBytes;
byteBuf.ReadBytes(_localRecvMs, data_len);
var msg = ProtobufHelper.FromBytes(typeof(ServerMessage), _localRecvMs.GetBuffer(), 0, data_len);
var server_msg = msg as ServerMessage;
if (server_msg != null)
{
ServerMessageHandler(server_msg);
}
else
{
Debug.LogError("[KcpDofClient]handleReceive: Fail to Deserialize ServerMessage");
}
}
public void handleException(Exception ex, Ukcp ukcp)
{
Debug.LogError($"[KcpDofClient]{ex}");
}
public void handleClose(Ukcp ukcp)
{
}
void ServerMessageHandler(ServerMessage msg)
{
if (msg.PlayerEntered != null)
{
Cid = msg.PlayerEntered.Cid;
Debug.Log($"Player Enter cid: {Cid}");
}
else if (msg.GameStart != null)
{
Debug.Log($"Game Start");
}
else if (msg.LevelStart != null)
{
Debug.Log($"Level Start");
}
else if (msg.PointFound != null)
{
Debug.Log($"Point Found");
}
else if (msg.GameFinish != null)
{
Debug.Log($"Game Finish");
}
else
{
Debug.LogError($"Unhandled ServerMessage");
}
if (OnServerMessage != null)
{
Loom.QueueOnMainThread(() =>
{
OnServerMessage.Invoke(msg);
});
}
}
}