public byte[] GetFrameBytesFromData(WebSocketOpCode opCode, byte[] payload, bool isLastFrame) { using (MemoryStream memoryStream = new MemoryStream()) { byte finBitSetAsByte = isLastFrame ? (byte)0x80 : (byte)0x00; byte byte1 = (byte)(finBitSetAsByte | (byte)opCode); memoryStream.WriteByte(byte1); // NB, dont set the mask flag. No need to mask data from server to client // depending on the size of the length we want to write it as a byte, ushort or ulong if (payload.Length < 126) { byte byte2 = (byte)payload.Length; memoryStream.WriteByte(byte2); } else if (payload.Length <= ushort.MaxValue) { byte byte2 = 126; memoryStream.WriteByte(byte2); BinaryReaderWriter.WriteUShort((ushort)payload.Length, memoryStream, false); } else { byte byte2 = 127; memoryStream.WriteByte(byte2); BinaryReaderWriter.WriteULong((ulong)payload.Length, memoryStream, false); } memoryStream.Write(payload, 0, payload.Length); byte[] buffer = memoryStream.ToArray(); return(buffer); } }
public BasicWebServer(string baseFolderPath = "", int?tcpPort = 54001, string httpPrefix = "http://localhost:8080/") { _tcpPort = tcpPort; _httpPrefix = httpPrefix; _wsClients = new Dictionary <string, NetworkStream>(); _httpMethods = new string[4] { "get", "post", "put", "delete" }; _cts = new CancellationTokenSource(); _ct = _cts.Token; _ct.Register(() => { _httpListener.Stop(); if (_tcpPort != null) { _tcpListener.Stop(); if (_tcpSocket != null && _tcpSocket.Connected) { //if we have active web socket clients send them a close message foreach (KeyValuePair <string, NetworkStream> entry in _wsClients) { WsFrameWriter frameWriter = new WsFrameWriter(entry.Value); //set the close reason to Normal BinaryReaderWriter.WriteUShort((ushort)WebSocketCloseCode.Normal, entry.Value, false); frameWriter.Write(WsOpCode.ConnectionClose, new byte[1], true); } _tcpSocket.Shutdown(SocketShutdown.Both); _tcpSocket.Close(); } } Console.WriteLine("Cancellation has been requested."); }); //check baseFolderPath if (!Directory.Exists(baseFolderPath)) { Console.WriteLine(baseFolderPath + " does not exist."); Console.WriteLine("Do you want to create it? (y/n)"); ConsoleKeyInfo consoleKey = Console.ReadKey(); if (consoleKey.KeyChar == 'y') { Directory.CreateDirectory(baseFolderPath); Console.WriteLine(); Console.WriteLine("Created base folder " + baseFolderPath); Console.WriteLine("Press any key to exit server."); Console.ReadKey(); } } else { _baseFolderPath = baseFolderPath; } }
public void Write(WebSocketOpCode opCode, byte[] payload, bool isLastFrame) { // best to write everything to a memory stream before we push it onto the wire // not really necessary but I like it this way using (MemoryStream memoryStream = new MemoryStream()) { byte finBitSetAsByte = isLastFrame ? (byte)0x80 : (byte)0x00; byte byte1 = (byte)(finBitSetAsByte | (byte)opCode); memoryStream.WriteByte(byte1); // NB, set the mask flag if we are constructing a client frame byte maskBitSetAsByte = _isClient ? (byte)0x80 : (byte)0x00; // depending on the size of the length we want to write it as a byte, ushort or ulong if (payload.Length < 126) { byte byte2 = (byte)(maskBitSetAsByte | (byte)payload.Length); memoryStream.WriteByte(byte2); } else if (payload.Length <= ushort.MaxValue) { byte byte2 = (byte)(maskBitSetAsByte | 126); memoryStream.WriteByte(byte2); BinaryReaderWriter.WriteUShort((ushort)payload.Length, memoryStream, false); } else { byte byte2 = (byte)(maskBitSetAsByte | 127); memoryStream.WriteByte(byte2); BinaryReaderWriter.WriteULong((ulong)payload.Length, memoryStream, false); } // if we are creating a client frame then we MUST mack the payload as per the spec if (_isClient) { byte[] maskKey = new byte[WebSocketFrameCommon.MaskKeyLength]; _random.NextBytes(maskKey); memoryStream.Write(maskKey, 0, maskKey.Length); // mask the payload WebSocketFrameCommon.ToggleMask(maskKey, payload); } memoryStream.Write(payload, 0, payload.Length); byte[] buffer = memoryStream.ToArray(); _stream.Write(buffer, 0, buffer.Length); } }
public virtual void Dispose() { if (_isOpen) { using (MemoryStream stream = new MemoryStream()) { // set the close reason to GoingAway BinaryReaderWriter.WriteUShort((ushort)WebSocketCloseCode.GoingAway, stream, false); // send close message to server to begin the close handshake Send(WebSocketOpCode.ConnectionClose, stream.ToArray()); _logger.Information("", this.GetType(), "Sent websocket close message to server. Reason: GoingAway"); } // this needs to run on a worker thread so that the read loop (in the base class) is not blocked Task.Factory.StartNew(WaitForServerCloseMessage); } }
public virtual void Dispose() { // send special web socket close message. Don't close the network stream, it will be disposed later if (_stream.CanWrite && !_isDisposed) { using (MemoryStream stream = new MemoryStream()) { // set the close reason to Normal BinaryReaderWriter.WriteUShort((ushort)WebSocketCloseCode.Normal, stream, false); // send close message to client to begin the close handshake Send(WebSocketOpCode.ConnectionClose, stream.ToArray()); } _isDisposed = true; _logger.Information("", this.GetType(), "Sent close message to client"); CloseConnection(_tcpClient.Client); } }
public static void SendWebSocket(int Index, WebSocketOpCode opCode, String Data, bool isLastFrame) { var array = Encoding.UTF8.GetBytes(Data); var fromPayload = new ArraySegment <byte>(array); MemoryStream memoryStream = new MemoryStream(); byte finBitSetAsByte = isLastFrame ? (byte)0x80 : (byte)0x00; byte byte1 = (byte)(finBitSetAsByte | (byte)opCode); memoryStream.WriteByte(byte1); byte maskBitSetAsByte = (byte)0x00; // depending on the size of the length we want to write it as a byte, ushort or ulong if (fromPayload.Count < 126) { byte byte2 = (byte)(maskBitSetAsByte | (byte)fromPayload.Count); memoryStream.WriteByte(byte2); } else if (fromPayload.Count <= ushort.MaxValue) { byte byte2 = (byte)(maskBitSetAsByte | 126); memoryStream.WriteByte(byte2); BinaryReaderWriter.WriteUShort((ushort)fromPayload.Count, memoryStream, false); } else { byte byte2 = (byte)(maskBitSetAsByte | 127); memoryStream.WriteByte(byte2); BinaryReaderWriter.WriteULong((ulong)fromPayload.Count, memoryStream, false); } memoryStream.Write(fromPayload.Array, fromPayload.Offset, fromPayload.Count); mapIndex_Client[Index].Socket.Client.Send(memoryStream.ToArray()); }