Alright, so now that we know what a simple messenger looks like with WCF callbacks, what does it take to put one together in Silverlight? For starters, Silverlight does not have the same capabilities as the full WCF framework. WCF callbacks in Silverlight must be done through HTTP Polling and therefore we don’t really have a truly bi-directional environment. Instead, we must manually setup the message asynchronous message architecture with a few special classes in a new System.ServiceModel.PollingDuplex library. It’s really not as scary as it seems, but it is somewhat confusing. Nevertheless, this article takes you through all that, plus how to work with Json serialization and JQuery to create an instant messenger for the web in Silverlight.

The GUI
I thought as a change in pace we will be working with XHTML and JQuery for our user interface. For this GUI, I thought it would be nice to have a similar chat bar to that of Facebook. We know that the bar will be docked to the bottom, stretch the width of the browser and contain the important chat boxes docked to the right of the bar. Before the chat is available, it should require us to log in with a nickname.
This “plexbar” which thus far includes the title, the nickname textbox, connect button and welcome text, in HTML looks like this:
<div id=”plexbar”>
<div id=”container”>
<div id=”title”>
<img alt=”" src=”Images/Universe.png” height=”20″ width=”20″
style=”float: left; padding-right: 4px;” />Post Galaxy
</div>
<input id=”nicknameTextBox” type=”text” class=”nickname” value=”Type a nickname” />
<input id=”connectButton” type=”button” value=”connect” class=”connect” />
— chat boxes go here –
<div id=”login”>Welcome</div>
</div>
</div>
A few CSS rules will dock the bar to the bottom, stretch it to the width of the browser and give it style:
body { overflow: hidden; width: 100%; margin: 0; background-color: #131313; }
#plexbar {
width: 100%; position: fixed;
bottom: 0px; text-align: right;
min-width: 450px;
}
#container {
height: 26px; margin-left: 15px;
margin-right: 15px; border-top: solid 1px #424242;
background-color: #323232; border-right: solid 1px #424242;
border-left: solid 1px #424242;
}
#title {
float: left; color: #AFAFAF;
padding-top: 2px; padding-left: 5px;
font-weight: bold; font-family: Trebuchet MS;
font-size: 10pt; cursor: default;
}
.nickname {
float: left; margin: 0px 0px 0px 20px;
font-size: 9pt; height: 23px;
padding: 3px 4px 0px 6px; width: 110px;
text-align: left; font-family: Trebuchet MS;
background-color: #424242; color: #AFAFAF;
border-left: solid 1px #878787; border-right: solid 1px #878787;
border-bottom-style: none; border-top-style: none;
font-style: italic;
}
.connect {
border: solid 1px #878787; background-color: #424242;
height: 100%; padding: 3px 10px 3px 10px;
color: #AFAFAF; margin-left: 10px;
outline-style: none; float: left;
}
#login { color: #AFAFAF; margin-right: 10px; font-style: italic; }
The — chat boxes — section will act as a button, initially it will be hidden. The html looks as follows:
<div id=”chatbar”>
<div id=”usersButton” class=”button”>
<div class=”usersTitle”>
<img alt=”" src=”Images/Dot.png” height=”12″ width=”12″ class=”titleImage” />
Online Friends <strong id=”numberOfOnline”>(loading)</strong>
</div>
</div>
</div>
The CSS that defines this HTML is show below:
#chatbar { height: 26px; float: right; margin-right: 10px; }
.button {
width: auto; height: 100%;
cursor: pointer; text-align: center;
margin: 0 2px 0 2px; display: inline-block;
border-left: solid 1px #565656; border-right: solid 1px #565656;
color: #AFAFAF; font-size: 9pt;
padding-top: 3px; padding-right: 13px;
padding-left: 12px; font-family: Trebuchet MS;
background-color: #323232;
}
.button:hover { background-color: #444444; color: #FFFFFF; }
.usersTitle strong { font-weight: bolder; font-size: 1.01em; }
.titleImage { position: relative; top: 1px; }
Of course, we will need a place for showing a list of users, I have setup a simple container. In order to get the vertical stack that we want, I am using a table where all the user items will be the subsequent rows.
<div id=”box”>
<div id=”plexbox”>
<table id=”listOUsers” style=”margin:0;padding:0;”>
</table>
</div>
</div>
JQuery
JQuery is a javascript library that handles all the nitty gritty parts of animation, DOM manipulation, JSON, AJAX and all sort of neat effects. The first thing to be aware of with JQuery is that the $ (dollar sign) is what you base almost all of your code from. The $ acts as a selector just like in scripting languages like PHP.
$(“#box”).fadeIn(“slow”)
There is a ton of really helpful documentation on JQuery’s site and I recommend looking through it, try a few of your own solutions out. Moving on, you can add the following scripts to the headers to use JQuery. The second script is where all of our JQuery code will go.
<script type=”text/javascript” src=”http://code.jquery.com/jquery-latest.js”></script>
<script type=”text/javascript” src=”DefaultBehavior.js”></script>
When the document first loads we need to hide a few visible items and show a few invisible ones.
$(document).ready(function() {
$(“#box”).hide();
$(“#chatbar”).hide();
$(“#login”).show();
…
…
});
In addition to the initial display changes, we need to wire to the textbox’s focus and blur events (when the textbox is focused and unfocused). Here I am simply changing the text based on whether or not there is any typed content. By doing this, it adds a watermark like effect to the textbox.
$(“#nicknameTextBox”).blur(function() {
if($(“#nicknameTextBox”).val() == “”) {
$(“#nicknameTextBox”).val(“Type a nickname”);
}
});
$(“#nicknameTextBox”).focus(function() {
if($(“#nicknameTextBox”).val() == “Type a nickname”) {
$(“#nicknameTextBox”).val(“”);
}
});
However, the two most important events to watch are a) when the user clicks the usersButton (that way we can show/hide the online friends) and b) when the user clicks the connect button.
$(“#usersButton”).click(function() {
$(“#box”).slideToggle(“fast”);
});
$(“#connectButton”).click(function() {
if($(“#connectButton”).val() == “connect”) {
if($(“#nicknameTextBox”).val() != “Type a nickname”) {
connect();
}
}
else {
leave();
}
});
Before, I move into the code for connect and leave, we are going to first get established with making javascript calls to Silverlight C# code and vice-versa. Add a Silverlight application and place a Silverlight control in the default.aspx page (along with the other html content).
<asp:ScriptManager ID=”scriptManager” runat=”server”></asp:ScriptManager>
<asp:Silverlight ID=”Xaml1″ runat=”server” Source=”~/ClientBin/Plex.xap”
MinimumVersion=”2.0.30523″ Width=”0″ Height=”0″ />
You will need to add the register prefix at the top of the page just like this:
<%@ Register Assembly=”System.Web.Silverlight”
Namespace=”System.Web.UI.SilverlightControls” TagPrefix=”asp” %>
Now that we have that setup, we will move into setting up the link between the Javascript and Silverlight code.
Silverlight Scriptables
Setting up scriptable content is as easy as its name implies. Simply create a class, and add the ScriptableType class attribute. Then, any method that you want to be callable from javascript should have a ScriptableMember method attribute. That’s it!
[ScriptableType]
public class ScriptCode
{
[ScriptableMember]
public void Connect(string name)
{
// connect code
}
}
The only thing left to let our javascript be able to see it is using the HtmlPage.RegisterScriptableObject method when the App loads.
private void Application_Startup(object sender, StartupEventArgs e)
{
this.RootVisual = new Page();
code = new ScriptCode();
HtmlPage.RegisterScriptableObject(“PlexScriptApp”, code);
}
Now we can call this code from our clientside javascript functions.
function connect() {
$(“#login”).show();
$(“#login”).val(“Logging in…”);
$(“#connectButton”).fadeOut(“slow”);
var slCtrl = document.getElementById(“Xaml1″);
slCtrl.Content.PlexScriptApp.Connect($(“#nicknameTextBox”).val());
}
function leave() {
$(“#chatbar”).fadeOut(“fast”);
$(“#login”).fadeIn(“slow”);
$(“#connectButton”).val(“connect”);
var slCtrl = document.getElementById(“Xaml1″);
slCtrl.Content.PlexScriptApp.Leave();
}
Before we get too crazy, we need to actually have some sort of server communication setup to do all this.
WCF Duplex Communication
If you remember from the previous article setting up a Duplex WCF service was as simple as adding a CallbackContract to the the ServiceContract of interest. We have this same capability with Silverlight 2 Beta 2, however it is somewhat limited in power. In Silverlight 2 Beta 2, we have to setup a polling binding where the client will using HttpPolling to see if there are any messages that are waiting. In light of this, much (if not all) of the setup is manual and without the traditional proxy layer that we’re used to.
Because of this manual process, we have to send Messages through a lower SOAP11 based class, Message, in the System.ServiceModel.Channels namespace. The Message class specifies the action, the MessageVersion and the content being sent with every request or response.
[ServiceContract(Namespace = "Silverlight", CallbackContract = typeof(IPlexChatCallback))]
public interface IPlexChatService
{
[OperationContract(IsOneWay = true)]
void Join(Message message);
[OperationContract(IsOneWay = true)]
void Leave(Message message);
[OperationContract(IsOneWay = true)]
void PostMessage(Message message);
}
[ServiceContract]
public interface IPlexChatCallback
{
[OperationContract(IsOneWay = true)]
void UserJoined(Message message);
[OperationContract(IsOneWay = true)]
void UserLeft(Message message);
[OperationContract(IsOneWay = true)]
void Users(Message message);
[OperationContract(IsOneWay = true)]
void NewMessage(Message message);
}
Of course, this doesn’t look it provides a whole lot of sustenance. That’s why we need to define a few data contracts.
[DataContract]
public class User
{
[DataMember]
public string ID { get; set; }
[DataMember]
public string Name { get; set; }
}
[DataContract]
public class ChatMessage
{
[DataMember]
public string FromID { get; set; }
[DataMember]
public string ToID { get; set; }
[DataMember]
public string Body { get; set; }
}
To use these types, we need to use a work with the Message object and choose a Serialization or Deserialization scheme to write and read data. For this article, since we’re working directly with the DOM using JQuery, we might as well work directly with Json. Json serialization is done via the DataContractJsonSerializer and the JsonReaderWriterFactory located in the System.Runtime.Serialization.Json namespace. You can obtain this by adding the System.ServiceModel.Web library to your project.
Read more: silverlightshow
Related Stuff
-
MooV: Using cutting edge Video phones and Software Video Phones - coupling all that with VoIP and empowering the disabled.
-
Moo Telecom: VoIP communications made easy - Ring anyway with the fun and ease of using a normal phone
-
TagR:Mobile Social Network with Real Time Locations Based services, and Ambience Intelligence, VoiP, IM, Skype, Googletalk, Mapping, Flickr, Events, Calendaring, Scheduling, SecondLife Support
-
ClearSMS : ClearSMS is a Web-based application that lets you send bulk SMS messages to your customers, contacts, or just about anyone.
-
Jajah:jah is a VoIP (Voice over IP) provider, founded by Austrians Roman Scharf and Daniel Mattes in 2005[1]. The Jajah headquarters are located in Mountain View, CA, USA, and Luxembourg. Jajah maintains a development centre in Israel.
-
Skype: It’s free to download and free to call other people on Skype. Skype the number one voice over ip software
- PrivatePhone: a free local phone number with voicemail and messages you can check online or from any phone.
Be the first ... |Add your comment.
Your Comment ...
Name (required)
Email (required, hidden)
Website
