using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Net.Sockets; using System.Text; using UMC.Net; namespace UMC.ITME { abstract class WebSocket : UMC.Net.MimeRequest, IDisposable { public override bool IsWebSocket => true; public abstract void Dispose(); } class HttpWebSocket : WebSocket { byte[] buffer = System.Buffers.ArrayPool.Shared.Rent(0x600); Socket socket; public HttpWebSocket(HttpMime mime, Socket stream) { this.mime = mime; this.socket = stream; SocketAsyncEventArgs eventArgs = new SocketAsyncEventArgs(); eventArgs.SetBuffer(buffer); eventArgs.Completed += Http; if (!this.socket.ReceiveAsync(eventArgs)) { ProcessReceive(eventArgs); } } HttpMime mime; private void Http(object sender, SocketAsyncEventArgs e) { switch (e.LastOperation) { case SocketAsyncOperation.Receive: ProcessReceive(e); break; } } private void ProcessReceive(SocketAsyncEventArgs e) { if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success) { try { this.mime.Write(buffer, e.Offset, e.BytesTransferred); while (!socket.ReceiveAsync(e)) { if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success) { this.mime.Write(buffer, e.Offset, e.BytesTransferred); } else { this.Dispose(); break; } } } catch { this.Dispose(); } } else { this.Dispose(); } } public override void Receive(byte[] buffer, int offset, int size) { socket.Send(buffer, offset, size, SocketFlags.None); } protected override void Header(byte[] data, int offset, int size) { } public override void Dispose() { this.mime.Dispose(); try { socket.Shutdown(SocketShutdown.Both); } catch { } socket.Close(); if (buffer != null) System.Buffers.ArrayPool.Shared.Return(buffer); buffer = null; } } }