This example demonstrates how two clients can share text through a Shared Dictionary using GroupLab.Networking.
Download the source code and executable |
Sections of this example:
1. Start a new C# Windows Application in Visual Studio and add a reference to GroupLab.Networking.dll. For detailed instructions click here.
2. Add a TextBox, two Labels and a Button to the Form like in the image below (make sure the button has the text caption 'Connect'; this is needed for the example to work properly).
3. Drag a Shared Dictionary and a Subscription from the toolbox to the form.
1. Connect / Disconnect: The button will be used to connect and disconnect from the shared dictionary, toggling between the two functions. When connecting, a Connect dialog will ask the user for a URL to connect to.
The URL format is: tcp://<computer name or IP>:<port # / dictionary name>
For example, "tcp://localhost:hello" will connect to a shared dictionary named hello on the the local machine.Two event handlers are added, SD_Opened and SD_Closed, to notify the application that it has successfully opened or closed a connection with the shared dictionary.
Add the following code to the button1_Click event:
//Connect / disconnect button is clicked
private void button1_Click(object sender, System.EventArgs e)
{
if(this.button1.Text == "Connect")
{
string url = "tcp://localhost:hello";
if(DialogResult.OK == GroupLab.Networking.UrlPrompt.Show(ref url))
{
this.SD.Url = url;
// we want be notified when we're connected or disconnected
this.SD.Opened += new EventHandler(SD_Opened);
this.SD.Closed += new EventHandler(SD_Closed);
this.SD.Open(); // start a server or client dictionary
this.button1.Enabled = false;
}
}
else
{
this.SD.Close(); // close the connection with the shared dictionary
}
}
2. SD Opened Event: This event will fire when the application connects to the shared dictionary. Our program will allow two instances of itself to share text. The first instance, the Server, will read messages from the path "/message1" in the shared dictionary and will write messages to the path "/message2". The second instance, the Client, will read messages in "/message2"; and write to "/message1". Each instance will create a subscription for the path that it reads from in order. When the content changes at the path, the instance will be notified.
Add the following code to the SD_Opened event:
// event handler for the connection opened event
private void SD_Opened(object sender,System.EventArgs args)
{
this.SD["/message1"] = "";
this.SD["/message2"] = "";
// make a subscription to /message so we get notified of incoming messages
this.subscription1.BeginInit();
this.subscription1.Dictionary = this.SD;
if(this.SD.ConnectionType == GroupLab.Networking.ConnectionType.Client)
this.subscription1.Pattern = "/message1";
else
this.subscription1.Pattern = "/message2";
// set the event handler in case a message arives
this.subscription1.Notified += new SubscriptionEventHandler(this.s_Notified);
this.subscription1.EndInit();
// let the user send messages to the server and see incoming messages
this.label1.Enabled = true;
this.textBox1.Enabled = true;
this.label2.Enabled = true;
this.button1.Text = "Disconnect";
this.button1.Enabled = true;
}
3. SD Closed Event: This event
will fire when the application disconnects from the shared dictionary. We
give the user the possibility to reconnect or to open a connection to a new
server by enabling the connect button and also provide a status message in one
of the labels.
Add the following code to the SD_Closed event:
// event handler for the connection closed event
private void SD_Closed(object sender,System.EventArgs args)
{
this.label1.Enabled = false; // hide unused labels, buttons and textboxes
this.textBox1.Enabled = false;
this.label2.Text = "Could not connect or connection closed"; // output the error message
this.label2.Enabled = true;
this.button1.Text = "Connect";
this.button1.Enabled = true;// show the connect button so the user can retry
}
4. OnClosing: If the user would like to close the application, the connection must be closed in an elegant fashion. For this, we create our own OnClosing override method here.
Create an OnClosing override method like below:
// method used to intercept OnClosing event
protected override void OnClosing(CancelEventArgs e)
{
// close connection to server or clients
this.SD.Close();
base.OnClosing (e);
}
5.
Sending Text: Text is sent in real time after each character is typed. When
the Enter key is pressed the TextBox will be emptied so that a new message can be typed. Depending on whether the instance is Client or Server, the message is placed in the appropriate
message box.
Add the following code to the textBox1_KeyPress event:
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if(e.KeyChar == '\r') // return pressed?
{
// put the message in the appropriate message box
if(this.SD.ConnectionType == GroupLab.Networking.ConnectionType.Client)
this.SD["/message2"] = this.textBox1.Text.ToString();
else
this.SD["/message1"] = this.textBox1.Text.ToString();
e.Handled = true;
this.textBox1.Text = "";// empty the textbox now
}
else
{
// place the partial message in the appropriate message box
if(this.SD.ConnectionType == GroupLab.Networking.ConnectionType.Client)
this.SD["/message2"] = this.textBox1.Text.ToString()+e.KeyChar.ToString();
else
this.SD["/message1"] = this.textBox1.Text.ToString()+e.KeyChar.ToString();
}
}
6.
Receiving Text:
When a message arrives (the dictionary's contents changes at a particular path) we will display it on screen. Depending on the type of instance (Client or Server) the appropriate message is retrieved.
Add the following code to the s_Notified event:
// event handler for incoming messages
private void s_Notified(object sender,GroupLab.Networking.SubscriptionEventArgs args)
{
// if a message arrives put it on screen
if(this.SD.ConnectionType == GroupLab.Networking.ConnectionType.Client)
this.label2.Text = this.SD.GetEntry("/message1").Value.ToString();
else
this.label2.Text = this.SD.GetEntry("/message2").Value.ToString();
}
1.Open an instance of the application. Hit "Connect".
2. In the Connect Dialog enter a hostname:port or leave the default one and press "Open"
3. Open one more instance and connect it to the SAME hostname:port. Now you can send messages back and forth between the two instances.