-4

I am making a birthday notification in windows service that uses jabber-net library which is a XMPP and System.Threading that must send automatic messages to user every day, but i'm getting an error in logs which says

Unable to cast object of type 'System.Threading.Timer' to type 'jabber.client.JabberClient'. at SparkSalesCrdBirthdays.SparkBirthDayGreeting.j_OnAuthenticate(Object sender)

Here's my code

protected override void OnStart(string[] args)
    {
        this.WriteToFile("Simple Service started {0}");
        JabberClient j = new JabberClient();

        // what user/pass to log in as
        j.User = "user";
        j.Server = "server";  // use gmail.com for GoogleTalk
        j.Password = "pass";
        //j.Resource = "admin";
        // don't do extra stuff, please.
        j.AutoPresence = false;
        j.AutoRoster = false;
        j.AutoReconnect = -1;
        j.KeepAlive = 10;
        j.AutoLogin = true;
        j.AutoStartTLS = false;
        j.PlaintextAuth = true;

        j.OnError += new bedrock.ExceptionHandler(j_OnError);

        // what to do when login completes
        j.OnAuthenticate += new bedrock.ObjectHandler(j_OnAuthenticate);

        // listen for XMPP wire protocol
        if (VERBOSE)
        {
            j.OnReadText += new bedrock.TextHandler(j_OnReadText);
            j.OnWriteText += new bedrock.TextHandler(j_OnWriteText);
        }
        // Set everything in motion
        j.Connect();

        // wait until sending a message is complete
        done.WaitOne();

        // logout cleanly
        j.Close();

        this.ScheduleService();
    }

    protected override void OnStop()
    {
        this.WriteToFile("Simple Service stopped {0}");
        this.Schedular.Dispose();
    }

    private Timer Schedular;

    static void j_OnWriteText(object sender, string txt)
    {
        if (txt == " ") return;  // ignore keep-alive spaces
        Console.WriteLine("SEND: " + txt);
    }

    static void j_OnReadText(object sender, string txt)
    {
        if (txt == " ") return;  // ignore keep-alive spaces
        Console.WriteLine("RECV: " + txt);
    }



private void j_OnAuthenticate(object sender)
    {

       try
        {
            JabberClient j = (JabberClient)sender;

            DataTable dt = new DataTable();
            string birthdaymsg = "";
            string fullname;
            string department;
            string query = "SELECT CONCAT(FirstName, ' ', MiddleName, ' ', LastName) as Fullname, DepartmentDescription FROM vw_EmployeeOrganization  WHERE DATEPART(d, BirthDate) = DATEPART(d,GETDATE()) AND DATEPART(m, BirthDate) = DATEPART(m, GETDATE()) AND DepartmentDescription IN('Client Relations--CDO', 'E-Learning', 'Sales ', 'Client Relations', 'Sales-Davao', 'Sales-CDO', 'Client Relations--Cebu', 'Sales-Cebu')";

            string constr = ConfigurationManager.ConnectionStrings["HRIS"].ConnectionString;
            lstUsers.Clear();

            using (SqlConnection conn = new SqlConnection(constr))
            {

                using (SqlCommand cmd = new SqlCommand(query))
                {

                    cmd.Connection = conn;


                    using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
                    {
                        sda.Fill(dt);

                    }
                }
            }

            foreach (DataRow row in dt.Rows)
            {

                fullname = row["Fullname"].ToString();
                department = row["DepartmentDescription"].ToString();

                birthdaymsg = "Happy Birthday! " + fullname + " from " + department + "." +
                    System.Environment.NewLine + "May today be filled with sunshine and smile, laughter and love.";

                string queryRecipient = "SELECT * FROM tbl_MPAlertUsers";
                string constr2 = ConfigurationManager.ConnectionStrings["Constring"].ConnectionString;

                using (SqlConnection conn2 = new SqlConnection(constr2))
                {
                    using (SqlCommand cmd2 = new SqlCommand(queryRecipient))
                    {

                        cmd2.Connection = conn2;
                        conn2.Open();
                        SqlDataReader reader = cmd2.ExecuteReader();

                        while (reader.Read())
                        {
                            lstUsers.Add(reader["ADname"].ToString());

                        }
                        reader.Close();
                        conn2.Close();



                    }
                }
                //Send to Recipient
                for (int i = 0; i <= lstUsers.Count - 1; i++)
                {

                    if (lstUsers[i].ToString().Trim().Length > 1)
                    {
                        WriteToFile("Trying to send spark to: " + lstUsers[i].ToString());
                        j.Message(lstUsers[i], birthdaymsg);

                    }
                }

                done.Set();
            }
            this.ScheduleService();
        }
        catch (Exception ex)
        {
            WriteToFile("Simple Service Error on: {0} " + ex.Message + ex.StackTrace);

            //Stop the Windows Service.
            using (System.ServiceProcess.ServiceController serviceController = new System.ServiceProcess.ServiceController("SparkBirthDayGreeting"))
            {
                serviceController.Stop();
            }
        }

    }

 public void ScheduleService()
    {
        try
        {

            Schedular = new Timer(new TimerCallback(j_OnAuthenticate));
            string mode = ConfigurationManager.AppSettings["Mode"].ToUpper();
            this.WriteToFile("Simple Service Mode: " + mode + " {0}");

            //Set the Default Time.
            DateTime scheduledTime = DateTime.MinValue;

            if (mode == "DAILY")
            {
                //Get the Scheduled Time from AppSettings.
                scheduledTime = DateTime.Parse(System.Configuration.ConfigurationManager.AppSettings["ScheduledTime"]);
                if (DateTime.Now > scheduledTime)
                {
                    //If Scheduled Time is passed set Schedule for the next day.
                    scheduledTime = scheduledTime.AddDays(1);
                }
            }

            if (mode.ToUpper() == "INTERVAL")
            {
                //Get the Interval in Minutes from AppSettings.
                int intervalMinutes = Convert.ToInt32(ConfigurationManager.AppSettings["IntervalMinutes"]);

                //Set the Scheduled Time by adding the Interval to Current Time.
                scheduledTime = DateTime.Now.AddMinutes(intervalMinutes);
                if (DateTime.Now > scheduledTime)
                {
                    //If Scheduled Time is passed set Schedule for the next Interval.
                    scheduledTime = scheduledTime.AddMinutes(intervalMinutes);
                }
            }

            TimeSpan timeSpan = scheduledTime.Subtract(DateTime.Now);
            string schedule = string.Format("{0} day(s) {1} hour(s) {2} minute(s) {3} seconds(s)", timeSpan.Days, timeSpan.Hours, timeSpan.Minutes, timeSpan.Seconds);

            this.WriteToFile("Simple Service scheduled to run after: " + schedule + " {0}");

            //Get the difference in Minutes between the Scheduled and Current Time.
            int dueTime = Convert.ToInt32(timeSpan.TotalMilliseconds);

            //Change the Timer's Due Time.
            Schedular.Change(dueTime, Timeout.Infinite);
        }
        catch (Exception ex)
        {
            WriteToFile("Simple Service Error on: {0} " + ex.Message + ex.StackTrace);

            //Stop the Windows Service.
            using (System.ServiceProcess.ServiceController serviceController = new System.ServiceProcess.ServiceController("SparkBirthDayGreeting"))
            {
                serviceController.Stop();
            }
        }
    }

    private void WriteToFile(string text)
    {
        string path = "C:\\ServiceLog.txt";
        using (StreamWriter writer = new StreamWriter(path, true))
        {
            writer.WriteLine(string.Format(text, DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss tt")));
            writer.Close();
        }
    }

I hope someone can help me with this. I am stuck :( Thank you.

kevin baroro
  • 29
  • 1
  • 6
  • 3
    You have put all the code that is useless for diagnosing the problem and removed the only relevant part... (`j_OnAuthenticate` is the only relevant part btw) – Jakub Dąbek Aug 31 '17 at 09:19
  • The exception's stack trace clearly points out where the error occurs. Unfortunatly, you removed exactly that part of your code from your question. The error message btw is pretty self-explaining. – René Vogt Aug 31 '17 at 09:20
  • sorry, i will edit it – kevin baroro Aug 31 '17 at 09:22
  • "//here's the part for sending messages to user, i remove the codes here because its to long **but i already test it in winforms and it is sending**" (emphasis by me) - What does that mean "you tested it in winforms" ? – Fildor Aug 31 '17 at 09:22
  • @Fildor i have a winform app to test if the sending of messages is working using the codes above except the ScheduleService method – kevin baroro Aug 31 '17 at 09:29

1 Answers1

2

The problem is that JabberClient's event is handled in j_OnAuthenticate and the timer's event is handled with it:

Schedular = new Timer(new TimerCallback(j_OnAuthenticate));
...
JabberClient j = new JabberClient();
j.OnAuthenticate += new bedrock.ObjectHandler(j_OnAuthenticate);

And in j_OnAuthenticate the first thing you do is cast the sender to JabberClient

private void j_OnAuthenticate(object sender)
{

   try
   {
       JabberClient j = (JabberClient)sender;
       ...
   }
   catch (Exception ex)
   {
       WriteToFile("Simple Service Error on: {0} " + ex.Message + ex.StackTrace);

       //Stop the Windows Service.
       using (System.ServiceProcess.ServiceController serviceController = new System.ServiceProcess.ServiceController("SparkBirthDayGreeting"))
       {
            serviceController.Stop();
       }
   }

The catch block handles and logs the exception.

You would have to change the code to do different things depending on the sender e.g.

if(sender is JabberClient)
{
    //do something
}
else if(sender is Timer)
{
    //do something else
}

Or give the timer a different callback function

Jakub Dąbek
  • 1,044
  • 1
  • 8
  • 17