private void EndSendServerHandshake(IAsyncResult ar) { Socket socket = (Socket)ar.AsyncState; socket.EndSend(ar); loggerEvents.OnNext(new Log(DateTime.Now + "> new connection from " + socket.LocalEndPoint, ServerLogLevel.Subtle)); // keep track of the new guy var clientConnection = new WebSocketConnection(socket); Connections.Add(clientConnection); clientConnection.OnSocketInfo.Where(si => si.Code == SocketInfoCode.Closed).Subscribe(_ => { ClientDisconnected(clientConnection, EventArgs.Empty); }); // invoke the connection event clientSocketEvents.OnNext(new ClientInfo(SocketInfoCode.Connected, "")); if (LogLevel != ServerLogLevel.Nothing) //clientConnection.OnMessage.Subscribe(x => //{ // DataReceivedFromClient(clientConnection, x); //}); // listen for more clients ListenForClients(); }
void DataReceivedFromClient(WebSocketConnection sender, string data) { clientSocketEvents.OnNext(new ClientInfo(SocketInfoCode.Received, data)); onMessage.OnNext(new Tuple<WebSocketConnection, string>(sender, data)); //loggerEvents.OnNext(new Log(string.Format("{0} > data ({1} bytes) from {2} : {3}", DateTime.Now, Encoding.UTF8.GetByteCount(data), sender.Socket.LocalEndPoint,data), ServerLogLevel.Verbose)); }
void ClientDisconnected(WebSocketConnection sender, EventArgs e) { Connections.Remove(sender); //loggerEvents.OnNext(new Log(string.Format("{0} > {1} disconnected", DateTime.Now, sender.Socket.LocalEndPoint), ServerLogLevel.Subtle)); }
/// <summary> /// send a string to all the clients except one /// </summary> /// <param name="data">the string to send</param> /// <param name="indifferent">the client that doesn't care</param> public void SendToAllExceptOne(string data, WebSocketConnection indifferent) { foreach (var client in Connections) { if (client != indifferent) client.Send(data); } }
public void Send(string data, WebSocketConnection client) { client.Send(data); }
/// <summary> /// Establishes the connection /// </summary> public void Connect() { string host = uri.Host; StringBuilder path = new StringBuilder(uri.AbsolutePath); if (path.Length == 0) { path.Append('/'); } string query = uri.Query; if (!string.IsNullOrEmpty(query)) { path.Append("?"); path.Append(query); } string origin = "http://" + host; networkStream = CreateSocket(); if (networkStream != null) { if (uri.Port != 80) { host = host + ":" + uri.Port; } ClientHandshake shake = new ClientHandshake(); shake.Host = host; shake.Origin = origin; shake.AdditionalFields = headers; shake.Key1 = Guid.NewGuid().ToString(); shake.Key2 = Guid.NewGuid().ToString(); shake.Key1 = shake.Key1.Replace('-', ' ').Substring(0, 10); shake.Key2 = shake.Key2.Replace('-', ' ').Substring(0, 10); var baseChallenge = Guid.NewGuid().ToString().Substring(0, 8); var challenge = baseChallenge.Substring(0, 2) + " " + baseChallenge.Substring(3, 2) + " " + baseChallenge.Substring(5, 2); shake.ChallengeBytes = new ArraySegment<byte>(Encoding.UTF8.GetBytes(challenge)); shake.ResourcePath = path.ToString(); //outputStream = new StreamWriter(networkStream, Encoding.UTF8); var response = shake.ToString(); byte[] encodedHandshake = Encoding.UTF8.GetBytes(response); networkStream.Write(encodedHandshake, 0, encodedHandshake.Length); networkStream.Flush(); //This needs to be implemented for security // var expectedAnswer = Encoding.UTF8.GetString(HandshakeHelper.CalculateAnswerBytes(shake.Key1, shake.Key2, shake.ChallengeBytes)); inputStream = new StreamReader(networkStream); //var input = inputStream.ReadToEnd(); string header = inputStream.ReadLine(); if (!header.Equals("HTTP/1.1 101 WebSocket Protocol Handshake")) { if (OnError != null) OnError(new InvalidOperationException("Invalid handshake response")); throw new InvalidOperationException("Invalid handshake response"); } header = inputStream.ReadLine(); if (!header.Equals("Upgrade: WebSocket")) { if (OnError != null) OnError(new InvalidOperationException("Invalid handshake response")); throw new InvalidOperationException("Invalid handshake response"); } header = inputStream.ReadLine(); if (!header.Equals("Connection: Upgrade")) { if (OnError != null) OnError(new InvalidOperationException("Invalid handshake response")); throw new InvalidOperationException("Invalid handshake response"); } // Ignore any further response do { header = inputStream.ReadLine(); } while (!header.Equals("")); handshakeComplete = true; connection = new WebSocketConnection(networkStream, isSocketIo); SubscribeToConnectionEvents(); } else { throw new InvalidOperationException("Could not create socket"); } }