/// <summary> /// /// </summary> /// <param name="callback"></param> /// <returns></returns> public SocketResult Error <TResult>(Fleck2Extensions.Action <TResult> callback) { if (_result is Exception) { callback((TResult)_result); } return(this); }
/// <summary> /// /// </summary> /// <param name="callback"></param> /// <returns></returns> public SocketResult Success(Fleck2Extensions.Action callback) { if (!(_result is Exception)) { callback(); } return(this); }
public void Setup() { _request = new WebSocketHttpRequest(); _onClose = delegate { }; _onMessage = delegate { }; _onBinary = delegate { }; _handler = Hybi13Handler.Create(_request, s => _onMessage(s), () => _onClose(), b => _onBinary(b)); }
/// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="beginMethod"></param> /// <param name="endMethod"></param> /// <param name="resultCallback"> </param> /// <returns></returns> public void HandleAsyncVoid <T>(Fleck2Extensions.Func <AsyncCallback, object, T> beginMethod, Fleck2Extensions.Action <T> endMethod, Action <SocketResult> resultCallback) { DoAsyncTask(() => beginMethod(result => DoAsyncTask(() => { endMethod((T)result); resultCallback(new SocketResult(true)); }, resultCallback), null), resultCallback); }
public void Receive(byte[] buffer, Fleck2Extensions.Action <int> callback, Fleck2Extensions.Action <Exception> error, int offset = 0) { Fleck2Extensions.Func <AsyncCallback, object, IAsyncResult> begin = (cb, data) => _stream.BeginRead(buffer, offset, buffer.Length, cb, data); _socketFactory.HandleAsync(begin, _stream.EndRead, result => { result.Success(callback); result.Error(error); }); }
public void Send(byte[] buffer, Fleck2Extensions.Action callback, Fleck2Extensions.Action <Exception> error) { Fleck2Extensions.Func <AsyncCallback, object, IAsyncResult> begin = (cb, s) => _stream.BeginWrite(buffer, 0, buffer.Length, cb, s); _socketFactory.HandleAsyncVoid(begin, _stream.EndWrite, result => { result.Success(callback); result.Error(error); }); }
public void Accept(Fleck2Extensions.Action <ISocket> callback, Fleck2Extensions.Action <Exception> error) { Fleck2Extensions.Func <IAsyncResult, ICancellationToken, ISocket> end = (result, token) => { token.ThrowIfCancellationRequested(); return(new SocketWrapper(_socket.EndAccept(result))); }; _socketFactory.HandleAsync(_socket.BeginAccept, end, result => { result.Success(callback); result.Error(error); }); }
public void Authenticate(X509Certificate2 certificate, Fleck2Extensions.Action callback, Fleck2Extensions.Action <Exception> error) { var ssl = new SslStream(_stream, false); _stream = ssl; Fleck2Extensions.Func <AsyncCallback, object, IAsyncResult> begin = (cb, s) => ssl.BeginAuthenticateAsServer(certificate, false, SslProtocols.Tls, false, cb, s); _socketFactory.HandleAsyncVoid(begin, ssl.EndAuthenticateAsServer, result => { result.Success(callback); result.Error(error); }); }
/// <summary> /// /// </summary> /// <param name="unitOfWork"></param> /// <param name="resultCallback"> </param> private static void DoAsyncTask(Fleck2Extensions.Action unitOfWork, Action <SocketResult> resultCallback) { ThreadPool.QueueUserWorkItem(delegate { try { unitOfWork(); } catch (SocketCancellationTokenException) { } catch (Exception ex) { resultCallback(new SocketResult(ex)); } }); }
public void ShouldCloseOnCloseFromValidStatusCode() { var frame = new Hybi14DataFrame { FrameType = FrameType.Close, IsFinal = true, IsMasked = true, MaskKey = 5232, Payload = 1000.ToBigEndianBytes < ushort > () }; var hit = false; _onClose = () => hit = true; _handler.Receive(frame.ToBytes()); Assert.IsTrue(hit); }
public void ShouldCloseOnCloseFromText() { var payload = Fleck2Extensions.ToArray(1000.ToBigEndianBytes < ushort > ().Concat(Encoding.UTF8.GetBytes("Reason"))); var frame = new Hybi14DataFrame { FrameType = FrameType.Close, IsFinal = true, IsMasked = true, MaskKey = 5232, Payload = payload }; var hit = false; _onClose = () => hit = true; _handler.Receive(frame.ToBytes()); Assert.IsTrue(hit); }
private void SendBytes(byte[] bytes, Fleck2Extensions.Action callback = null) { Socket.Send(bytes, () => { FleckLog.Debug("Sent " + bytes.Length + " bytes"); if (callback != null) { callback(); } }, e => { if (e is IOException) { FleckLog.Debug("Failed to send. Disconnecting.", e); } else { FleckLog.Info("Failed to send. Disconnecting.", e); } CloseSocket(); }); }
public static void ReceiveData(List <byte> data, ReadState readState, Fleck2Extensions.Action <FrameType, byte[]> processFrame) { while (data.Count >= 2) { var isFinal = (data[0] & 128) != 0; var reservedBits = (data[0] & 112); var frameType = (FrameType)(data[0] & 15); var isMasked = (data[1] & 128) != 0; var length = (data[1] & 127); if (!isMasked || !Enum.IsDefined(typeof(FrameType), frameType) || reservedBits != 0 || //Must be zero per spec 5.2 (frameType == FrameType.Continuation && !readState.FrameType.HasValue)) { throw new WebSocketException(WebSocketStatusCodes.ProtocolError); } var index = 2; int payloadLength; switch (length) { case 127: if (data.Count < index + 8) { return; //Not complete } payloadLength = data.Skip(index).Take(8).ToArray().ToLittleEndianInt(); index += 8; break; case 126: if (data.Count < index + 2) { return; //Not complete } payloadLength = data.Skip(index).Take(2).ToArray().ToLittleEndianInt(); index += 2; break; default: payloadLength = length; break; } if (data.Count < index + 4) { return; //Not complete } var maskBytes = data.Skip(index).Take(4).ToList(); index += 4; if (data.Count < index + payloadLength) { return; //Not complete } var i = 0; var payload = data.Skip(index) .Take(payloadLength) .Select(value => (byte)(value ^ maskBytes[i++ % 4])); readState.Data.AddRange(payload); data.RemoveRange(0, index + payloadLength); if (frameType != FrameType.Continuation) { readState.FrameType = frameType; } if (!isFinal || !readState.FrameType.HasValue) { continue; } var stateData = readState.Data.ToArray(); var stateFrameType = readState.FrameType; readState.Clear(); processFrame(stateFrameType.Value, stateData); } }
public static void ProcessFrame(FrameType frameType, byte[] data, Action <string> onMessage, Fleck2Extensions.Action onClose, Action <byte[]> onBinary) { switch (frameType) { case FrameType.Close: if (data.Length == 1 || data.Length > 125) { throw new WebSocketException(WebSocketStatusCodes.ProtocolError); } if (data.Length >= 2) { var closeCode = (ushort)(data.Take(2).ToArray().ToLittleEndianInt()); if (!WebSocketStatusCodes.Contains(closeCode) && (closeCode < 3000 || closeCode > 4999)) { throw new WebSocketException(WebSocketStatusCodes.ProtocolError); } } if (data.Length > 2) { ReadUtf8PayloadData(data.Skip(2)); } onClose(); break; case FrameType.Binary: onBinary(data); break; case FrameType.Text: onMessage(ReadUtf8PayloadData(data)); break; default: FleckLog.Debug("Received unhandled " + frameType); break; } }
public static IHandler Create(WebSocketHttpRequest request, Action <string> onMessage, Fleck2Extensions.Action onClose, Action <byte[]> onBinary) { var readState = new ReadState(); return(new ComposableHandler { Handshake = () => BuildHandshake(request), TextFrame = data => FrameData(Encoding.UTF8.GetBytes(data), FrameType.Text), BinaryFrame = data => FrameData(data, FrameType.Binary), CloseFrame = i => FrameData(i.ToBigEndianBytes <ushort>(), FrameType.Close), ReceiveData = bytes => ReceiveData(bytes, readState, (op, data) => ProcessFrame(op, data, onMessage, onClose, onBinary)) }); }
public static IHandler BuildHandler(WebSocketHttpRequest request, Action <string> onMessage, Fleck2Extensions.Action onClose, Action <byte[]> onBinary) { var version = GetVersion(request); switch (version) { case "76": return(Draft76Handler.Create(request, onMessage)); case "7": case "8": case "13": return(Hybi13Handler.Create(request, onMessage, onClose, onBinary)); } throw new WebSocketException(WebSocketStatusCodes.UnsupportedDataType); }
public void ShouldCloseOnCloseFromValidStatusCode() { var frame = new Hybi14DataFrame { FrameType = FrameType.Close, IsFinal = true, IsMasked = true, MaskKey = 5232, Payload = 1000.ToBigEndianBytes<ushort>() }; var hit = false; _onClose = () => hit = true; _handler.Receive(frame.ToBytes()); Assert.IsTrue(hit); }
public void ShouldCloseOnCloseFromText() { var payload = Fleck2Extensions.ToArray(1000.ToBigEndianBytes<ushort>().Concat(Encoding.UTF8.GetBytes("Reason"))); var frame = new Hybi14DataFrame { FrameType = FrameType.Close, IsFinal = true, IsMasked = true, MaskKey = 5232, Payload = payload }; var hit = false; _onClose = () => hit = true; _handler.Receive(frame.ToBytes()); Assert.IsTrue(hit); }