/// <summary> /// When a client is connected, bind all relevant events. /// </summary> /// <param name="Socket"></param> private void OnClient(IWebSocketConnection Socket) { // Handle new socket opens. Socket.OnOpen = () => { Console.Error.WriteLine("[II] Repeater Open: " + Socket.ConnectionInfo.ClientIpAddress + Socket.ConnectionInfo.Path); try { // Extract repeater arguments from URL. var sPath = Socket.ConnectionInfo.Path.ToLowerInvariant(); var dArgs = Regex.Matches(sPath, "([^?=&]+)(=([^&]*))?").Cast <Match>().ToDictionary(x => x.Groups[1].Value, x => x.Groups[3].Value); // Handle based on the available types. if (sPath.StartsWith("/tuio")) { dSockets[Socket] = new TUIOForwarder(dArgs); } else if (sPath.StartsWith("/console")) { dSockets[Socket] = new ConsoleForwarder(); } else if (sPath.StartsWith("/win7")) { dSockets[Socket] = new Win7Forwarder(dArgs); } else if (sPath.StartsWith("/win8")) { dSockets[Socket] = new Win8Forwarder(dArgs); } else if (sPath.StartsWith("/mouse")) { dSockets[Socket] = new MouseForwarder(dArgs); } else { throw new ArgumentException("Unsupported Repeater"); } } catch (Exception e) { Console.Error.WriteLine(e.Message); Socket.Close(); } }; // Handle socket closures. Socket.OnClose = () => { Console.Error.WriteLine("[II] Repeater Closed: " + Socket.ConnectionInfo.ClientIpAddress + Socket.ConnectionInfo.Path); // Clean up. IForwarder pOut; if (dSockets.TryRemove(Socket, out pOut)) { if (pOut != null) { pOut.Dispose(); } } }; // Handle socket errors. Socket.OnError = (Exception e) => { Console.WriteLine("[WW] Repeater Socket Error: " + e.Message); Socket.Close(); }; // Listen for socket commands. Socket.OnMessage = (string data) => { // Parse the message out. var pMessage = TouchMessage.FromString(data); if (pMessage.Valid == false) { //Console.Error.WriteLine("[WW] Touch Invalid: " + data); return; } // Find the forwarder. IForwarder pFwd; if (dSockets.TryGetValue(Socket, out pFwd)) { if (pFwd != null) { pFwd.Forward(pMessage); } } }; }
/// <summary> /// Parse a string in the format "#type|id|x|y|z" OR "#type|id|x|y|z|userdata". id is an integer, type is one of 'u', 'd', or 'm' (up, down, move). /// </summary> /// <param name="Data"></param> public static TouchMessage FromString(String Data) { // New packet. var pMessage = new TouchMessage() { Valid = false }; // Source data. pMessage.Source = Data; try { // Constants. const char SPLIT = '|'; // delimiter const string MAGIC = "#"; // magic start const int VARS_NO_USER = 5; // number of data items excluding user data const int VARS_W_USER = VARS_NO_USER + 1; // number of data items including user data // Verify magic. if (Data == null || !Data.StartsWith(MAGIC)) { return(pMessage); } // Consume magic start. Data = Data.Substring(1); // Parse information out. var tParts = Data.Split(SPLIT); if (tParts.Length == VARS_NO_USER || tParts.Length == VARS_W_USER) { var t = tParts[0].ToString(); // type pMessage.Type = (t == "u") ? Nature.Up : (t == "d") ? Nature.Down : (t == "m") ? Nature.Move : Nature.Unknown; pMessage.ID = int.Parse(tParts[1].ToString()); // id pMessage.X = double.Parse(tParts[2].ToString()); // x pMessage.Y = double.Parse(tParts[3].ToString()); // y pMessage.Z = double.Parse(tParts[4].ToString()); // z if (tParts.Length == VARS_W_USER) // userdata { pMessage.UserData = tParts[5].ToString(); } } else { return(pMessage); } // If the type is unknown. if (pMessage.Type == Nature.Unknown) { return(pMessage); } // Say we are valid. pMessage.Valid = true; } finally { // Log malformed message string. } // Return the message. return(pMessage); }