Click here to Skip to main content
13,301,619 members (74,359 online)
Click here to Skip to main content
Add your own
alternative version


70 bookmarked
Posted 17 Dec 2009

Web-Cam SecureChat

, 12 Mar 2010
Rate this:
Please Sign up or sign in to vote.
This article will explain how to create a simple chat program using this remoting technology, which supports web-cam and sending files.


This article explains how to create a simple Secure Chat with WebCam support using Pfz.Remoting.


I've already written some articles about communication, in special Pfz.Remoting and Creating an Asymmetric/Symmetric Secure Stream without SSL, which is in fact part of the remoting DLL. This article will explain how to create a simple chat program using this remoting technology, which supports web-cam and sending files.

I then wanted to create an article explaining how to create a simple multi-user chat but, when I saw AForge and its video capture capabilities, I wanted to create a chat program with web-cam support. In the end, I created a very basic chat, almost without exception handling, but the important part is that it supports web-cam and audio capture with multiple clients.

The Principle

The principle is very simple. Data can be lost. This is not a very big problem for video, it can be for audio, but it is not possible to simple avoid it.

For example, the program receiving the web-cam frames can receive 10 frames, but the client which receives it can only be able to receive 5. Intermediate frames must be lost.

Also, in the architecture I made for this sample, everything goes throught the server. So, the web-cam owner receives 10 frames. The server receives only seven frames. And it can distribute the frames it receives among its clients, which one can be able to receive them all (the 7), another can receive only 3 and another can receive only 5. So, how do we distribute the data?

ActualValueEnumerator and EnumeratorDistributor

I created two main classes that help the distribution of data that "can be lost". The ActualValueEnumerator is a class that "enumerates" throught its values, and waits for new values when all values are already read. But, if two or more values appears before the "enumerator" is able to read them, only the last one (the actual) remains. That's why I called the class ActualValueEnumerator.

In the first version of the article I made the WebCamEnumerator class using ManualResetEvent, but it was ugly. Now it is very simple. So, look at the code:

using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using AForge.Video;
using AForge.Video.DirectShow;
using Pfz.Collections;
namespace SecureChat.Client
	public sealed class WebCamEnumerator:
		private volatile VideoCaptureDevice fDevice;
		public WebCamEnumerator(string monikerString)
			var device = new VideoCaptureDevice(monikerString);
			fDevice = device;
			device.DesiredFrameSize = new Size(160, 120);
			device.NewFrame += p_NewFrame;
		protected override void Dispose(bool disposing)
			var device = fDevice;
			if (device != null)
				fDevice = null;
		private void p_NewFrame(object sender, NewFrameEventArgs eventArgs)
			var image = (Bitmap)eventArgs.Frame;
			using(var stream = new MemoryStream())
				image.Save(stream, ImageFormat.Jpeg);
				ActualValue = stream.ToArray();

The important things here are: In the constructor, it starts the web-cam and sets the NewFrame event. In the dispose it stops the web-cam. And, in the new frame, it generates the byte array of the image and sets the ActualValue to such bytes. I convert the image to bytes so the server does not need to know how to process graphics... it only receives bytes and distribute bytes to the clients. It may not be "visible" in the first moment, but as this class inherits from ActualValueEnumerator, it can be used in a foreach (must use Pfz.Extensions.FastEnumeratorExtensions and the AsEnumerable method) and it already deals with the possibility of loosing frames.

The server is always a bit more complicated, and I must admit I made it hard. I will try to make it easier and re-update the article, but to help the server be less-complicated I created the EnumeratorDistributor class. Similar to the ActualValueEnumerator, it allows values to be lost. But, instead of being an enumerator itself, it must be used over another enumerator, and each client gets its own enumerator which allows the frames to be lost. So, different speed clients will receive different number of values. So, to use it, the server receives the enumerator from one client (for example, the server receives the WebCamEnumerator from one client), and creates an EnumeratorDistributor over it. Each client that is now interested in such web-cam will get a new enumerator (throught the CreateClient method), which will always receive the last frame from such base enumerator. If frames are to be skipped, they will be.

The project As I said earlier, the server is still more complicated than it needs to be, but the basic idea here is: There is the Common library, in which the classes and interfaces used by both client and server are present. Note that any method the client needs to call in the server or that the client must call in the client must be done via interfaces, which are here.

There is the server project, which supports the client connections and implements the server part, so it is responsible for telling all other clients when a new one connects and to find another client, requests its web-cam or sound-capture device and returning the appropriate enumerator when someone asks for the web-cam or sound from another client. And the client project. It is "simpler" than the server as it does not need to deals with many clients, but it must be able to capture video and sound and must be able to play them. Actually, when one client wants the video or sound from another one, it must request the Server for such information, which will be returned as a IFastEnumerator. The IFastEnumerator is faster than a custom enumerator over the TCP/IP, as instead of first calling "MoveNext" (which sends and receives information) and then Current (which agains sends and receives information) it uses only GetNext, which can return null to tell there are no more values. Well, I hope this little explanation and the source-code is enough for anyone trying to create an application which remote web-cam or sound-capture support.

The Samples

If you want to try the samples, you must:

  • Run the server in command prompt with any parameter (I use the parameter DEBUG), or install it with installutil and then start the service.
  • Run a local client normally, if you want.
  • Change the app.config to point to the server host and run a client from another computer. Having more clients is better.
  • Actually the user-name is taken from the user logged in the system, and this user can't log many times in the same server. Someone must start his own web-cam (be it a fake web-cam or a real one). Then, the others can ask to start that clients' web-cam.

The program supports simple chat and file transfer (drag-and-drop a file over a user name). Dragging a file to your own name will do a really wasteful work of sending the file to the server and then sending the file back to the client.


  • 17th December, 2009: Initial post
  • 11th January, 2010: New version of webcam source - This version has corrected a bug in the server, where a client with two webcams will only send the first one for the clients, not importing which one the client asked. Also, it has corrected a bug when sending files with more than 2GB.
  • 12th March, 2010: Added very basic support to sound capture.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Paulo Zemek
Engineer YouTube
United States United States
I started to program computers when I was 11 years old, as a hobbyist, programming in AMOS Basic and Blitz Basic for Amiga.
At 12 I had my first try with assembler, but it was too difficult at the time. Then, in the same year, I learned C and, after learning C, I was finally able to learn assembler (for Motorola 680x0).
Not sure, but probably between 12 and 13, I started to learn C++. I always programmed "in an object oriented way", but using function pointers instead of virtual methods.

At 15 I started to learn Pascal at school and to use Delphi. At 16 I started my first internship (using Delphi). At 18 I started to work professionally using C++ and since then I've developed my programming skills as a professional developer in C++ and C#, generally creating libraries that help other developers do their work easier, faster and with less errors.

Want more info or simply want to contact me?
Take a look at:
Or e-mail me at:

Codeproject MVP 2012, 2015 & 2016
Microsoft MVP 2013-2014 (now I work at Microsoft so I can't be a Microsoft MVP anymore)

You may also be interested in...

Comments and Discussions

QuestionEcho Cancellation Pin
daknu0927-Jan-13 13:57
memberdaknu0927-Jan-13 13:57 
QuestionAccessing Remote server Webcam From the Local Machine? Pin
Pawan Kiran28-Aug-12 5:57
memberPawan Kiran28-Aug-12 5:57 
AnswerRe: Accessing Remote server Webcam From the Local Machine? Pin
Paulo Zemek28-Aug-12 7:24
mvpPaulo Zemek28-Aug-12 7:24 
GeneralRe: Accessing Remote server Webcam From the Local Machine? Pin
Pawan Kiran25-Sep-12 1:09
memberPawan Kiran25-Sep-12 1:09 
GeneralRe: Accessing Remote server Webcam From the Local Machine? Pin
Paulo Zemek25-Sep-12 5:14
mvpPaulo Zemek25-Sep-12 5:14 
GeneralMy vote of 5 Pin
Member 36979113-Jan-12 14:43
memberMember 36979113-Jan-12 14:43 
GeneralRe: My vote of 5 Pin
Paulo Zemek6-Jan-12 8:48
memberPaulo Zemek6-Jan-12 8:48 
Questiontwo video session online and message cannot be sent Pin
SARP CEVİK4-Jul-11 10:54
memberSARP CEVİK4-Jul-11 10:54 
AnswerRe: two video session online and message cannot be sent Pin
Paulo Zemek5-Jul-11 3:31
memberPaulo Zemek5-Jul-11 3:31 
GeneralRe: two video session online and message cannot be sent Pin
SARP CEVİK5-Jul-11 18:13
memberSARP CEVİK5-Jul-11 18:13 
i can help you to simulate it and i guess it is not flashing not only trying to send empty string you cannot even type it. I guess it could be handled via using threads in key input in order to improve responsiveness. And i looked the code was removed to build multi chatroom logic if you have an explanation or code sample or one two three step guide for that ? Cos i am trying to enable smileys for the reciever and sender part and also the kick ban features and some right management or let say permission check to give users different roles just like room operator,system operator something like that
GeneralRe: two video session online and message cannot be sent Pin
Paulo Zemek6-Jul-11 11:56
memberPaulo Zemek6-Jul-11 11:56 
GeneralRe: two video session online and message cannot be sent Pin
SARP CEVİK7-Jul-11 8:42
memberSARP CEVİK7-Jul-11 8:42 
GeneralRe: two video session online and message cannot be sent Pin
Paulo Zemek7-Jul-11 8:54
memberPaulo Zemek7-Jul-11 8:54 
GeneralRe: two video session online and message cannot be sent Pin
SARP CEVİK9-Jul-11 11:25
memberSARP CEVİK9-Jul-11 11:25 
Generalmultiple rooms [modified] Pin
hamada el3ashe29-Nov-10 14:26
memberhamada el3ashe29-Nov-10 14:26 
QuestionSending a Message after Receiving Pin
dythim12-Sep-10 15:16
memberdythim12-Sep-10 15:16 
AnswerRe: Sending a Message after Receiving Pin
Paulo Zemek13-Sep-10 16:02
memberPaulo Zemek13-Sep-10 16:02 
GeneralRe: Sending a Message after Receiving Pin
dythim13-Sep-10 18:10
memberdythim13-Sep-10 18:10 
GeneralServer go out Pin
cybertronick24-Apr-10 7:25
membercybertronick24-Apr-10 7:25 
GeneralRe: Server go out Pin
Paulo Zemek26-Apr-10 11:40
memberPaulo Zemek26-Apr-10 11:40 
GeneralRe: Server go out Pin
cybertronick9-May-10 4:41
membercybertronick9-May-10 4:41 
Generalthank you Paulo Zemek ! Pin
Member 408024115-Mar-10 17:25
memberMember 408024115-Mar-10 17:25 
QuestionIs a web version of this application possible? Pin
xyzhee2-Mar-10 6:56
memberxyzhee2-Mar-10 6:56 
AnswerRe: Is a web version of this application possible? Pin
Paulo Zemek2-Mar-10 13:04
memberPaulo Zemek2-Mar-10 13:04 
GeneralRe: Is a web version of this application possible? Pin
defwebserver6-Mar-10 7:16
memberdefwebserver6-Mar-10 7:16 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.171207.1 | Last Updated 12 Mar 2010
Article Copyright 2009 by Paulo Zemek
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid