Summary
This is a simple example showing how a Silverlight application can receive messages from a standalone desktop application.
Introduction
The article is a free continuation of How to Send Message to Desktop Application where the Silverlight application sends a text message to the desktop application. Now I would like to show how the Silverlight application can receive text messages from the desktop application using TCP connection. (Actually, the example below shows the bidirectional communication between the Silverlight application and the desktop application.)
The implementation uses Eneter Messaging Framework
. (The framework is free and can be downloaded from http://www.eneter.net/. The online help for developers can be found at http://www.eneter.net/OnlineHelp/EneterMessagingFramework/Index.html.)
As mentioned in the previous article, the Silverlight communication via TCP has the following specifics:
- The Silverlight framework requires the policy server.
- The Silverlight framework allows only ports of range 4502 - 4532.
In addition:
- The Silverlight application cannot be a TCP listener.
Therefore, if the Silverlight application wants to receive messages, it must open TCP connection to the listening desktop application and receive response messages.
Eneter Messaging Framework
supports these specifics. It contains the policy server, wraps the low-level socket communication and allows the request-response communication via duplex channels.
The implementation is very simple.
Desktop Application
The desktop application is responsible for starting the policy server, for receiving messages and for sending messages back to the Silverlight application.
using System;
using System.Windows.Forms;
using Eneter.Messaging.EndPoints.StringMessages;
using Eneter.Messaging.MessagingSystems.MessagingSystemBase;
using Eneter.Messaging.MessagingSystems.TcpMessagingSystem;
namespace DesktopApplication
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
myPolicyServer.StartPolicyServer();
IDuplexStringMessagesFactory aStringMessagesFactory =
new DuplexStringMessagesFactory();
myMessageReceiver = aStringMessagesFactory.CreateDuplexStringMessageReceiver();
myMessageReceiver.ResponseReceiverConnected += ClientConnected;
myMessageReceiver.ResponseReceiverDisconnected += ClientDisconnected;
myMessageReceiver.RequestReceived += MessageReceived;
IMessagingSystemFactory aMessaging = new TcpMessagingSystemFactory();
IDuplexInputChannel aDuplexInputChannel =
aMessaging.CreateDuplexInputChannel("127.0.0.1:4502");
myMessageReceiver.AttachDuplexInputChannel(aDuplexInputChannel);
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
myMessageReceiver.DetachDuplexInputChannel();
myPolicyServer.StopPolicyServer();
}
private void MessageReceived(object sender, StringRequestReceivedEventArgs e)
{
InvokeInUIThread(() =>
{
ReceivedMessageTextBox.Text = e.RequestMessage;
});
}
private void ClientConnected(object sender, ResponseReceiverEventArgs e)
{
InvokeInUIThread(() =>
{
ConnectedClientsListBox.Items.Add(e.ResponseReceiverId);
});
}
private void ClientDisconnected(object sender, ResponseReceiverEventArgs e)
{
InvokeInUIThread(() =>
{
ConnectedClientsListBox.Items.Remove(e.ResponseReceiverId);
});
}
private void SendButton_Click(object sender, EventArgs e)
{
foreach (string aClientId in ConnectedClientsListBox.Items)
{
myMessageReceiver.SendResponseMessage(aClientId, MessageTextBox.Text);
}
}
private void InvokeInUIThread(Action uiMethod)
{
if (InvokeRequired)
{
Invoke(uiMethod);
}
else
{
uiMethod();
}
}
private TcpPolicyServer myPolicyServer = new TcpPolicyServer();
private IDuplexStringMessageReceiver myMessageReceiver;
}
}
Silverlight Application
The Silverlight application is responsible for sending text messages and for receiving response messages. (The communication with the policy server is invoked automatically by Silverlight before the connection is established.)
using System.Windows;
using System.Windows.Controls;
using Eneter.Messaging.EndPoints.StringMessages;
using Eneter.Messaging.MessagingSystems.MessagingSystemBase;
using Eneter.Messaging.MessagingSystems.TcpMessagingSystem;
namespace SilverlightApplication
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
IDuplexStringMessagesFactory aStringMessagesFactory =
new DuplexStringMessagesFactory();
myMessageSender = aStringMessagesFactory.CreateDuplexStringMessageSender();
myMessageSender.ResponseReceived += MessageReceived;
IMessagingSystemFactory aMessaging = new TcpMessagingSystemFactory();
IDuplexOutputChannel aDuplexOutputChannel =
aMessaging.CreateDuplexOutputChannel("127.0.0.1:4502");
myMessageSender.AttachDuplexOutputChannel(aDuplexOutputChannel);
}
private void MessageReceived(object sender, StringResponseReceivedEventArgs e)
{
textBox2.Text = e.ResponseMessage;
}
private void SendMessage_Click(object sender, RoutedEventArgs e)
{
myMessageSender.SendMessage(textBox1.Text);
}
private IDuplexStringMessageSender myMessageSender;
}
}
Communicating Applications
The picture below shows the communicating applications. The desktop applications sent the message 'Hello Silverlight' that was received by both Silverlight clients. The first Silverlight application sent the message 'Hi Desktop' that was received by the desktop application.
I hope you found the article useful. Any feedback is welcome.
CodeProject