Sending a message from the server to a remote mobile device

Now that you have everything set up on both sides, it's time to create the support case application. As explained earlier in the overview, your server-side application will attempt to broadcast a new job to all connected mobile devices when it is created. For this purpose, you will be sending data from the server to a queue on each mobile device remotely.

Sending data to a remote queue

The code to send a message to a remote queue remains the same as the one you've written earlier for the local queue. The only difference is that your queue name now takes on the following format:

FormatName:DIRECT=TCP:192.168.0.128\private$\devicejobqueue

The preceding IP address shown is the target device's IP address on the network. If you want to refer to the device by name, you can also use the following format:

FormatName:DIRECT=OS:MYPOCKETPC\private$\devicejobqueue

For your testing purposes, you will most likely need the IP address of your mobile device. You can retrieve this information via the Windows Mobile Network Analyzer PowerToy tool, which can be downloaded from the Microsoft website at the following location:

http://www.microsoft.com/downloads/details.aspx?FamilyID=081c6401-49d4-4506-a03b-c41bc76c2f51&DisplayLang=en

This tool allows you to view useful network settings such as the IP address of the device (a rough equivalent of the ipconfig tool on the PC).

Sending data to a remote queue

Creating the server-side application

Create a new project, named SupportCaseServerApp, and add a new class to your project, named JobClass. This will be the business object that holds the details of each job.

using System;
public class JobClass
{
private string _JobID;
private string _JobSubject;
private DateTime _JobDate;
private string _JobRemarks;
private string _JobStatus;
public string JobStatus
{
get
{
return _JobStatus;
}
set
{
_JobStatus = value;
}
}
public string JobSubject
{
get
{
return _JobSubject;
}
set
{
_JobSubject = value;
}
}
public string JobRemarks
{
get
{
return _JobRemarks;
}
set
{
_JobRemarks = value;
}
}
public DateTime JobDate
{
get
{
return _JobDate;
}
set
{
_JobDate = value;
}
}
public string JobID
{
get
{
return _JobID;
}
set
{
_JobID = value;
}
}
}

Add a form to your project named AddNewJob. This form is the interface that allows you to modify the properties of a JobClass object.

Creating the server-side application

Write the following code in the code behind of this form:

using System;
using System.Windows.Forms;
public partial class AddNewJob
{
private JobClass _jobObj;
public JobClass Datasource
{
get
{
return _jobObj;
}
set
{
_jobObj = value;
}
}
public void OK_Button_Click(System.Object sender,
System.EventArgs e)
{
_jobObj.JobID = txtJobID.Text;
_jobObj.JobSubject = txtJobSubject.Text;
_jobObj.JobRemarks = txtJobRemarks.Text;
_jobObj.JobDate = datJobDate.Value;
_jobObj.JobStatus = "OPEN";
this.DialogResult = DialogResult.OK;
this.Close();
}
public void Cancel_Button_Click(System.Object sender,
System.EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
this.Close();
}
}

Now, add another form (named Main) to your project. This will be the main form of your application. Place a Datagrid, listbox, and two buttons on the form in the following fashion. Key in the IP address of your mobile device/emulator (retrieved earlier) in the Recipients listbox.

Creating the server-side application

In the click event of the Broadcast a new job button, you will need to launch the AddNewJob form, obtain the details of the new job from the user (and place it in the JobClass object), then broadcast it to the list of recipients.

//The list of jobs on the server
private List<JobClass> _Jobs = new List<JobClass>();
public void btnBroadCastNewJob_Click(System.Object sender, System.EventArgs e)
{
AddNewJob _frmAddNewJob = new AddNewJob();
JobClass _jobObject = new JobClass();
_frmAddNewJob.Datasource = _jobObject;
if (_frmAddNewJob.ShowDialog() == DialogResult.OK)
{
_Jobs.Add(_jobObject);
RefreshGrid();
//Broadcast this new job to all devices
SendJobToAllQueues(_jobObject);
}
_frmAddNewJob.Dispose();
_frmAddNewJob = null;
}
//Loop through all recipient IP addresses and sends the same //message for each one
private void SendJobToAllQueues(JobClass JobObject)
{
int _counter;
string _subject;
_subject = "Job ID : " + JobObject.JobID;
for (_counter = 0; _counter <= lbRecipients.Items.Count
1; _counter++)
{
SendMSMQMessage(_subject, JobObject,
lbRecipients.Items[_counter].ToString());
}
}
//Sends an MSMQ message containing a JobClass object to a //target IP address
message sending, server to remote mobile deviceserver-side application, creatingprivate void SendMSMQMessage(string Label, JobClass JobObject,
string TargetIP)
{
string _targetAddress = "FormatName:DIRECT=TCP:" + TargetIP
+ "\private$\devicejobqueue";
try
{
MessageQueue _mq = new MessageQueue(_targetAddress);
Message _m = new Message();
_m.Label = Label;
_m.Body = JobObject;
_mq.Send(_m);
_mq.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
//Refreshes the list of jobs displayed on the grid
private void RefreshGrid()
{
dgJobs.DataSource = null;
dgJobs.DataSource = _Jobs;
}

You can try running the preceding code at this point. Ensure that your mobile device/emulator is not connected to your PC. After creating a new job (via the Broadcast a new job button), you will be able to see the job appear in your Datagrid.

More importantly, you will notice that MSMQ has internally created an outgoing queue (via the Computer Management tool). You can see the details of the message by double-clicking on it in the right pane of the tool.

Creating the server-side application

When the mobile device reconnects with your PC, the message will be automatically sent out to the remote queue, and will be removed from this Outgoing messages area.

Creating the client-side application

Now you will need to create the client-side application so that you can retrieve these incoming messages from the devicejobqueue queue on the mobile device. Add the same JobClass class to the same SupportCase smart application project you've created earlier in this chapter.

Add a new form named JobPool to your project. This form will contain a Datagrid control and some menu options. The following is the layout:

Creating the client-side application

Upon loading, this form should check to see if the private$devicejobqueue queue is present, and if not, create it. It should then check to see if there are any messages in this queue. You can do this via the MessageQueue.GetAllMessages function, which returns an array of Message objects found in the queue. Take note that this function will not remove the message from the queue. To remove it, you must explicitly call the MessageQueue.ReceiveByID method. Let's see how it all looks in the following code:

//The list of jobs retrieved from the server
message sending, server to remote mobile deviceclient-side application, creatingprivate List<JobClass> _Jobs = new List<JobClass>();
//The currently selected row in the Datagrid
private int _currentRow = - 1;
public void JobPool_Load(object sender, System.EventArgs e)
{
//Initialize MSMQ service on the device
if (Generic.InitializeMSMQ() == false)
{
MessageBox.Show("Could not initialize MSMQ");
return;
}
//Creates the private$devicejobqueue queue if its not
//present
CreateJobQueue();
//Reads from the Job Queue
ReadFromJobQueue();
}
//Creates the private$devicejobqueue queue if it does not //exist
private void CreateJobQueue()
{
string _queueName = ".\private$\devicejobqueue";
try
{
if (! MessageQueue.Exists(_queueName))
{
MessageQueue.Create(_queueName);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
//Reads any messages (if available) from the queue. Notice //that you need to inform MSMQ that the payload of the message //is no longer a String object, but a JobClass object
private void ReadFromJobQueue()
{
string _queueName = ".\private$\devicejobqueue";
try
{
MessageQueue _mq = new MessageQueue(_queueName);
_mq.Formatter = new XmlMessageFormatter(new Type[]
{typeof(@JobClass)});
//Retrieve all messages from the queue
Message[] _messages = _mq.GetAllMessages();
int _counter;
for (_counter = 0; _counter <= (_messages.Length - 1);
_counter++)
{
Message _currentMsg = _messages[_counter];
JobClass _jobObject = (JobClass)(_currentMsg.Body);
_Jobs.Add(_jobObject);
//You must do a Receive for each message to remove it
//from the queue
_mq.ReceiveById(_currentMsg.Id);
}
RefreshGrid();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
//Refreshes the grid display with the latest list of jobs
private void RefreshGrid()
{
dgJobs.DataSource = null;
dgJobs.DataSource = _Jobs;
}
//store the index of the currently selected row
public void dgJobs_CurrentCellChanged(object sender,
System.EventArgs e)
{
_currentRow = dgJobs.CurrentCell.RowNumber;
}
//Refreshes the grid by reading again from the message queue
public void mnuRefresh_Click(System.Object sender, System.EventArgs e)
{
ReadFromJobQueue();
}

You can try running your application at this point. Ensure that your mobile device/emulator is connected to your PC. Start both the server-side and client-side applications. Create a new job at the server side. After you have done that, click on the Refresh menu in the client-side application on your mobile device. You will be able to see the newly created job show up in the data grid.

Creating the client-side application
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.131.72