예제 #1
0
        public void Respond()
        {
            _logger.Information(this.GetType(), "Request: {0}", _path);
            string file = GetSafePath(_path);

            // default to index.html is path is supplied
            if (IsDirectory(file))
            {
                file += "index.html";
            }

            FileInfo fi = new FileInfo(file);

            if (fi.Exists)
            {
                string ext = fi.Extension.ToLower();

                string contentType;
                if (_mimeTypes.TryGetValue(ext, out contentType))
                {
                    Byte[] bytes = File.ReadAllBytes(fi.FullName);
                    RespondSuccess(contentType, bytes.Length);
                    _stream.Write(bytes, 0, bytes.Length);
                    _logger.Information(this.GetType(), "Served file: {0}", file);
                }
                else
                {
                    RespondMimeTypeFailure(file);
                }
            }
            else
            {
                RespondNotFoundFailure(file);
            }
        }
예제 #2
0
        protected override void PerformHandshake(Stream stream) {
            string header = _header;

            try {
                Regex webSocketKeyRegex = new Regex("Sec-WebSocket-Key: (.*)");
                Regex webSocketVersionRegex = new Regex("Sec-WebSocket-Version: (.*)");

                // check the version. Support version 13 and above
                const int WebSocketVersion = 13;
                int secWebSocketVersion = Convert.ToInt32(webSocketVersionRegex.Match(header).Groups[1].Value.Trim());
                if (secWebSocketVersion < WebSocketVersion) {
                    throw new WebSocketVersionNotSupportedException(string.Format("WebSocket Version {0} not suported. Must be {1} or above", secWebSocketVersion, WebSocketVersion));
                }

                string secWebSocketKey = webSocketKeyRegex.Match(header).Groups[1].Value.Trim();
                string setWebSocketAccept = base.ComputeSocketAcceptString(secWebSocketKey);
                string response = ("HTTP/1.1 101 Switching Protocols" + Environment.NewLine
                                   + "Connection: Upgrade" + Environment.NewLine
                                   + "Upgrade: websocket" + Environment.NewLine
                                   + "Sec-WebSocket-Accept: " + setWebSocketAccept);

                HttpHelper.WriteHttpHeader(response, stream);
                _logger.Information(this.GetType(), "Web Socket handshake sent");
            }
            catch (WebSocketVersionNotSupportedException) {
                string response = "HTTP/1.1 426 Upgrade Required" + Environment.NewLine + "Sec-WebSocket-Version: 13";
                HttpHelper.WriteHttpHeader(response, stream);
                throw;
            }
            catch (Exception) {
                HttpHelper.WriteHttpHeader("HTTP/1.1 400 Bad Request", stream);
                throw;
            }
        }
예제 #3
0
        private static void TestClient(object state)
        {
            try
            {
                string url = (string)state;
                using (var client = new ChatWebSocketClient(true, _logger))
                {
                    Uri uri = new Uri(url);
                    client.TextFrame        += Client_TextFrame;
                    client.ConnectionOpened += Client_ConnectionOpened;

                    // test the open handshake
                    client.OpenBlocking(uri);
                }

                _logger.Information(typeof(Program), "Client finished, press any key");
            }
            catch (Exception ex)
            {
                _logger.Error(typeof(Program), ex.ToString());
                _logger.Information(typeof(Program), "Client terminated: Press any key");
            }

            Console.ReadKey();
        }
예제 #4
0
        /// <summary>
        /// Gets the first available port and listens on it. Returns the port
        /// </summary>
        public int Listen()
        {
            IPAddress localAddress = IPAddress.Any;

            _listener = new TcpListener(localAddress, 0);
            _listener.Start();
            StartAccept("int Webserver:Listen");
            int port = ((IPEndPoint)_listener.LocalEndpoint).Port;

            _logger.Information(this.GetType(), string.Format("Server started listening on port {0}", port));
            return(port);
        }
        protected override void OnTextFrame(string text)
        {
            string response = "ServerABC: " + text;

            base.Send(response);
            _logger.Information(this.GetType(), response);
        }
예제 #6
0
        public HttpPostService(Stream stream, TcpClient tcpClient, string header, IWebSocketLogger logger, WebServer server, String Identification_Alias, BusinessObject My_CommObject) : base(stream, tcpClient, header, true, logger)
        {
            _logger = logger;
            _server = server;
            _stream = stream;
            _Identification_Alias = Identification_Alias;
            _header = header;
            //Response to Client
            RespondSuccess("text/html");

            _My_CommObject = My_CommObject;
            string sValue      = "";
            string sDeviceType = "";

            string[] tokens = _header.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);

            if (tokens.Length > 3)//标示有标识内容类型
            {
                foreach (string sTemp in tokens)
                {
                    if ((sTemp.ToUpper().Contains("application/json".ToUpper())) && (sTemp.ToUpper().Contains("Content-Type:".ToUpper())))//Jason format
                    {
                        sValue = tokens[tokens.Length - 1];
                        if (base.IsValidJson(sValue))
                        {
                            JToken  Content = null;
                            JObject JSearch = JObject.Parse(sValue);
                            if (JSearch.TryGetValue("reader_name", out Content))//Zebra FX Reader
                            {
                                sDeviceType = "ZebraFXReader";
                            }
                        }
                    }

                    if ((sTemp.ToUpper().Contains("multipart/form-data;".ToUpper())) && (sTemp.ToUpper().Contains("Content-Type:".ToUpper())))//Jason format
                    {
                        sDeviceType = "ZebraPrinter_HttpPost";
                        sValue      = tokens[tokens.Length - 1];
                    }
                }
                _logger.Information("", this.GetType(), "Got HttpPost request:" + Environment.NewLine + _header);
            }
            else
            {
                _logger.Information("", this.GetType(), "Invalid http request");
            }
        }
예제 #7
0
        protected virtual void OnConnectionClose(byte[] payload)
        {
            ConnectionCloseEventArgs args = GetConnectionCloseEventArgsFromPayload(payload);

            if (args.Reason == null)
            {
                _logger.Information(this.GetType(), "Received web socket close message: {0}", args.Code);
            }
            else
            {
                _logger.Information(this.GetType(), "Received web socket close message: Code '{0}' Reason '{1}'", args.Code, args.Reason);
            }

            if (ConnectionClose != null)
            {
                ConnectionClose(this, args);
            }
        }
예제 #8
0
        protected override void OnTextFrame(string text)
        {
            string response = "ServerABC: " + text;

            base.Send(response);

            // limit the log message size
            string logMessage = response.Length > 100 ? response.Substring(0, 100) + "..." : response;

            _logger.Information(this.GetType(), logMessage);
        }
예제 #9
0
        private bool ParsePostAndCreateUser(string sHeader)
        {
            int    iLength   = GetContentLength(sHeader);
            string sPostData = sHeader.Substring(sHeader.Length - iLength);

            _logger.Information(typeof(MOTR_WebserverFactoryInitalWizard), "PostData from init: " + sPostData);

            string[] sTextSplit = sPostData.Split('&');

            string sUsername      = "";
            string sPassword      = "";
            string sAdminPassword = "";

            //Loop through
            for (int i = 0; i < sTextSplit.Count(); i++)
            {
                string[] sItem = sTextSplit[i].Split('=');
                if (sItem.Count() > 1)
                {
                    if (sItem[0].ToLower() == "username")
                    {
                        sUsername = sItem[1];
                    }
                    if (sItem[0].ToLower() == "password")
                    {
                        sPassword = sItem[1];
                    }
                    if (sItem[0].ToLower() == "adminpassword")
                    {
                        sAdminPassword = sItem[1];
                    }
                }
            }

            //Check that we got what we came for
            if (sUsername.Length < 1 || sPassword.Length < 6 || sAdminPassword.Length < 8)
            {
                WindowsService.LogEventError(string.Format("One or more items is empty or to short: User: {0} - Pass: {1} - Admin: {2}", sUsername, sPassword, sAdminPassword));
                return(false);
            }

            //Now create a user
            m_Users.AddUserName(sUsername, sPassword);

            //Now create an admin password
            m_Admin.CreateAdminPassword(sAdminPassword);
            if (m_Admin.GetErrorString().Length > 0)
            {
                WindowsService.LogEventError(m_Admin.GetErrorString());
            }
            return(true);
        }
예제 #10
0
 public ServiceFactory(string webRoot, IWebSocketLogger logger)
 {
     _logger  = logger;
     _webRoot = string.IsNullOrWhiteSpace(webRoot) ? GetWebRoot() : webRoot;
     if (!Directory.Exists(_webRoot))
     {
         _logger.Warning(this.GetType(), "Web root not found: {0}", _webRoot);
     }
     else
     {
         _logger.Information(this.GetType(), "Web root: {0}", _webRoot);
     }
 }
예제 #11
0
 public void Listen(int port, X509Certificate2 sslCertificate)
 {
     try
     {
         _sslCertificate = sslCertificate;
         IPAddress localAddress = IPAddress.Any;
         _listener = new TcpListener(localAddress, port);
         _listener.Start();
         _logger.Information("", this.GetType(), "Server started listening on port {0}", port);
         StartAccept();
     }
     catch (SocketException ex)
     {
         string message = string.Format("Error listening on port {0}. Make sure IIS or another application is not running and consuming your port.", port);
         throw new ServerListenerSocketException(message, ex);
     }
 }
예제 #12
0
 public ServiceFactory(string webRoot, IWebSocketLogger logger, String Identification_Alias, WebServer server, BusinessObject My_CommObject)
 {
     _Identification_Alias = Identification_Alias;
     _logger        = logger;
     _webRoot       = string.IsNullOrWhiteSpace(webRoot) ? GetWebRoot() : webRoot;
     _server        = server;
     _My_CommObject = My_CommObject;
     if (!Directory.Exists(_webRoot))
     {
         _logger.Warning("", this.GetType(), "Web root not found: {0}", _webRoot);
     }
     else
     {
         _logger.Information("", this.GetType(), "Web root: {0}", _webRoot);
     }
 }
예제 #13
0
        /// <summary>
        ///  Show the progress of the download in a progressbar
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        /*private void wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
         * {
         *  // In case you don't have a progressBar Log the value instead
         *  _logger.Information(typeof(MOTR_Moviescraper), "MOTR_Moviescraper image download: " + e.ProgressPercentage.ToString());
         * }*/

        //Feedback from the webclient, downloading our file to the imagestore
        private void wc_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
        {
            if (e.Cancelled)
            {
                _logger.Error(typeof(MOTR_Moviescraper), "Download canceled!");
                return;
            }

            if (e.Error != null) // We have an error! Retry a few times, then abort.
            {
                _logger.Error(typeof(MOTR_Moviescraper), "An error accured during download: " + e.Error.ToString());
                return;
            }

            _logger.Information(typeof(MOTR_Moviescraper), "MOTR_Moviescraper image download complete");
        }
예제 #14
0
        public MOTR_WebserverFactoryInitalWizard(string webRoot, MOTR_Users users, MOTR_Admin _admin, IWebSocketLogger logger)
        {
            _logger  = logger;
            _webRoot = string.IsNullOrWhiteSpace(webRoot) ? GetWebRoot() : webRoot;
            m_Users  = users;
            m_Admin  = _admin;

            if (!Directory.Exists(_webRoot))
            {
                _logger.Warning(this.GetType(), "InitalWizard: Web root not found: {0}", _webRoot);
            }
            else
            {
                _logger.Information(this.GetType(), "InitalWizard: Web root: {0}", _webRoot);
            }
        }
예제 #15
0
 private Stream GetStream(TcpClient tcpClient, bool isSecure)
 {
     if (isSecure)
     {
         SslStream sslStream = new SslStream(tcpClient.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
         _logger.Information(this.GetType(), "Attempting to secure connection...");
         sslStream.AuthenticateAsClient("clusteredanalytics.com");
         _logger.Information(this.GetType(), "Connection successfully secured.");
         return(sslStream);
     }
     else
     {
         _logger.Information(this.GetType(), "Connection not secure");
         return(tcpClient.GetStream());
     }
 }
        protected override void OnTextFrame(string text)
        {
            try
            {
                string response = "Server Send: " + text;
                base.Send(response);

                // limit the log message size
                int    length     = 1024 * 16; // 16KB buffer more than enough for http header
                string logMessage = response.Length > length?response.Substring(0, length) + "..." : response;

                _logger.Information("", this.GetType(), logMessage);
            }
            catch (Exception ex)
            {
                _logger.Error("", this.GetType(), ex.Message);
            }
        }
예제 #17
0
        private Stream GetStream(TcpClient tcpClient, bool isSecure, string host)
        {
            if (isSecure)
            {
                SslStream sslStream = new SslStream(tcpClient.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
                _logger.Information("", this.GetType(), "Attempting to secure connection...");

                // This will throw an AuthenticationException if the sertificate is not valid
                sslStream.AuthenticateAsClient(host);

                _logger.Information("", this.GetType(), "Connection successfully secured.");
                return(sslStream);
            }
            else
            {
                _logger.Information("", this.GetType(), "Connection not secure");
                return(tcpClient.GetStream());
            }
        }
예제 #18
0
        protected override void OnTextFrame(string text)
        {
            string jsonText = null;

            //             WebsocketSendClass WSTest2 = new WebsocketSendClass();
            //             WSTest2.command = "Do this thing";
            //             WSTest2.aArray = m_Dirs.GetArray();
            //             WSTest2.count = WSTest2.aArray.Count;
            //             jsonText = fastJSON.JSON.ToJSON(WSTest2);

            //Just for debugging purposes
            //Console.WriteLine("Received: " + text);

            //Every object is linked to this
            //WebSocketCommandClass WSCommand = (WebSocketCommandClass)fastJSON.JSON.ToObject(text);

            //Every object is linked to this
            WebSocketCommandClass WSCommand = new WebSocketCommandClass();

            //Try & catch on the parsing
            try
            {
                dynamic WSTemp = fastJSON.JSON.ToDynamic(text);
                WSCommand.command   = WSTemp.command;
                WSCommand.parameter = WSTemp.parameter;
                //WSCommand.sessionid = WSTemp.sessionid;
            }
            catch (Exception ex)
            {
                _logger.Error(typeof(MOTR_AdminWebsocket), "Admin->Error parsing JSON: " + text + " - Returnstring: " + ex.ToString());
                return;
            }

            //Check if the user is logged in
//            if (!m_Sessions.SessionLoggedIn(WSCommand.sessionid))
//                return;

            //Just temp info
//            _logger.Information(typeof(MOTR_AdminWebsocket), "session: " + WSCommand.sessionid);
            _logger.Information(typeof(MOTR_AdminWebsocket), "command: " + WSCommand.command);

            //This object is used to send info
            WebsocketSendClass WSSend = new WebsocketSendClass();

            //Return the state of the user trying to log in
            if (WSCommand.command == "ISLOGGEDIN")
            {
                //Store the session for later
                sSession = WSCommand.parameter;

                WSSend.command = "LOGGEDIN";
                WSSend.aArray  = new ArrayList();
                WSSend.aArray.Add(m_Admin.IsSessionLoggedIn(sSession));
                WSSend.count = WSSend.aArray.Count;
                jsonText     = fastJSON.JSON.ToJSON(WSSend);
                base.Send(jsonText);
                return;
            }

            //Return a ISLOGGEDIN if seesoin it not set
            if (sSession.Length == 0)
            {
                WSSend.command = "ISLOGGEDIN";
                WSSend.aArray  = new ArrayList();
                WSSend.aArray.Add("You need to sens ISLOGGEDIN first");
                WSSend.count = WSSend.aArray.Count;
                jsonText     = fastJSON.JSON.ToJSON(WSSend);
                base.Send(jsonText);
                return;
            }
            _logger.Information(typeof(MOTR_AdminWebsocket), "Session trying to admin: " + sSession);

            //Check password
            if (WSCommand.command == "LOGIN")
            {
                WSSend.command = "LOGIN";
                WSSend.aArray  = new ArrayList();
                WSSend.aArray.Add(m_Admin.CheckAdminPassword(WSCommand.parameter, sSession));
                WSSend.count = WSSend.aArray.Count;
                jsonText     = fastJSON.JSON.ToJSON(WSSend);
                base.Send(jsonText);
                return;
            }

            //=========================================================================
            //Everything below here is not available if not logged in
            if (!m_Admin.IsSessionLoggedIn(sSession))
            {
                return;
            }

            //Return an array of users
            if (WSCommand.command == "ADDUSER")
            {
                //Add the user
                string[] aInfo     = WSCommand.parameter.Split(',');
                string   sUsername = aInfo[0];
                string   sPassword = aInfo[1];
                bool     bRet      = m_Users.AddUserName(sUsername, sPassword);
                if (!bRet)
                {
                    m_Admin.SetErrorString("Username exists or wrong parameters");
                }

                //Send the userlist
                WSCommand.command = "USERLIST";
            }
            if (WSCommand.command == "CHANGEUSER")
            {
                //Add the user
                string[] aInfo     = WSCommand.parameter.Split(',');
                string   sID       = aInfo[0];
                string   sPassword = aInfo[1];
                int      nID       = Convert.ToInt32(sID);

                WSSend.command = "CHANGEUSER";
                WSSend.aArray  = new ArrayList();
                WSSend.aArray.Add(m_Users.ChangePassword(nID, sPassword));
                WSSend.count = WSSend.aArray.Count;
                jsonText     = fastJSON.JSON.ToJSON(WSSend);
            }
            //Return an array of users
            if (WSCommand.command == "DELETEUSER")
            {
                //Delete the user
                int nID = Convert.ToInt32(WSCommand.parameter);
                m_Users.RemoveUser(nID);

                //Send the userlist back
                WSCommand.command = "USERLIST";
            }

            //Sends the userlist, just names
            if (WSCommand.command == "USERLIST")
            {
                //Send new userlist
                WSSend.command = "USERLIST";
                WSSend.aArray  = m_Users.GetUserArray();
                WSSend.count   = WSSend.aArray.Count;
                jsonText       = fastJSON.JSON.ToJSON(WSSend);
            }

            //Adds a directory to the pathslist
            if (WSCommand.command == "ADMINADDIRECTORY")
            {
                string   sDisplayName, sPath, sUncUser, sUncPass;
                string[] sTmp = WSCommand.parameter.Split(',');

                //Only add if the parameters are correct
                if (sTmp.Length > 2)
                {
                    sDisplayName = sTmp[0];
                    sPath        = sTmp[1];
                    sUncUser     = sTmp[2];
                    sUncPass     = sTmp[3];

                    //Now add the directory
                    m_Dirs.AddDirectory(sDisplayName, sPath, sUncUser, sUncPass);
                }

                //Send directories available
                WSCommand.command = "DIRLIST";
            }

            //Removes a directory and return new dirlist
            if (WSCommand.command == "ADMINREMOVEDIRECTORY")
            {
                //Delete the user
                int nID = Convert.ToInt32(WSCommand.parameter);
                m_Dirs.RemoveDirectory(nID);

                //Send the userlist back
                WSCommand.command = "DIRLIST";
            }

            //Sends paths list
            if (WSCommand.command == "DIRLIST")
            {
                //Send new userlist
                WSSend.command = "DIRLIST";
                WSSend.aArray  = m_Dirs.GetDirsArray();
                WSSend.count   = WSSend.aArray.Count;
                jsonText       = fastJSON.JSON.ToJSON(WSSend);
                //Console.WriteLine("DIRLIST: " + jsonText);
            }

            //Sends drives and network list to the browser
            if (WSCommand.command == "ADMINDRIVES")
            {
                //Send new userlist
                WSSend.command = "ADMINDRIVES";
                WSSend.aArray  = m_Admin.GetDrivesAndNetwork();
                WSSend.count   = WSSend.aArray.Count;
                jsonText       = fastJSON.JSON.ToJSON(WSSend);
                //Console.WriteLine("ADMINDRIVES: " + jsonText);
            }

            //Set the drive we are going to browse
            if (WSCommand.command == "ADMINSETDRIVE")
            {
                m_Admin.SetBasePath(WSCommand.parameter);
                WSCommand.command = "ADMINFILELIST";
            }

            //Set the drive we are going to browse
            if (WSCommand.command == "ADMINSETPATH")
            {
                m_Admin.SetCurrentPath(WSCommand.parameter);
                WSCommand.command = "ADMINFILELIST";
            }

            //Return the filelist based on the current path
            if (WSCommand.command == "ADMINFILELIST")
            {
                //Send new userlist
                WSSend.command = "ADMINFILELIST";
                WSSend.aArray  = m_Admin.GetDirectoryList();
                WSSend.count   = WSSend.aArray.Count;
                jsonText       = fastJSON.JSON.ToJSON(WSSend);
                //Console.WriteLine("ADMINFILELIST: " + jsonText);
            }

            //Set the drive we are going to browse
            if (WSCommand.command == "ADMINCHECKFORTOOLUPDATE")
            {
                //Create return message
                WSSend.command = "ADMINCHECKFORTOOLUPDATE";
                WSSend.aArray  = new ArrayList();

                //Check if the tool is updated
                string sTool         = WSCommand.parameter;
                string sLocalVersion = MOTR_Settings.GetCurrentToolVersion(sTool);
                string sWebVersion   = MOTR_Settings.GetWebsiteToolVersion(sTool);
                if (sLocalVersion != sWebVersion)
                {
                    WSSend.aArray.Add("Updating " + sTool + " to v" + sWebVersion);
                    bool bRet = MOTR_Settings.UpdateTool(sTool, sWebVersion);
                    if (bRet)
                    {
                        WSSend.aArray.Add(sTool + " updated ok");
                    }
                    else
                    {
                        WSSend.aArray.Add(sTool + " failed to update");
                    }
                }
                else
                {
                    WSSend.aArray.Add("Newest version installed for " + sTool);
                }

                //Set the number of items added
                WSSend.count = WSSend.aArray.Count;
                jsonText     = fastJSON.JSON.ToJSON(WSSend);
            }

            //Restarts the server with given ports
            if (WSCommand.command == "ADMINRESTARTSERVER")
            {
                //Get ports available
                string[] ports  = WSCommand.parameter.Split(';');
                int      http   = MOTR_Settings.GetNumber("http");
                int      https  = MOTR_Settings.GetNumber("https");
                bool     bError = false;
                if (ports.Length > 1)
                {
                    //Temp store ports to check if changed
                    int httptemp  = http;
                    int httpstemp = https;
                    http  = Convert.ToInt32(ports[0]);
                    https = Convert.ToInt32(ports[1]);

                    //Check if the ports are available
                    if (httptemp != http)
                    {
                        if (WindowsService.IsPortOpen(http))
                        {
                            m_Admin.SetErrorString("http port is already taken, please choose another available port");
                            bError = true;
                        }
                    }
                    if (httpstemp != https)
                    {
                        if (WindowsService.IsPortOpen(https))
                        {
                            m_Admin.SetErrorString("https port is already taken, please choose another available port");
                            bError = true;
                        }
                    }
                }

                //No error, then we go fishing
                if (!bError)
                {
                    //Store the new ports
                    MOTR_Settings.SetNumber("http", http);
                    MOTR_Settings.SetNumber("https", https);

                    //Restart server
                    OnRestartWebserver(this, EventArgs.Empty);
                }

                //Send response back to server
                WSSend.command = "ADMINRESTARTSERVER";
                WSSend.aArray  = new ArrayList();
                WSSend.aArray.Add(bError);
                WSSend.aArray.Add(http);
                WSSend.aArray.Add(https);
                WSSend.count = WSSend.aArray.Count;
                jsonText     = fastJSON.JSON.ToJSON(WSSend);
            }


            //Send if the jsonText is set
            if (jsonText != null)
            {
                base.Send(jsonText);
            }
            else
            {
                _logger.Information(typeof(MOTR_AdminWebsocket), "Unknown admin command from websocket: " + WSCommand.command);
                WSSend.command = "UNKNOWN";
                WSSend.count   = 2;
                WSSend.aArray  = new ArrayList();
                WSSend.aArray.Add(WSCommand.command);
                WSSend.aArray.Add(WSCommand.parameter);
                jsonText = fastJSON.JSON.ToJSON(WSSend);
                base.Send(jsonText);
            }

            //Check if the admin has errors, send it if nessesary
            if (m_Admin.HasError)
            {
                WSSend.command = "ADMINERRORMESSAGE";
                WSSend.aArray  = new ArrayList();
                WSSend.aArray.Add(m_Admin.GetErrorString());
                WSSend.count = WSSend.count;
                jsonText     = fastJSON.JSON.ToJSON(WSSend);
                base.Send(jsonText);
            }
        }