public void HandleConnnect() { // 如果连接上了就不用处理了 if (this.IsConnected) { return; } this.kcp = Kcp.KcpCreate(this.RemoteConn, new IntPtr(this.LocalConn)); this.InitKcp(); ulong localRmoteConn = ((ulong)this.RemoteConn << 32) | this.LocalConn; idLocalRemoteConn.TryAdd(this.Id, localRmoteConn); Log.Info($"channel connected: {this.Id} {this.LocalConn} {this.RemoteConn} {this.RemoteAddress}"); this.IsConnected = true; this.lastRecvTime = this.Service.TimeNow; while (true) { if (this.sendBuffer.Count <= 0) { break; } KcpWaitPacket buffer = this.sendBuffer.Dequeue(); this.KcpSend(buffer); } }
private void KcpSend(KcpWaitPacket kcpWaitPacket) { if (this.IsDisposed) { return; } MemoryStream memoryStream = kcpWaitPacket.MemoryStream; switch (this.Service.ServiceType) { case ServiceType.Inner: { memoryStream.GetBuffer().WriteTo(0, kcpWaitPacket.ActorId); break; } case ServiceType.Outer: { // 外网不需要发送actorId,跳过 memoryStream.Seek(Packet.ActorIdLength, SeekOrigin.Begin); break; } } int count = (int)(memoryStream.Length - memoryStream.Position); // 超出maxPacketSize需要分片 if (count <= maxPacketSize) { Kcp.KcpSend(this.kcp, memoryStream.GetBuffer(), (int)memoryStream.Position, count); } else { // 先发分片信息 this.sendCache.WriteTo(0, 0); this.sendCache.WriteTo(4, count); Kcp.KcpSend(this.kcp, this.sendCache, 0, 8); // 分片发送 int alreadySendCount = 0; while (alreadySendCount < count) { int leftCount = count - alreadySendCount; int sendCount = leftCount < maxPacketSize ? leftCount : maxPacketSize; Kcp.KcpSend(this.kcp, memoryStream.GetBuffer(), (int)memoryStream.Position + alreadySendCount, sendCount); alreadySendCount += sendCount; } } this.Service.AddToUpdateNextTime(0, this.Id); }
private void KcpSend(KcpWaitPacket kcpWaitPacket) { if (this.IsDisposed) { return; } MemoryStream memoryStream = kcpWaitPacket.MemoryStream; if (this.Service.ServiceType == ServiceType.Inner) { memoryStream.GetBuffer().WriteTo(0, kcpWaitPacket.ActorId); } int count = (int)(memoryStream.Length - memoryStream.Position); Kcp.KcpSend(this.kcp, memoryStream.GetBuffer(), (int)memoryStream.Position, count); this.Service.AddToUpdateNextTime(0, this.Id); }
public void Send(long actorId, MemoryStream stream) { if (this.kcp != IntPtr.Zero) { // 检查等待发送的消息,如果超出最大等待大小,应该断开连接 int n = Kcp.KcpWaitsnd(this.kcp); int maxWaitSize = 0; switch (this.Service.ServiceType) { case ServiceType.Inner: maxWaitSize = Kcp.InnerMaxWaitSize; break; case ServiceType.Outer: maxWaitSize = Kcp.OuterMaxWaitSize; break; default: throw new ArgumentOutOfRangeException(); } if (n > maxWaitSize) { Log.Error($"kcp wait snd too large: {n}: {this.Id} {this.RemoteConn}"); this.OnError(ErrorCode.ERR_KcpWaitSendSizeTooLarge); return; } } KcpWaitPacket kcpWaitPacket = new KcpWaitPacket() { ActorId = actorId, MemoryStream = stream }; if (!this.IsConnected) { this.sendBuffer.Enqueue(kcpWaitPacket); return; } this.KcpSend(kcpWaitPacket); }