Ozeki VoIP SDK - Product Guide
Developers Guide
Building a webinar/web conferencing system using Silverlight webphone technology
Explanation
Prerequisities
![]() |
Download: | SLWebinar.zip |
This article is a brief introduction about web conferences and webinars with Silverlight webphone technology in relation with Ozeki VoIP SIP SDK. After reading through this page you will be fully familiar with all the essential terms concerning Silverlight web conferences and webinars and what you will need for creating your own solution using Ozeki VoIP SIP SDK.
Introduction
Silverlight webphone clients are capable for traditional VoIP calls but they can also be extended to be used for webinars or web conferences.
Figure 1 - Silverlight web conference solution
The term webinar is short for Web-based Seminar, a presentation, lecture, workshop or seminar that is transmitted over the web. Web conferencing refers to a service that allows conferencing events to be shared with remote locations. Both technologies use basically the same method of VoIP communication that can be implemented within a Silverlight webphone.
The following program code uses the background support of Ozeki VoIP SIP SDK, therefore you will need to download and install the SDK on your computer before starting to use the program code. You will also need to have Visual Studio 2010 or compatible IDE and .NET Framework installed on your system, as the program code below is written in C# language.
If you want to build a webinar or web conference solution in Silverlight, you can use the voice webphone example introduced on the page Web to web voice calls.
For an audio conference you need the connection support and the audio stream support of the Ozeki VoIP SIP SDK on both client and server-side. The only difference in the code will be that all the connected clients will send their audio stream to all other clients.
Server application
The server-side solution of this web conference example is a C# console application. It uses the background support of Ozeki VoIP SIP SDK by being derived from the Ozeki MediaGateway class. This means that the server overrides some basic methods and defines a few others for the client-client communication and it can run properly.
Code 1 shows the method that runs when the server starts. It is an overridden method from the MediaGateway class and basically just initializes the client list as a Dictionary.
public override void OnStart()
{
chatClients = new Dictionary<string, IClient>();
Console.WriteLine("Web2Web Gateway started.");
}
Code 1 - Starting the server
In Code 2 you can see the method that is invoked when a client connects to the server. It is also an overridden method that puts the newly connected client in the client list and writes some log information on the console.
public override void OnClientConnect(IClient client, object[] parameters)
{
Console.WriteLine( "{0} client connected to the server.",client.RemoteAddress);
if (!chatClients.ContainsKey(string.Format("client{0}", clientCounter++)))
{
chatClients.Add(string.Format("client{0}", clientCounter++), client);
}
}
Code 2 - Client connection
When a client is disconnected from the server, the method shown in Code 3 is invoked. This method only contains basic debug information as the client list is handled in another one.
public override void OnClientDisconnect(IClient client)
{
if (chatClients.ContainsValue(client))
{
Console.WriteLine("{0} client disconnected from the server.", client.RemoteAddress);
return;
}
}
Code 3 - Client disconnection
Code 4 contains the last overridden method from the MediaGateway class. This invokes when a client is ready for communication and starts to publish its media stream.
public override void OnStreamPublishStart(IClient client, IMediaStream mediaStream)
{
Console.WriteLine("client : {0} publish his stream : {1}",client.RemoteAddress,mediaStream.Name);
base.OnStreamPublishStart(client, mediaStream);
}
Code 4 - A client is ready for communication
The next methods will cover the client-client communication support in the serve-side application. In Code 5 you can see what happens when a client joins to the conference. As in the conference application all the joined clients can communicate with each other, all the other clients need to be notified about the newly joined client.
public void Join(IClient invokerClient, string name)
{
foreach (IClient client in chatClients.Values)
{
client.InvokeMethod("OnInCall");
}
}
Code 5 - A client joins to the conference
When a client wants to communicate with the others, it needs to start playing the others' streams. The method in Code 6 shows a solution for that on the server-side.
public void PlayRemoteStream(IClient invokerClient, string name)
{
foreach (IClient client in chatClients.Values)
{
if (client != invokerClient)
client.InvokeMethod("OnPlayRemoteStream", name);
}
}
Code 6 - Playing remote streams in the client
When a client wants to quit the conference, the method in Code 7 is called. This will notify all the clients about the client quit. Please note that quit does not necessarily mean disconnection from the server. When a client quitted from a conference, it can join again later.
public void Quit(IClient invokerClient, string name)
{
foreach (IClient client in chatClients.Values)
{
if (client != invokerClient)
client.InvokeMethod("OnCallStop", name);
}
}
Code 7 - A client quits from the conference
The server-side application is technically ready for receiving and handling client connections. Now, you need to implement the client side and the conference will be ready to use.
Client application
The client application is a Silverlight 4 solution, therefore you can use the Visual Studio for implementing it as well as the server application.
The client application uses the Ozeki Silverlight client support, therefore the project uses the SLClientSDK.dll as a reference. The client-side solution for this conference application is a simple one with audio support. The client can connect and disconnect to the server and join and quit the conversation (Figure 2).
Figure 2 - A simple Silverlight audio conference client
When a remote client joins to the conference, the communication needs a media sender and a media receiver to be established. In the case of a new remote client join, the client needs to assign a new stream receiver to the client through that it can receive the media data the remote client sends (Code 8).
public void OnPlayRemoteStream(string remoteparty)
{
MediaStreamReceiver streamReceiver = new MediaStreamReceiver(connection);
streamReceiver.StreamStateChanged += new EventHandler<GenericEventArgs<StreamState>>(streamReceiver_StreamStateChanged);
streamReceiver.AttachAudioPlayer(audioPlayer);
streamReceiver.Play(remoteparty);
streamReceivers.Add(remoteparty, streamReceiver);
}
Code 8 - Establishing a stream receiver for a newly joined remote client
When a remote client joins to the conference the method shown in Code 9 is invoked from the server-side. This method arranges the communication line between the remote client and the local one.
public void OnInCall()
{
txtboxInfo.Text = "Incall";
if (microphone == null)
{
microphone = Microphone.GetMicrophone();
streamSender = new MediaStreamSender(connection);
try
{
streamSender.AttachMicrophone(microphone);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
streamSender.StreamStateChanged += new EventHandler<GenericEventArgs<Ozeki.MediaGateway.SilverlightService.StreamState>>(streamSender_StreamStateChanged);
streamSender.Publish(clientID);
}
}
Code 9 - A client joined to the conference
The method in Code 10 is invoked from the server-side, when a client quitted the conference. In this case the line between the quitted client and the local one is destroyed.
public void OnCallStop(String remoteparty)
{
if (!streamReceivers.ContainsKey(remoteparty))
return;
MediaStreamReceiver streamReceiver = streamReceivers[remoteparty];
if (streamReceiver != null)
{
streamReceivers.Remove(remoteparty);
streamReceiver.StreamStateChanged -= streamReceiver_StreamStateChanged;
streamReceiver.Close();
}
}
Code 10 - A remote client exited the conference
The two buttons on the GUI is the Join and the Quit and both need a basic event handler for the Click event. Code 11 shows the one for the Join button. When a client joins a conference it invokes the Join server-side method and all the other clients will be informed about the join and the communication lines will be established between the newly joined client and the others.
private void btnJoin_Click(object sender, RoutedEventArgs e)
{
if (Microphone.GetPermissionToMicrophone())
{
ReleaseStreams();
callProcess = true;
connection.InvokeOnConnection("Join", clientID);
btnJoin.IsEnabled = false;
}
else
{
txtboxInfo.Text = "Please, add permission to access microphone.";
}
}
Code 11 - Pressing the Join button
In Code 12 you can see how the Click event of the Quit button is handled. When you press the Quit button, you end the communication, but do not disconnect from the server, therefore you can join the conversation again if you want.
private void btnQuit_Click(object sender, RoutedEventArgs e)
{
if (callProcess)
{
txtboxInfo.Text = "Online";
connection.InvokeOnConnection("Quit", txtBClientID.Text);
ReleaseStreams();
btnJoin.IsEnabled = true;
}
}
Code 12 - Quit button click event
Code 13 shows the event handler defined for the connection state change. The connection needs to be subscribed for this event in order to have the client work properly.
void connection_ConnectionStateChanged(object sender, GenericEventArgs<ConnectionState> e)
{
switch (e.Item)
{
case ConnectionState.Success:
txtboxInfo.Text = "Online";
audioPlayer = new AudioPlayer();
connection.Client = this;
break;
default:
InvokeGUIThread(() =>
{
txtboxInfo.Text = "Connection failed.";
btnQuit.IsEnabled = btnJoin.IsEnabled = false;
});
break;
}
}
Code 13 - Event handler for the connection
The stream sender and receivers also need some basic event handler methods, these can be found in Code 14.
void streamReceiver_StreamStateChanged(object sender, GenericEventArgs<StreamState> e)
{
//Debug.WriteLine("receiver play {0}", e.Item);
txtBDebug.Text = e.Item.ToString();
}
void streamSender_StreamStateChanged(object sender, GenericEventArgs<StreamState> e)
{
txtBDebug.Text = e.Item.ToString();
switch (e.Item)
{
case StreamState.PublishingSuccess:
connection.InvokeOnConnection("PlayRemoteStream");
break;
default:
//Debug.WriteLine(e.Item);
break;
}
}
Code 14 - Event handlers for the stream sender and receivers
Now both the client and the server are ready to use, you can start running the conference solution and you can also extend the possibilities of it if you want. If you need suggestions about extending a Silverlight client solution, please read How to add new functionality to a Silverlight client article.
This article introduced you the basic knowledge about Silverlight webinars and web conferences and showed how Ozeki VoIP SIP SDK can help you to fulfill your wishes about this topic. If you have read through this page carefully, you already have all the knowledge you need to start on your own solution.
As you are now familiar with all the terms concerning this topic, now it is time to take a step further and explore what other extraordinary solution Ozeki VoIP SIP SDK can provide to you.
If you have any questions or need assistance, please contact us at info@voip-sip-sdk.com
You can select a suitable Ozeki VoIP SIP SDK license for your project on licensing page
Related Pages
- Setup Ozeki VoIP SIP SDK effectively: Quick start guide
- Download Ozeki VoIP SIP SDK form the Ozeki VoIP SIP SDK download page
- You can find licensing information of Ozeki VoIP SIP SDK on Pricing and licensing information page
| Operating system: | Windows 8, Windows 7, Vista, 200x, XP |
| Development environment: | Visual Studio 2010 (Recommended), Visual Studio 2008, Visual Studio 2005 |
| Programming language: | C#.NET |
| Supported .NET framework: | .NET Framework 4.5, .NET Framework 4.0, .NET Framework 3.5 SP1 |
| Software development kit: | OZEKI VoIP SIP SDK (Download) |
| VoIP connection: | 1 SIP account |
| System memory: | 512 MB+ |
| Free disk space: | 100 MB+ |
INTERMEDIATE
VoIP technology walkthrough
Softphone development
Webphone development
Mobile development
Voice recording
GETTING AROUND
Sitemap
Search the manual
API documentation
FAQ
Appendix


