private void tmrConnectionChecker_Tick(object sender, EventArgs e) { if (firstTime) { firstTime = false; try { Main.connection.connect(txtIP.Text, Int32.Parse(txtPort.Text)); } catch (Exception) { } } WebSocketState st = Main.connection.state; if (st != lastState) { if (st == WebSocketState.Closed) { btnCnnct.Enabled = true; btnCnnct.Text = "Connect"; } else { btnCnnct.Enabled = btnOK.Enabled = false; btnCnnct.Text = Enum.GetName(typeof(WebSocketState), st); } btnOK.Enabled = (st == WebSocketState.Open); lastState = st; } }
public OwinWebSocketAdapter(IDictionary<string, object> websocketContext, string subProtocol) { _websocketContext = websocketContext; _sendAsync = (WebSocketSendAsync)websocketContext[OwinConstants.WebSocket.SendAsync]; _receiveAsync = (WebSocketReceiveAsync)websocketContext[OwinConstants.WebSocket.ReceiveAsync]; _closeAsync = (WebSocketCloseAsync)websocketContext[OwinConstants.WebSocket.CloseAsync]; _state = WebSocketState.Open; _subProtocol = subProtocol; }
public override void Dispose() { if (_state >= WebSocketState.Closed) // or Aborted { return; } _state = WebSocketState.Closed; _session.WebSocketDispose(); }
public async Task CloseNoopsIfInTerminalState(WebSocketState state) { var webSocket = new Mock<WebSocket>(); var webSocketHandler = new Mock<WebSocketHandler>(64 * 1024, new Mock<ILogger>().Object) {CallBase = true}; webSocket.Setup(m => m.State).Returns(state); webSocketHandler.Object.WebSocket = webSocket.Object; await webSocketHandler.Object.CloseAsync(); webSocket.Verify(m => m.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None), Times.Never()); }
/// <summary> /// Polite close (use the close handshake) /// </summary> public override async Task CloseAsync(WebSocketCloseStatus closeStatus, string statusDescription, CancellationToken cancellationToken) { if (_state == WebSocketState.Open) { using (MemoryStream stream = _recycledStreamFactory()) { ArraySegment <byte> buffer = BuildClosePayload(closeStatus, statusDescription); WebSocketFrameWriter.Write(WebSocketOpCode.ConnectionClose, buffer, stream, true, _isClient); await WriteStreamToNetwork(stream, cancellationToken); _state = WebSocketState.CloseSent; } } }
public StreamWebSocket (Stream rstream, Stream wstream, Socket socket, string subProtocol, bool maskSend, ArraySegment<byte> preloaded) { this.rstream = rstream; this.wstream = wstream; // Necessary when both of rstream and wstream doesn't close socket. this.socket = socket; this.subProtocol = subProtocol; this.maskSend = maskSend; if (maskSend) { random = new Random (); } this.preloaded = preloaded; state = WebSocketState.Open; headerBuffer = new byte[HeaderMaxLength]; }
private void DisposeCompressionWebSocket() { if (!_disposed) { _disposed = true; _keepAliveTimer?.Dispose(); _stream?.Dispose(); if (_state < WebSocketState.Aborted) { _state = WebSocketState.Closed; } } }
public override async Task CloseOutputAsync(WebSocketCloseStatus closeStatus, string statusDescription, CancellationToken cancellationToken) { await SendMessageAsync( new WebSocketMessage { CloseStatus = closeStatus, CloseStatusDescription = statusDescription, MessageType = WebSocketMessageType.Close, }, cancellationToken).ConfigureAwait(false); _state = WebSocketState.CloseSent; _output.TryComplete(); }
public CommonWebSocket(Stream stream, string subProtocol, TimeSpan keepAliveInterval, int receiveBufferSize, bool maskOutput, bool useZeroMask, bool unmaskInput) { _stream = stream; _subProtocl = subProtocol; _state = WebSocketState.Open; _receiveBuffer = new byte[receiveBufferSize]; _maskOutput = maskOutput; _useZeroMask = useZeroMask; _unmaskInput = unmaskInput; _writeLock = new SemaphoreSlim(1); if (keepAliveInterval != Timeout.InfiniteTimeSpan) { _keepAliveTimer = new Timer(SendKeepAlive, this, keepAliveInterval, keepAliveInterval); } }
private void _connection_ConnectionStateChanged(object sender, WebSocketState state) { switch (state) { case WebSocketState.Closed: MarkChannelsAsUnsubscribed(); break; case WebSocketState.Open: SubscribeExistingChannels(); break; } ConnectionStateChanged?.Invoke(sender, state); }
protected CommonWebSocket(string subProtocol, TimeSpan keepAliveInterval, int receiveBufferSize, bool maskOutput, bool useZeroMask, bool unmaskInput) { _connection = new TcpClient { NoDelay = true }; _state = WebSocketState.None; _subProtocol = subProtocol; _keepAliveInterval = keepAliveInterval; _receiveBuffer = new byte[receiveBufferSize]; _maskOutput = maskOutput; _useZeroMask = useZeroMask; _unmaskInput = unmaskInput; _writeLock = new SemaphoreSlim(1); }
public override Task <WebSocketReceiveResult> ReceiveAsync(ArraySegment <byte> buffer, CancellationToken cancellationToken) { var e = IncomingJson.Count > 0 ? IncomingJson.Dequeue() : null; if (e != null) { var data = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(e)); data.CopyTo(buffer.Array, 0); if (!IncomingJson.Any() && CloseWhenNoMoreMessages) { _state = WebSocketState.Closed; } return(Task.FromResult(new WebSocketReceiveResult(data.Length, WebSocketMessageType.Text, true))); } return(Task.FromResult(new WebSocketReceiveResult(0, WebSocketMessageType.Text, true))); }
public override async Task StartReceiving() { var buffer = new byte[1024 * 4]; try { Console.WriteLine("ClientView connection started"); WebSocketReceiveResult result = await socket.ReceiveAsync(new ArraySegment <byte>(buffer), CancellationToken.None); while (!result.CloseStatus.HasValue) { //string yeetmessage = Encoding.UTF8.GetString(buffer); //System.Diagnostics.Debug.WriteLine("Received the following information from client: " + yeetmessage ); WebSocketState state = socket.State; result = await socket.ReceiveAsync(new ArraySegment <byte>(buffer), CancellationToken.None); List <Command> templist = receiveManager.ReceiveString(Encoding.UTF8.GetString(buffer)); if (templist != null) { SendCommandsToObservers(templist); } for (int i = 0; i < buffer.Length; i++) { buffer[i] = 0; } } if (result.CloseStatus.HasValue) { List <Command> cmdList = new List <Command>(); cmdList.Add(new DeleteObjectCommand(player)); SendCommandsToObservers(cmdList); } Console.WriteLine("ClientView has disconnected"); await socket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None); socket.Dispose(); } catch (Exception e) { return; } }
public async override Task CloseOutputAsync(WebSocketCloseStatus closeStatus, string statusDescription, CancellationToken cancellationToken) { ThrowIfDisposed(); ThrowIfOutputClosed(); var message = new Message(closeStatus, statusDescription); await _sendBuffer.SendAsync(message, cancellationToken); if (State == WebSocketState.Open) { _state = WebSocketState.CloseSent; } else if (State == WebSocketState.CloseReceived) { _state = WebSocketState.Closed; Close(); } }
protected static void ThrowOnInvalidState(WebSocketState state, params WebSocketState[] validStates) { string validStatesText = string.Empty; if (validStates != null && validStates.Length > 0) { foreach (WebSocketState currentState in validStates) { if (state == currentState) { return; } } validStatesText = string.Join(", ", validStates); } throw new WebSocketException(SR.Format(SR.net_WebSockets_InvalidState, state, validStatesText)); }
private void close(PayloadData payload, bool send, bool wait) { lock (_forClose) { if (_readyState == WebSocketState.CLOSING || _readyState == WebSocketState.CLOSED) return; _readyState = WebSocketState.CLOSING; } _logger.Trace ("Start closing handshake."); var args = new CloseEventArgs (payload); args.WasClean = _client ? close ( send ? WsFrame.CreateCloseFrame (Mask.MASK, payload).ToByteArray () : null, wait ? 5000 : 0, closeClientResources) : close ( send ? WsFrame.CreateCloseFrame (Mask.UNMASK, payload).ToByteArray () : null, wait ? 1000 : 0, closeServerResources); _readyState = WebSocketState.CLOSED; OnClose.Emit (this, args); _logger.Trace ("End closing handshake."); }
// As server internal void Close(CloseEventArgs args, byte [] frameAsBytes, int waitTimeOut) { lock (_forClose) { if (_readyState == WebSocketState.CLOSING || _readyState == WebSocketState.CLOSED) return; _readyState = WebSocketState.CLOSING; } args.WasClean = close (frameAsBytes, waitTimeOut, closeServerResources); _readyState = WebSocketState.CLOSED; OnClose.Emit (this, args); }
private void init () { _compression = CompressionMethod.None; _cookies = new CookieCollection (); _forConn = new object (); _forEvent = new object (); _forSend = new object (); _messageEventQueue = new Queue<MessageEventArgs> (); _forMessageEventQueue = ((ICollection) _messageEventQueue).SyncRoot; _readyState = WebSocketState.Connecting; }
public void InterlockedCheckAndUpdateState( WebSocketState newState, params WebSocketState[] validStates) { lock (_lock) { CheckValidState(validStates); UpdateState(newState); } }
// As server internal void Close(HttpStatusCode code) { _readyState = WebSocketState.CLOSING; send (createHandshakeResponse (code)); closeServerResources (); _readyState = WebSocketState.CLOSED; }
public void UpdateState(WebSocketState value) { if ((_state != WebSocketState.Closed) && (_state != WebSocketState.Aborted)) { _state = value; } }
private void open() { _readyState = WebSocketState.OPEN; OnOpen.Emit (this, EventArgs.Empty); startReceiving (); }
private WebSocket() { _compression = CompressionMethod.NONE; _cookies = new CookieCollection (); _extensions = String.Empty; _forClose = new object (); _forSend = new object (); _origin = String.Empty; _preAuth = false; _protocol = String.Empty; _readyState = WebSocketState.CONNECTING; }
/// <summary> /// Processes a websocket frame and triggers consumer events /// </summary> /// <param name="psocketState">We need to modify the websocket state here depending on the frame</param> private void ProcessFrame(WebSocketState psocketState) { if (psocketState.Header.IsMasked) { byte[] unmask = psocketState.ReceivedBytes.ToArray(); WebSocketReader.Mask(psocketState.Header.Mask, unmask); psocketState.ReceivedBytes = new List<byte>(unmask); } if (psocketState.Header.Opcode != WebSocketReader.OpCode.Continue && _initialMsgTimeout > 0) { _receiveDone.Set(); _initialMsgTimeout = 0; } switch (psocketState.Header.Opcode) { case WebSocketReader.OpCode.Ping: PingDelegate pingD = OnPing; if (pingD != null) { pingD(this, new PingEventArgs()); } WebSocketFrame pongFrame = new WebSocketFrame(){Header = WebsocketFrameHeader.HeaderDefault(),WebSocketPayload = new byte[0]}; pongFrame.Header.Opcode = WebSocketReader.OpCode.Pong; pongFrame.Header.IsEnd = true; SendSocket(pongFrame.ToBytes()); break; case WebSocketReader.OpCode.Pong: PongDelegate pongD = OnPong; if (pongD != null) { pongD(this, new PongEventArgs(){PingResponseMS = Util.EnvironmentTickCountSubtract(Util.EnvironmentTickCount(),_pingtime)}); } break; case WebSocketReader.OpCode.Binary: if (!psocketState.Header.IsEnd) // Not done, so we need to store this and wait for the end frame. { psocketState.ContinuationFrame = new WebSocketFrame { Header = psocketState.Header, WebSocketPayload = psocketState.ReceivedBytes.ToArray() }; } else { // Send Done Event! DataDelegate dataD = OnData; if (dataD != null) { dataD(this,new WebsocketDataEventArgs(){Data = psocketState.ReceivedBytes.ToArray()}); } } break; case WebSocketReader.OpCode.Text: if (!psocketState.Header.IsEnd) // Not done, so we need to store this and wait for the end frame. { psocketState.ContinuationFrame = new WebSocketFrame { Header = psocketState.Header, WebSocketPayload = psocketState.ReceivedBytes.ToArray() }; } else { TextDelegate textD = OnText; if (textD != null) { textD(this, new WebsocketTextEventArgs() { Data = Encoding.UTF8.GetString(psocketState.ReceivedBytes.ToArray()) }); } // Send Done Event! } break; case WebSocketReader.OpCode.Continue: // Continuation. Multiple frames worth of data for one message. Only valid when not using Control Opcodes //Console.WriteLine("currhead " + psocketState.Header.IsEnd); //Console.WriteLine("Continuation! " + psocketState.ContinuationFrame.Header.IsEnd); byte[] combineddata = new byte[psocketState.ReceivedBytes.Count+psocketState.ContinuationFrame.WebSocketPayload.Length]; byte[] newdata = psocketState.ReceivedBytes.ToArray(); Buffer.BlockCopy(psocketState.ContinuationFrame.WebSocketPayload, 0, combineddata, 0, psocketState.ContinuationFrame.WebSocketPayload.Length); Buffer.BlockCopy(newdata, 0, combineddata, psocketState.ContinuationFrame.WebSocketPayload.Length, newdata.Length); psocketState.ContinuationFrame.WebSocketPayload = combineddata; psocketState.Header.PayloadLen = (ulong)combineddata.Length; if (psocketState.Header.IsEnd) { if (psocketState.ContinuationFrame.Header.Opcode == WebSocketReader.OpCode.Text) { // Send Done event TextDelegate textD = OnText; if (textD != null) { textD(this, new WebsocketTextEventArgs() { Data = Encoding.UTF8.GetString(combineddata) }); } } else if (psocketState.ContinuationFrame.Header.Opcode == WebSocketReader.OpCode.Binary) { // Send Done event DataDelegate dataD = OnData; if (dataD != null) { dataD(this, new WebsocketDataEventArgs() { Data = combineddata }); } } else { // protocol violation } psocketState.ContinuationFrame = null; } break; case WebSocketReader.OpCode.Close: Close(string.Empty); break; } psocketState.Header.SetDefault(); psocketState.ReceivedBytes.Clear(); psocketState.ExpectedBytes = 0; }
public void InterlockedCheckValidStates(WebSocketState[] validStates) { lock (_lock) { CheckValidState(validStates); } }
public void Open( string url ) { if (IsOpen) { Close(); Helper.Log("FIXME: Wait for the connection to close"); } _url = url; try { _state = WebSocketState.Connecting; makeHandshake( url ); } catch (Exception err) { Helper.Log( "ERROR: " + err ); _state = WebSocketState.Closed; throw; } }
// Must be called with Lock taken. public void CheckValidState(WebSocketState[] validStates) { string validStatesText = string.Empty; if (validStates != null && validStates.Length > 0) { foreach (WebSocketState currentState in validStates) { if (_state == currentState) { // Ordering is important to maintain .Net 4.5 WebSocket implementation exception behavior. if (_disposed) { throw new ObjectDisposedException(GetType().FullName); } return; } } validStatesText = string.Join(", ", validStates); } throw new WebSocketException(SR.Format(SR.net_WebSockets_InvalidState, _state, validStatesText)); }
public void Cleanup() { ResponseHeaders.Clear(); Stream = null; _state = WebSocketState.Closed; }
/// <summary> /// Informs the otherside that we accepted their upgrade request /// </summary> /// <param name="pHandshakeResponse">The HTTP 1.1 101 response that says Yay \o/ </param> private void SendUpgradeSuccess(string pHandshakeResponse) { // Create a new websocket state so we can keep track of data in between network reads. WebSocketState socketState = new WebSocketState() { ReceivedBytes = new List<byte>(), Header = WebsocketFrameHeader.HeaderDefault(), FrameComplete = true}; byte[] bhandshakeResponse = Encoding.UTF8.GetBytes(pHandshakeResponse); try { if (_initialMsgTimeout > 0) { _receiveDone.Reset(); } // Begin reading the TCP stream before writing the Upgrade success message to the other side of the stream. _networkContext.Stream.BeginRead(_buffer, 0, _bufferLength, OnReceive, socketState); // Write the upgrade handshake success message _networkContext.Stream.Write(bhandshakeResponse, 0, bhandshakeResponse.Length); _networkContext.Stream.Flush(); _upgraded = true; UpgradeCompletedDelegate d = OnUpgradeCompleted; if (d != null) d(this, new UpgradeCompletedEventArgs()); if (_initialMsgTimeout > 0) { if (!_receiveDone.WaitOne(TimeSpan.FromMilliseconds(_initialMsgTimeout))) Close(string.Empty); } } catch (IOException) { Close(string.Empty); } catch (ObjectDisposedException) { Close(string.Empty); } }
// As server internal void Close (CloseEventArgs e, byte[] frameAsBytes, TimeSpan timeout) { lock (_forConn) { if (_readyState == WebSocketState.Closing) { _logger.Info ("The closing is already in progress."); return; } if (_readyState == WebSocketState.Closed) { _logger.Info ("The connection has been closed."); return; } _readyState = WebSocketState.Closing; } e.WasClean = closeHandshake (frameAsBytes, timeout, releaseServerResources); _readyState = WebSocketState.Closed; try { OnClose.Emit (this, e); } catch (Exception ex) { _logger.Fatal (ex.ToString ()); } }
// if I known that all messages will be ASCII, I can optimize strings exchange public WebSocket( Encoding encoding ) { Helper.CheckArgNotNull( encoding, "encoding" ); _enc = encoding; RequestHeaders = new WebHeaderCollection(); ResponseHeaders = new WebHeaderCollection(); HttpHeader = "GET {0} HTTP/1.1"; prepareHeaders(); _forState = new object(); _state = WebSocketState.Closed; }
// As server internal void InternalAccept () { try { if (acceptHandshake ()) { _readyState = WebSocketState.Open; open (); } } catch (Exception ex) { processException (ex, "An exception has occurred while accepting."); } }
public void Close() { if (!IsOpen) return; // Change state to Closing so that no other messages come through _state = WebSocketState.Closing; // Send Close control frame SendClose(); // TODO: Cleanup }
private void close (CloseEventArgs e, bool send, bool wait) { lock (_forConn) { if (_readyState == WebSocketState.Closing) { _logger.Info ("The closing is already in progress."); return; } if (_readyState == WebSocketState.Closed) { _logger.Info ("The connection has been closed."); return; } send = send && _readyState == WebSocketState.Open; wait = wait && send; _readyState = WebSocketState.Closing; } _logger.Trace ("Begin closing the connection."); e.WasClean = closeHandshake ( send ? WebSocketFrame.CreateCloseFrame (e.PayloadData, _client).ToArray () : null, wait ? _waitTime : TimeSpan.Zero, _client ? (Action) releaseClientResources : releaseServerResources); _logger.Trace ("End closing the connection."); _readyState = WebSocketState.Closed; try { OnClose.Emit (this, e); } catch (Exception ex) { _logger.Fatal (ex.ToString ()); error ("An exception has occurred during an OnClose event.", ex); } }
void makeHandshake( string url ) { Uri uri = new Uri( url ); string host = uri.DnsSafeHost; string path = uri.PathAndQuery; bool isWss = url.ToLower().StartsWith( "wss" ); string origin = uri.Scheme + "://" + host; Socket sock = new Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp ); sock.SetSocketOption( SocketOptionLevel.Socket, SocketOptionName.NoDelay, true ); IPAddress addr = Dns.GetHostAddresses( host )[ 0 ]; int port = uri.Port; port = port < 0 ? (isWss ? 443 : 80) : port; sock.Connect( new IPEndPoint( addr, port ) ); Stream stream = new NetworkStream( sock, true ); if (isWss) { var ssl = new SslStream( stream, false, validateServerCertificate ); ssl.AuthenticateAsClient( host ); stream = ssl; } // create HttpKey header var bsec = new byte[ 16 ]; using (var rnd = RandomNumberGenerator.Create()) rnd.GetBytes( bsec ); var ssec = Convert.ToBase64String( bsec ); var whs = RequestHeaders; whs[ HttpRequestHeader.Host ] = host; whs[ sOrigin ] = origin; whs[ sSecOrigin ] = origin; whs[ sSecKey ] = ssec; string sreq0 = string.Format( HttpHeader, path ); string sreq = sreq0 + "\r\n" + whs.ToString(); whs[ HttpKey ] = sreq0; // send HttpKey-header to server (UTF8. ignore _enc) int len = Encoding.UTF8.GetBytes( sreq, 0, sreq.Length, _buf_data, 0 ); stream.Write( _buf_data, 0, len ); // read response from server whs = readHttpResponse( stream, ResponseHeaders ); // Sincerely yours, Captain Obviousness // check headers if ((!"HTTP/1.1 101 Switching Protocols".Equals(whs[HttpKey]) && !"HTTP/1.1 101 Web Socket Protocol Handshake".Equals(whs[HttpKey])) || !sWebsocket.Equals( whs[ HttpResponseHeader.Upgrade ] ) || !sUpgrade.Equals( whs[ HttpResponseHeader.Connection ] )) { throw new FormatException( "Invalid handshake response" ); } // check SecKey ssec += sSecSalt; using (var sha1 = new SHA1Managed()) { sha1.Initialize(); bsec = sha1.ComputeHash( Encoding.ASCII.GetBytes( ssec ) ); } var shash = Convert.ToBase64String( bsec ); if (whs[ sSecAccept ] != shash) throw new FormatException( "Sec-WebSocket-Accept not equals to SHA1-hash" ); // The connection is now in the OPEN state _state = WebSocketState.Open; Stream = stream; beginRecv( stream ); }
// As client private bool connect () { lock (_forConn) { var msg = _readyState.CheckIfAvailable (true, false, false, true); if (msg != null) { _logger.Error (msg); error ("An error has occurred in connecting.", null); return false; } try { _readyState = WebSocketState.Connecting; if (doHandshake ()) { _readyState = WebSocketState.Open; return true; } } catch (Exception ex) { processException (ex, "An exception has occurred while connecting."); } return false; } }