private void ReceiveNext() { if (_closeFlag == 1) { return; } _receiveAsyncEventArgs.SetBuffer(_receiveBuffer.Buffer, _receiveBuffer.Tail, _receiveBuffer.WritableSize); _receiveAsyncEventArgs.UserToken = _receiveBuffer; if (!UnderlineSocket.ReceiveAsync(_receiveAsyncEventArgs)) { ProcessReceive(); } }
/// <summary> /// 关闭会话 /// </summary> /// <param name="reason"></param> public void Close(SessionCloseReason reason) { if (Interlocked.CompareExchange(ref _closeFlag, 1, 0) == 1) { return; } if (UnderlineSocket.Connected) { UnderlineSocket.Shutdown(SocketShutdown.Both); } UnderlineSocket.Close(); UnderlineSocket = null; //_receiveAsyncEventArgs.Dispose(); //_receiveAsyncEventArgs = null; _receiveBuffer = null; _extractor = null; Loop.Ins.Perform(() => { _dispatcher.OnClose(this, reason); }); }
private void Send(byte[] data, Action <bool> cb) { if (_closeFlag == 1 || data.IsNullOrEmpty()) { cb?.Invoke(false); return; } var buffers = new List <ArraySegment <byte> >(); const int limit = PackageMaxSize - sizeof(byte); var cnt = data.Length / limit; var lastLen = data.Length % limit; if (lastLen != 0) { ++cnt; } for (var i = 0; i < cnt; ++i) { var packLen = limit; if (i == cnt - 1 && lastLen != 0) { packLen = lastLen; } var slice = new byte[packLen + sizeof(byte) + HeaderSize]; using (var ms = new MemoryStream(slice)) using (var bw = new BinaryWriter(ms)) { bw.Write((ushort)(packLen + sizeof(byte))); bw.Write((byte)(cnt - i)); bw.Write(data, i * limit, packLen); } buffers.Add(new ArraySegment <byte>(slice)); } try { var e = SocketAsyncEventArgsPool.Ins.Pop(); e.Completed += OnSendCompleted; e.BufferList = buffers; e.UserToken = cb; #if MESSAGE_TRACK_ENABLED var sb = new StringBuilder(); for (var i = 0; i < buffers.Count; ++i) { var buf = buffers[i]; sb.Append("Write [ "); foreach (var b in buf) { sb.Append($"{b.ToString("X2")} "); } sb.Append("]"); if (i != buffers.Count - 1) { sb.AppendLine(); } } Logger.Ins.Debug(sb.ToString()); #endif if (UnderlineSocket.SendAsync(e)) { return; } if (e.SocketError != SocketError.Success) { cb?.Invoke(false); Close(SessionCloseReason.WriteError); } e.Completed -= OnSendCompleted; SocketAsyncEventArgsPool.Ins.Push(e); } catch (ObjectDisposedException e) { Logger.Ins.Warn("Socket already closed! detail : {0}", e.StackTrace); } catch (Exception e) { Logger.Ins.Exception("Send", e); Close(SessionCloseReason.WriteError); } }