예제 #1
0
        public void Remove(SocketService socketService)
        {
            if (socketService == null)
            {
                Logger.Error($"{nameof(socketService)}为 null!");
                return;
            }

            if (_concurrentDictionary.TryGetValue(socketService, out var result))
            {
                lock (_lockObject) {
                    _ackAction        -= result.AckAction;
                    _disconnectAction -= result.DisAction;
                }

                Logger.Debug("剩余AckDelegate:" + _ackAction.GetInvocationList().Length);
                Logger.Debug("剩余DisDelegate:" + _disconnectAction.GetInvocationList().Length);

                if (!_concurrentDictionary.TryRemove(socketService, out _))
                {
                    Logger.Warn($"删除{nameof(socketService)}失败!");
                }
            }
            else
            {
                Logger.Warn($"获取{nameof(socketService)}失败!");
            }
        }
예제 #2
0
        private bool Acknowledge(
            SocketService socketService,
            SendOption sendOption,
            PacketHead packetHead,
            IWriteStream writeStream = null)
        {
            if (socketService == null)
            {
                Logger.Error($"{nameof(socketService)} 为 null !");
                return(false);
            }
            var fragment = writeStream?.ToByteFragment();

            packetHead.Length     = fragment.HasValue ? (ushort)(PacketHead.GetSize() + fragment?.Count) : (ushort)PacketHead.GetSize();
            packetHead.SendOption = sendOption;

            var ws = PoolAllocator <IWriteStream> .GetObject();

            if (writeStream != null)
            {
                ws.ShiftRight(writeStream.ToByteFragment());
            }
            Packet.ToBytes(packetHead, ws);
            var byteSegment = ws.ToByteFragment();

            var result = StartWrite(socketService, byteSegment.Buffer, byteSegment.Offset, byteSegment.Count, ws, true);

            SocketStatistics.LogUnreliableSend();
            SocketStatistics.LogTotalBytesSent(packetHead.Length);
            return(true);
        }
예제 #3
0
        public override void Disconnect(SocketService socketService)
        {
            if (socketService == null)
            {
                throw new ArgumentNullException($"{nameof(socketService)} 为 null !");
            }

            WriteMessage(socketService, SendOption.Disconnect, socketService.SendCounter, null);
        }
예제 #4
0
        private void CreateAck(SocketService socketService)
        {
            if (socketService == null)
            {
                Logger.Error($"{nameof(socketService)} 为 null !");
                return;
            }

            _udpKeepAlive?.AddAck(socketService, () => {
                WriteMessage(socketService, SendOption.Ack, 0, null);
                SocketStatistics.LogAckSend();
                Logger.Debug($"发给{socketService.Connection.RemoteAddress}心跳包!");
            }, () => {
                OnDisconnect(socketService);
            });
        }
예제 #5
0
        public override bool Write(SocketService socketService, IWriteStream writeSteam)
        {
            if (socketService == null)
            {
                Logger.Error($"{nameof(socketService)} 为 null !");
                return(false);
            }

            if (writeSteam == null)
            {
                socketService.OnError($"{nameof(writeSteam)} 为 null !");
                return(false);
            }

            return(WriteMessage(socketService, SendOption.Fragment, writeSteam));
        }
예제 #6
0
        protected override void OnDisconnect(SocketService socketService)
        {
            if (_connections.TryRemove(socketService.Connection.RemoteAddress, out _))
            {
                Logger.Info($"断开{socketService.Connection.RemoteAddress}连接!");
                _udpKeepAlive?.Remove(socketService);

                foreach (var id in socketService.PacketIds)
                {
                    _fragmentTimer?.Remove(id);
                }
                socketService.OnDisconnect();
                socketService.Recycle();
            }
            else
            {
                Logger.Warn("是否已经断开?");
            }
        }
예제 #7
0
        protected override bool WriteMessage(
            SocketService socketService,
            SendOption sendOption,
            ulong messageId,
            IWriteStream writeStream)
        {
            if (socketService == null)
            {
                Logger.Error($"{nameof(socketService)} 为 null !");
                return(false);
            }

            var fragment   = writeStream?.ToByteFragment();
            var packetHead = new PacketHead {
                Length         = fragment.HasValue ? (ushort)(PacketHead.GetSize() + fragment?.Count) : (ushort)PacketHead.GetSize(),
                PacketId       = messageId,
                SendOption     = sendOption,
                TotalBytes     = fragment.HasValue ? (ushort)fragment?.Count : (ushort)0,
                FragmentId     = 0,
                TotalFragments = 1
            };

            var ws = PoolAllocator <IWriteStream> .GetObject();

            if (fragment.HasValue)
            {
                ws.ShiftRight((ByteFragment)fragment);
            }
            Packet.ToBytes(packetHead, ws);
            var byteSegment = ws.ToByteFragment();
            var result      = StartWrite(socketService, byteSegment.Buffer, byteSegment.Offset, byteSegment.Count, ws, true);

            SocketStatistics.LogUnreliableSend();
            SocketStatistics.LogTotalBytesSent(packetHead.Length);
            return(result);
        }
예제 #8
0
 protected abstract bool WriteMessage(SocketService socketService, SendOption sendOption, ulong messageId, IWriteStream writeSteam);
예제 #9
0
 public abstract bool Write(SocketService socketService, IWriteStream writeSteam);
예제 #10
0
 public abstract void Disconnect(SocketService socketService);
예제 #11
0
 protected abstract void OnDisconnect(SocketService socketService);
예제 #12
0
        public void AddAck(SocketService socketService, Action ackAction, Action disconnectAction)
        {
            if (socketService == null)
            {
                Logger.Error($"{nameof(socketService)}为 null!");
                return;
            }

            if (ackAction == null)
            {
                Logger.Error($"{nameof(ackAction)}为 null!");
                return;
            }

            if (disconnectAction == null)
            {
                Logger.Error($"{nameof(disconnectAction)}为 null!");
                return;
            }

            void DisAction()
            {
                if (_concurrentDictionary.TryGetValue(socketService, out var result))
                {
                    Logger.Info($"重置次数:{result.Count}");
                    if (result.Count >= _reconnectMaxCount)
                    {
                        disconnectAction?.Invoke();
                        return;
                    }

                    lock (_lockObject) {
                        ++result.Count;
                    }
                }
            }

            void Action()
            {
                if (_concurrentDictionary.TryGetValue(socketService, out var result))
                {
                    if (result.Count == 0)
                    {
                        lock (_lockObject) {
                            _disconnectAction += result.DisAction;
                        }
                    }
                    ackAction?.Invoke();
                }
            }

            lock (_lockObject) {
                _ackAction += Action;
            }

            var tuple = new Tuple {
                Count     = 0,
                AckAction = Action,
                DisAction = DisAction
            };

            if (!_concurrentDictionary.TryAdd(socketService, tuple))
            {
                Logger.Warn("添加ACK失败!");
            }
        }
예제 #13
0
        private void BeginRead(SocketService socketService)
        {
            if (socketService == null)
            {
                Logger.Error($"{nameof(socketService)} 为 null !");
                return;
            }

            var endPoint   = socketService.Connection.LocalAddress;
            var readStream = PoolAllocator <IReadStream> .GetObject();

            var byteFragment = readStream.GetReadBuffer();

            try {
                lock (_receiveLock) {
                    _readSocket.BeginReceiveFrom(byteFragment.Buffer, byteFragment.Offset, byteFragment.Count, SocketFlags.None,
                                                 ref endPoint, result => {
                        EndPoint remoteEndPoint = new IPEndPoint(
                            endPoint.AddressFamily == AddressFamily.InterNetwork
                                    ? IPAddress.Any
                                    : IPAddress.IPv6Any,
                            0);

                        var bytesReceived = 0;
                        try {
                            lock (_receiveLock) {
                                bytesReceived = _readSocket.EndReceiveFrom(result, ref remoteEndPoint);
                            }
                        } catch (SocketException e) {
                            socketService?.OnError(e.ToString());
                            readStream.Dispose();
                            BeginRead(socketService);
                            return;
                        } catch (ObjectDisposedException objectDisposedException) {
                            socketService?.OnError(objectDisposedException.ToString());
                            readStream.Dispose();
                            return;
                        } catch (InvalidOperationException invalidOperationException) {
                            socketService?.OnError(invalidOperationException.ToString());
                            readStream.Dispose();
                            return;
                        }
                        if (bytesReceived == 0)
                        {
                            return;
                        }

                        BeginRead(socketService);

                        var length = byteFragment.Buffer.ToValue <ushort>(byteFragment.Offset);
                        if (length == bytesReceived)
                        {
                            readStream.SetReadCount(length);
                            try {
                                OnRead(remoteEndPoint, readStream);
                            } catch (Exception e) {
                                Logger.Error(e);
                            }
                        }
                        else
                        {
                            Logger.Warn($"包数据未接收全,总长{length},接收长度{bytesReceived},自动丢弃!");
                        }

                        readStream.Dispose();
                    }, null);
                }
            } catch (SocketException e) {
                socketService?.OnError(e.ToString());
                BeginRead(socketService);
            } catch (ObjectDisposedException objectDisposedException) {
                socketService?.OnError(objectDisposedException.ToString());
            } catch (InvalidOperationException invalidOperationException) {
                socketService?.OnError(invalidOperationException.ToString());
            }
        }
예제 #14
0
        protected override bool WriteMessage(
            SocketService socketService,
            SendOption sendOption,
            IWriteStream writeStream)
        {
            if (socketService == null)
            {
                Logger.Error($"{nameof(socketService)} 为 null !");
                return(false);
            }

            if (writeStream == null)
            {
                Logger.Error($"{nameof(writeStream)} 为 null !");
                return(false);
            }

            var fragment    = writeStream.ToByteFragment();
            var dataLengnth = MTU - PacketHead.GetSize();
            var messageId   = socketService.SendCounter;
            // 分包
            var splits = Math.Ceiling(fragment.Count * 1.0d / dataLengnth);

            for (var i = 0; i < splits; i++)
            {
                var packetHead = new PacketHead {
                    Length         = (ushort)(Math.Min(fragment.Count - i * dataLengnth, dataLengnth) + PacketHead.GetSize()),
                    PacketId       = messageId,
                    SendOption     = sendOption,
                    TotalBytes     = (ushort)Math.Min(fragment.Count - i * dataLengnth, dataLengnth),
                    FragmentId     = (ushort)i,
                    TotalFragments = (ushort)splits
                };

                var ws = PoolAllocator <IWriteStream> .GetObject();

                ws.ShiftRight(fragment.Buffer, fragment.Offset + i * dataLengnth, packetHead.TotalBytes);
                Packet.ToBytes(packetHead, ws);

                var byteSegment = ws.ToByteFragment();

                void Action()
                {
                    StartWrite(socketService, byteSegment.Buffer, byteSegment.Offset, byteSegment.Count, ws);
                    SocketStatistics.LogFragmentedSend();
                    SocketStatistics.LogDataBytesSent(packetHead.TotalBytes);
                    SocketStatistics.LogTotalBytesSent(packetHead.Length);
                    Logger.Info("重发数据包!");
                }

                void RecycleAction()
                {
                    ws.Dispose();
                }

                var id = BuildID(packetHead);
                _fragmentTimer?.Add(id, Action, RecycleAction);

                StartWrite(socketService, byteSegment.Buffer, byteSegment.Offset, byteSegment.Count, writeStream);

                socketService.PacketIds.Add(id);
                SocketStatistics.LogFragmentedSend();
                SocketStatistics.LogReliableSend();
                SocketStatistics.LogDataBytesSent(packetHead.TotalBytes);
                SocketStatistics.LogTotalBytesSent(packetHead.Length);
            }

            return(true);
        }
예제 #15
0
        private bool StartWrite(SocketService socketService, byte[] buffer, int offset, int count, IWriteStream writeStream,
                                bool isRecycle = false)
        {
            if (socketService == null)
            {
                Logger.Error($"{nameof(socketService)} 为 null !");
                return(false);
            }

            if (socketService.Connection.RemoteAddress == null)
            {
                Logger.Error($"远程地址不能为null!");
                return(false);
            }

            lock (_senderLock) {
                try {
                    _readSocket.BeginSendTo(buffer, offset, count, SocketFlags.None,
                                            socketService.Connection.RemoteAddress, result => {
                        var bytesSended = 0;
                        try {
                            lock (_senderLock) {
                                bytesSended = _readSocket.EndSendTo(result);
                            }
                        } catch (SocketException socketException) {
                            socketService.OnError(socketException.ToString());
                            OnDisconnect(socketService);
                        } catch (ObjectDisposedException objectDisposedException) {
                            socketService.OnError(objectDisposedException.ToString());
                            OnDisconnect(socketService);
                        } catch (InvalidOperationException invalidOperationException) {
                            socketService.OnError(invalidOperationException.ToString());
                            OnDisconnect(socketService);
                        }

                        if (bytesSended != count)
                        {
                            Logger.Warn("未完全发送完,自动丢弃!");
                        }
                        else
                        {
                            Logger.Debug($"发送{socketService.Connection.RemoteAddress}:{count}字节数据!");
                            socketService.OnWrite(true);
                        }

                        if (isRecycle)
                        {
                            writeStream.Dispose();
                        }
                    }, null);
                } catch (SocketException socketException) {
                    Logger.Error(socketException.ToString());
                    socketService.OnError(socketException.ToString());
                    OnDisconnect(socketService);
                } catch (ObjectDisposedException objectDisposedException) {
                    socketService.OnError(objectDisposedException.ToString());
                    OnDisconnect(socketService);
                } catch (InvalidOperationException invalidOperationException) {
                    socketService.OnError(invalidOperationException.ToString());
                    OnDisconnect(socketService);
                }
            }
            return(true);
        }