Sei sulla pagina 1di 46

Mail server

TCP/IP Chat Application Using C#


By xironix | 30 Jan 2006
This is a LAN chat application with TCP/IP socket programming technology in C#. This
application is a multi thread network application and works in a non-blocking way. Public and
private chat is also implemented in this code.
Top of Form
/w EPDw UKMTAy

• Download source files - 345 Kb


• Download demo - 298 Kb

Introduction
The power of network programming in .NET platform cannot be denied. Socket programming is
the core of network programming in Windows and Linux, and today the .NET platform
implements it in a powerful way. In this article, we will see the basics of socket programming in
C#. To be precise, I have created a command client and a command server, to communicate
between a remote server and up to 200 clients and send the specified commands to them. As a
sample application, I have created a chat client application that uses this command client/server
to implement chat functions. Before I start explaining my application, let me give you a small
introduction on network programming and sockets taken from the book 'C# network
programming', written by Richard Blum.
Sockets
In socket-based network programming, you don't directly access the network interface device to
send and receive packets. Instead, an intermediary connector is created to handle the
programming interface to the network. Assume that a socket is a connector that connects your
application to a network interface of your computer. For sending and receiving data to and from
the network you should call the socket's methods.
Socket programming in C#
The 'System.Net.Sockets' namespace contains the classes that provide the actual .NET
interface to the low-level Winsock APIs. In network programming, apart from which
programming language to use there are some common concepts like the IP address and port. IP
address is a unique identifier of a computer on a network and port is like a gate through which
applications communicate with each other. In brief, when we want to communicate with a
remote computer or a device over the network, we should know its IP address. Then, we must
open a gate (Port) to that IP and then send and receive the required data.
IP addresses in C#
One of the biggest advantages you will notice in the .NET network library is the way IP
address/port pairs are handled. It is a fairly straightforward process that presents a welcome
improvement over the old, confusing UNIX way. .NET defines two classes in the System.Net
namespace to handle various types of IP address information:
• IPAddress
• IPEndPoint

IPAddress
An IPAddress object is used to represent a single IP address. This value is then used in various
socket methods to represent the IP address. The default constructor for IPAddress is as follows:
Collapse

public IPAddress(long address)


The default constructor takes a long value and converts it to an IPAddress value. In practice, the
default is almost never used. Instead, several methods in the IPAddress class can be used to
create and manipulate IP addresses. The Parse() method is often used to create IPAddress
instances:
Collapse

IPAddress newaddress = IPAddress.Parse("192.168.1.1");

IPEndPoint
The .NET Framework uses the IPEndPoint object to represent a specific IP address/port
combination. An IPEndPoint object is used when binding sockets to local addresses, or when
connecting sockets to remote addresses.
Connection-oriented and connectionless sockets
The world of IP connectivity revolves around two types of communication: connection-oriented
and connectionless. In a connection-oriented socket, the TCP protocol is used to establish a
session (connection) between two IP address endpoints. There is a fair amount of overhead
involved with establishing the connection, but once it is established, the data can be reliably
transferred between the devices.
Connectionless sockets use the UDP protocol. Because of that no connection information is
required to be sent between the network devices and it is often difficult to determine which
device is acting as a "server", and which is acting as a "client". We will focus on the first type of
socket programming in this article.
Using connection-oriented sockets
In the .NET Framework, you can create connection-oriented communications with remote hosts
across a network. To create a connection-oriented socket, separate sequences of functions must
be used for server programs and client programs:

Server
You have four tasks to perform before a server can transfer data with a client connection:
1. Create a socket.
2. Bind the socket to a local IPEndPoint.
3. Place the socket in listen mode.
4. Accept an incoming connection on the socket.
Creating the server
The first step to constructing a TCP server is to create an instance of the Socket object. The
other three functions necessary for successful server operations are then accomplished by using
the methods of Socket object. The following C# code snippet includes these steps:
Collapse

IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, 8000);


Socket newsock = Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
newsock.Bind(localEndPoint);
newsock.Listen(10);
Socket client = newsock.Accept();
The Socket object created by the Accept() method can now be used to transmit data in either
direction between the server and the remote client.
Client
Now that you have a working TCP server, you can create a simple TCP client program to interact
with it. There are only two steps required to connect a client program to a TCP server:
1. Create a socket.
2. Connect the socket to the remote server address.
Creating the client
As it was for the server program, the first step for creating the client program is to create a
Socket object. The Socket object is used by the socket Connect() method to connect the socket
to a remote host:
Collapse

IPEndPoint ipep =
new IPEndPoint(Ipaddress.Parse("127.0.0.1"), 8000);
Socket server = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
server.Connect(ipep);
This example attempts to connect the socket to the server located at address 127.0.0.1.This is the
IP address of the local host (current computer) and is a loopback IP for testing a network
application without a network. Of course, you can also use hostnames along with the
Dns.Resolve() method in a real network. (Dns is in System.Net namespace). Once the remote
server TCP program accepts the connection request, the client program is ready to transmit data
with the server using the standard Send() and Receive() methods.

Blocking problem of network applications


Sockets are in blocking mode by default. In this mode they will wait forever to complete their
functions, holding up other functions within the application program until they are complete.
Many programs can work quite competently in this mode, but for applications that work in the
Windows programming environment, this can be a problem. There are some ways to solve this
problem. The first thing that comes to a programmer's mind is multi threading. I chose this
solution in my application too. This is a simple way when compared to asynchronous network
programming or the old 'Non-Blocking sockets' way.
Our command client/server
After a brief introduction on network programming in C#, I should give you more details about
our command client/server application here. Of course, I can't write a book on network
programming in this little article. This is only an introduction to network programming. You can
find many samples and tutorials on MSDN and CodeProject explaining this concept in detail.
About the command server
The server application is a console program. After starting, it will bind to the '127.0.0.1' local IP
and wait on the port 8000 by default for clients. You can pass the IP and the port of the server as
the first and second command line parameters when starting the server, if you have a real
network. For example: c:\> ConsoleServer 192.198.0.100 8960.
I used BackgroundWorker to implement multithreading in time consuming functions in the
server and client. One of these actions includes the acceptance part of the server:
Collapse

bwListener = new BackgroundWorker();


bwListener.DoWork += new DoWorkEventHandler(StartToListen);
bwListener.RunWorkerAsync();

private void StartToListen(object sender , DoWorkEventArgs e)


{
this.listenerSocket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
this.listenerSocket.Bind(
new IPEndPoint(this.serverIP , this.serverPort));
this.listenerSocket.Listen(200);
while ( true )
this.CreateNewClientManager(this.listenerSocket.Accept());
}
I have a class named ClientManager. When the server is connected to a remote client it passes
the communication socket to this class and adds this new ClientManager object to a list of
current connected remote clients. Each ClientManager object in the list is responsible for
communicating with its remote client. The ClientManager object announces the server with
various events defined in this class when an action takes place between the remote client and the
server. These events are:
Collapse

public event CommandReceivedEventHandler CommandReceived;


Occurs when a command is received from a remote client.
Collapse

public event CommandSentEventHandler CommandSent;


Occurs when a command had been sent to the remote client successfully.
Collapse

public event CommandSendingFailedEventHandler CommandFailed;


Occurs when a command sending action fails. This is may be because of disconnection or
sending exception.
Collapse

public event DisconnectedEventHandler Disconnected;


Occurs when a client is disconnected from this server.
Sending and receiving data
Since we have a command client/server application we should have a command object to send
and receive data. This is implemented in a 'Command' class. This class is the same in client and
server. When the server wants to send a command to the client it builds a Command object and
then sends it to the client and vice versa.
The command class is good for the user of this code. But in the network, we can't send and
receive an object or a type. Everything should be converted to byte array. So, we should convert
this object to a byte array part by part and send or receive it over the network in real Send and
Receive functions inside our code. The following code shows the send command method. 'cmd'
is the command that we want to send to the remote client:
Collapse

//Type

byte [] buffer = new byte [4];


buffer = BitConverter.GetBytes((int)cmd.CommandType);
this.networkStream.Write(buffer , 0 , 4);
this.networkStream.Flush();

//Sender IP

byte [] senderIPBuffer =
Encoding.ASCII.GetBytes(cmd.SenderIP.ToString());
buffer = new byte [4];
buffer = BitConverter.GetBytes(senderIPBuffer.Length);
this.networkStream.Write(buffer , 0 , 4);
this.networkStream.Flush();
this.networkStream.Write(senderIPBuffer, 0,
senderIPBuffer.Length);
this.networkStream.Flush();

//Sender Name

byte [] senderNameBuffer =
Encoding.Unicode.GetBytes(cmd.SenderName.ToString());
buffer = new byte [4];
buffer = BitConverter.GetBytes(senderNameBuffer.Length);
this.networkStream.Write(buffer , 0 , 4);
this.networkStream.Flush();
this.networkStream.Write(senderNameBuffer, 0,
senderNameBuffer.Length);
this.networkStream.Flush();

//Target

byte [] ipBuffer =
Encoding.ASCII.GetBytes(cmd.Target.ToString());
buffer = new byte [4];
buffer = BitConverter.GetBytes(ipBuffer.Length);
this.networkStream.Write(buffer , 0 , 4);
this.networkStream.Flush();
this.networkStream.Write(ipBuffer , 0 , ipBuffer.Length);
this.networkStream.Flush();

//Meta Data.

if ( cmd.MetaData == null || cmd.MetaData == "" )


cmd.MetaData = "\n";

byte [] metaBuffer =
Encoding.Unicode.GetBytes(cmd.MetaData);
buffer = new byte [4];
buffer = BitConverter.GetBytes(metaBuffer.Length);
this.networkStream.Write(buffer , 0 , 4);
this.networkStream.Flush();
this.networkStream.Write(metaBuffer, 0, metaBuffer.Length);
this.networkStream.Flush();
The send and receive are bidirectional operations. For example, when we send 4 bytes to the
client, the client should read the 4 bytes. We should repeat this operation until all the sent data is
read. See the receive code of the client here:
Collapse

while ( this.clientSocket.Connected )
{
//Read the command's Type.

byte [] buffer = new byte [4];


int readBytes = this.networkStream.Read(buffer , 0 , 4);
if ( readBytes == 0 )
break;
CommandType cmdType =
(CommandType)( BitConverter.ToInt32(buffer , 0) );

//Read the command's sender ip size.

buffer = new byte [4];


readBytes = this.networkStream.Read(buffer , 0 , 4);
if ( readBytes == 0 )
break;
int senderIPSize = BitConverter.ToInt32(buffer , 0);

//Read the command's sender ip.

buffer = new byte [senderIPSize];


readBytes =
this.networkStream.Read(buffer , 0 , senderIPSize);
if ( readBytes == 0 )
break;
IPAddress senderIP = IPAddress.Parse(
System.Text.Encoding.ASCII.GetString(buffer));

//Read the command's sender name size.


buffer = new byte [4];
readBytes = this.networkStream.Read(buffer , 0 , 4);
if ( readBytes == 0 )
break;
int senderNameSize = BitConverter.ToInt32(buffer , 0);

//Read the command's sender name.

buffer = new byte [senderNameSize];


readBytes = this.networkStream.Read(buffer, 0, senderNameSize);
if ( readBytes == 0 )
break;
string senderName =
System.Text.Encoding.Unicode.GetString(buffer);

//Read the command's target size.

string cmdTarget = "";


buffer = new byte [4];
readBytes = this.networkStream.Read(buffer , 0 , 4);
if ( readBytes == 0 )
break;
int ipSize = BitConverter.ToInt32(buffer , 0);

//Read the command's target.

buffer = new byte [ipSize];


readBytes = this.networkStream.Read(buffer , 0 , ipSize);
if ( readBytes == 0 )
break;
cmdTarget = System.Text.Encoding.ASCII.GetString(buffer);

//Read the command's MetaData size.

string cmdMetaData = "";


buffer = new byte [4];
readBytes = this.networkStream.Read(buffer , 0 , 4);
if ( readBytes == 0 )
break;
int metaDataSize = BitConverter.ToInt32(buffer , 0);

//Read the command's Meta data.

buffer = new byte [metaDataSize];


readBytes = this.networkStream.Read(buffer , 0 , metaDataSize);
if ( readBytes == 0 )
break;
cmdMetaData = System.Text.Encoding.Unicode.GetString(buffer);

Command cmd = new Command(cmdType,


IPAddress.Parse(cmdTarget), cmdMetaData);
cmd.SenderIP = senderIP;
cmd.SenderName = senderName;
this.OnCommandReceived(new CommandEventArgs(cmd));
}
this.OnServerDisconnected(new ServerEventArgs(this.clientSocket));
this.Disconnect();
}

About the command client


The command client is very similar to the server. Everything is in the 'CommandClient' class.
Since our application is an event driven program this class also has some events to announce the
user of the occurred actions. Here is a brief definition of these events:
Collapse

public event CommandReceivedEventHandler CommandReceived;


Occurs when a command is received from a remote client.
Collapse

public event CommandSentEventHandler CommandSent;


Occurs when a command has been sent to the remote server successfully.
Collapse

public event CommandSendingFailedEventHandler CommandFailed;


Occurs when a command sending action fails. This is because of disconnection or sending
exception.
Collapse

public event ServerDisconnectedEventHandler ServerDisconnected;


Occurs when the client is disconnected.
Collapse

public event DisconnectedEventHandler DisconnectedFromServer;


Occurs when this client is disconnected from the remote server.
Collapse

public event ConnectingSuccessedEventHandler ConnectingSuccessed;


Occurs when this client is connected to the remote server successfully.
Collapse

public event ConnectingFailedEventHandler ConnectingFailed;


Occurs when this client fails on connecting to the server.
Collapse

public event NetworkDeadEventHandler NetworkDead;


Occurs when the network fails.
Collapse

public event NetworkAlivedEventHandler NetworkAlived;


Occurs when the network starts to work.
Conclusion
In this application, you can find the following concepts of .NET programming:
• Socket programming, server side and client side.
• Working with resources at runtime.
• Concurrency management in multi threaded environment.
• Calling windows API functions within C# code.
• Creating custom events and eventargs, and throwing events in a UI safe mode.
• Creating custom exceptions and throwing them as and when needed.
• Generating an HTML page at runtime dynamically.
And many other .NET programming concepts that I couldn't explain in detail here. The code is
fully XML commented and very clear to understand. Please contact me if there is any ambiguous
point or you need any help on my code.
License
This article has no explicit license attached to it but may contain usage terms in the article text or
the download files themselves. If in doubt please contact the author via the discussion board
below.
A list of licenses authors might use can be found here

Bottom of Form

How to C# Chat Client


The Microsoft .NET framework provides two namespaces, System.Net and System.Net.Sockets
for managed implementation of Internet protocols that applications can use to send or receive
data over the Internet . The C# Chat Client here is a Windows based Application and its main
function is to send message to the Chat Server.
In the previous section C# Multi Threaded Socket Program we saw a C# Multithreaded Server
Socket Program communicate with more than one Client at the same time . If you don't know the
basics of Socket programming , take a look at the section C# Socket Programming before you
start this section.
The C# Chat Server Program has two sections.
1. C# Chat Server
2. Chat Client
Chat Client
The Chat Client here is to connect the PORT 8888 of the C# Chat Server in " 127.0.0.1 " . Here
we give " 127.0.0.1 " , because Chat Server and Chat Client are running on the same machine .
When we start the Chat Client program , we have to enter a User Name for identifying the client
in Server side . The Client program connect to the Chat Server and start a Thread for receive the
messages from Server side client . Here we implement an infinite loop in the function
getMessage() and call this function in a Thread .
Create a new C# Windows based project and put the source code in it.
C# Source Code Download Print Source Code
How to C# Chat Client - Download

C# Tutorial

using System;
using System.Windows.Forms;
using System.Text;
using System.Net.Sockets ;
using System.Threading;

namespace WindowsApplication2
{
public partial class Form1 : Form
{
System.Net.Sockets.TcpClient clientSocket = new
System.Net.Sockets.TcpClient();
NetworkStream serverStream = default(NetworkStream);
string readData = null;

public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)


{
byte[] outStream =
System.Text.Encoding.ASCII.GetBytes(textBox2.Text + "$");
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
}

private void button2_Click(object sender, EventArgs e)


{
readData = "Conected to Chat Server ...";
msg();
clientSocket.Connect("127.0.0.1", 8888);
serverStream = clientSocket.GetStream();

byte[] outStream =
System.Text.Encoding.ASCII.GetBytes(textBox3.Text + "$");
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();

Thread ctThread = new Thread(getMessage);


ctThread.Start();
}

private void getMessage()


{
while (true)
{
serverStream = clientSocket.GetStream();
int buffSize = 0;
byte[] inStream = new byte[10025];
buffSize = clientSocket.ReceiveBufferSize;
serverStream.Read(inStream, 0, buffSize);
string returndata =
System.Text.Encoding.ASCII.GetString(inStream);
readData = "" + returndata;
msg();
}
}

private void msg()


{
if (this.InvokeRequired)
this.Invoke(new MethodInvoker(msg));
else
textBox1.Text = textBox1.Text + Environment.NewLine + " >> "
+ readData;
}

}
}
The C# Chat Server Program has two sections.
1. C# Chat Server

2. Chat Client

How to run Chat Server program ?

Create the C# Chat Server and C# Chat Client are two separate C# projects and compile and
build the program. Open a DOS Prompt and run the Server Program first and then run the Client
program .

In the Client program, Enter a Chat name and click " Connect to Server " button . Then you can
see the message in the Server program User "Joined Chat Room" . Similarly you can connect
more than one Clients at the same time and start chatting each other. If you plan to run more than
one client, it is better to copy the .exe file in separate folders and run from the .exe file.

How to find IP Adress of a computer


Network programming in windows is possible with sockets . C# simplifies network
programming through its namespaces like System.Net and System.Net.Sockets . The System.Net
classes provide functionalities that is similar to Microsoft WinInet API.
The System.net namespace provides the information about IP Address . The following C#
program shows how to find the IP Address of a host.
C# Source Code Download Print Source Code
How to find IP Adress of a computer - Download

C# Tutorial

using System;
using System.Windows.Forms;
using System.Net;

namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)


{
try
{
IPHostEntry hostname = Dns.GetHostByName(textBox1.Text );
IPAddress[] ip = hostname.AddressList;
textBox2.Text = ip[0].ToString();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
}

If you pass localhost in GetHostByName return the IP Address of local machine .


How to find hostname of a computer
The System.Net classes provide functionalities that is similar to Microsoft WinInet API , it
allows classes to communicate with other applications by using the Hypertext Transfer Protocol
(HTTP), Transmission Control Protocol (TCP), User Datagram Protocol (UDP), and Socket
Internet protocols.
The following C# program show how to find the Host name of a computer.
Dns.GetHostName();
C# Source Code Download Print Source Code
How to find hostname of a computer - Download

C# Tutorial

using System;
using System.Net;
using System.Windows.Forms;

namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)


{
MessageBox.Show (Dns.GetHostName());
}
}
}

CSharp Communications Related Contents

How to send cdo email from C#


The Microsoft .NET framework provides two namespaces, System.Net and System.Net.Sockets
for managed implementation of Internet protocols that applications can use to send or receive
data over the Internet .
In the previous C# program SMTP email from C# describes how to send an email with text
body . Here we are sending an email without using SMTP protocol through C# programming .
Instead of SMTP here we use CDOSYS , Collaboration Data Objects (CDO) for Windows
2000 library (Cdosys.dll) . The Cdosys.dll library is also known as CDOSYS .
Create a new C# project and add a reference to Microsoft CDO For Windows 2000 Library .
From the following picture you can understand how to add Microsoft CDO For Windows 2000
Library in your C#project.

C# Source Code Download Print Source Code


How to send cdo email from C# - Download

C# Tutorial

using System;
using System.Windows.Forms;
using System.Net.Mail;

namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)


{
try
{
CDO.Message oMsg = new CDO.Message();
CDO.IConfiguration iConfg;
iConfg = oMsg.Configuration;
ADODB.Fields oFields;
oFields = iConfg.Fields;
ADODB.Field oField =
oFields["http://schemas.microsoft.com/cdo/configuration/sendusing"];
oFields.Update();
oMsg.Subject = "Test CDO";
oMsg.From = "from_address";
oMsg.To = "to_address";
oMsg.TextBody = "CDO Mail test";
oMsg.Send();
MessageBox.Show("mail Send");
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
}

How to send html email from C#


The System.Net classes provide the functionalities that is similar to Microsoft WinInet API .
Here we are using System.Net class for sending an HTML email from the following C#
program . In an HTML email , the body part contain HTML codes like HTML pages. In the
previous C# program SMTP email from C# describes how to send an email with a text body .
Here instead of text body part we are sending email with HTML body part.
mail.IsBodyHtml = true;
string htmlBody = "create html page" ;
mail.Body = htmlBody;
The following C# source code shows how to send an email with HTML body part from a Gmail
address . The Gmail SMTP server name is smtp.gmail.com and the port using for send mail is
587 . Here using NetworkCredential for password based authentication.
SmtpServer.Credentials =
new System.Net.NetworkCredential("username", "password");

C# Source Code Download Print Source Code


How to send html email from C# - Download

C# Tutorial

using System;
using System.Windows.Forms;
using System.Net.Mail;

namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)


{
try
{
MailMessage mail = new MailMessage();
SmtpClient SmtpServer = new SmtpClient("smtp.gmail.com");

mail.From = new MailAddress("your_email_address@gmail.com");


mail.To.Add("to_address");
mail.Subject = "Test Mail - 1";

mail.IsBodyHtml = true;
string htmlBody;

htmlBody = "Write some HTML code here";

mail.Body = htmlBody;

SmtpServer.Port = 587;
SmtpServer.Credentials = new
System.Net.NetworkCredential("username", "password");
SmtpServer.EnableSsl = true;

SmtpServer.Send(mail);
MessageBox.Show("mail Send");
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
}

You have to provide the necessary information like your gmail username and password etc.
How to send email with attachment
from C#
C# simplifies network programming in .Net framework. C# describes various protocols using
communication programming like Socket communications , SMTP mail , UDP , URL etc. The
System.Net classes uses to communicate with other applications by using the HTTP, TCP, UDP,
Socket etc. In the previous program we saw how to SMTP email from C# describes how to send
an email with text body . Here we are sending an email with an attachment.
System.Net.Mail.Attachment attachment;
attachment = new System.Net.Mail.Attachment("c:\\containers.xls");
mail.Attachments.Add(attachment);
The following C# source code shows how to send an email with an attachment from a Gmail
address . The Gmail SMTP server name is smtp.gmail.com and the port using send mail is 587 .
Here using NetworkCredential for password based authentication.
SmtpServer.Credentials =
new System.Net.NetworkCredential("username", "password");

C# Source Code Download Print Source Code


How to send email with attachment from C# - Download

C# Tutorial

using System;
using System.Windows.Forms;
using System.Net.Mail;

namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)


{
try
{
MailMessage mail = new MailMessage();
SmtpClient SmtpServer = new SmtpClient("smtp.gmail.com");
mail.From = new MailAddress("your_email_address@gmail.com");
mail.To.Add("to_address");
mail.Subject = "Test Mail - 1";
mail.Body = "mail with attachment";

System.Net.Mail.Attachment attachment;
attachment = new System.Net.Mail.Attachment("you attachment
file");
mail.Attachments.Add(attachment);

SmtpServer.Port = 587;
SmtpServer.Credentials = new
System.Net.NetworkCredential("username", "password");
SmtpServer.EnableSsl = true;

SmtpServer.Send(mail);
MessageBox.Show("mail Send");
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
}

You have to provide the necessary information like your gmail username and password etc.

How to send email from C#


The Microsoft .NET framework provides two namespaces, System.Net and System.Net.Sockets
for managed implementation of Internet protocols that applications can use to send or receive
data over the Internet . SMTP protocol is using for sending email from C#. SMTP stands for
Simple Mail Transfer Protocol . C# using System.Net.Mail namespace for sending email . We
can instantiate SmtpClient class and assign the Host and Port . The default port using SMTP is
25 , but it may vary different Mail Servers .
The following C# source code shows how to send an email from a Gmail address using SMTP
server. The Gmail SMTP server name is smtp.gmail.com and the port using send mail is 587
and also using NetworkCredential for password based authentication.
SmtpClient SmtpServer = new SmtpClient("smtp.gmail.com");
SmtpServer.Port = 587;
SmtpServer.Credentials =
new System.Net.NetworkCredential("username", "password");

C# Source Code Download Print Source Code


How to send email from C# - Download

C# Tutorial

using System;
using System.Windows.Forms;
using System.Net.Mail;

namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)


{
try
{
MailMessage mail = new MailMessage();
SmtpClient SmtpServer = new SmtpClient("smtp.gmail.com");

mail.From = new MailAddress("your_email_address@gmail.com");


mail.To.Add("to_address@mfc.ae");
mail.Subject = "Test Mail";
mail.Body = "This is for testing SMTP mail from GMAIL";

SmtpServer.Port = 587;
SmtpServer.Credentials = new
System.Net.NetworkCredential("username", "password");
SmtpServer.EnableSsl = true;

SmtpServer.Send(mail);
MessageBox.Show("mail Send");
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
}
}

You have to provide the necessary information like your gmail username and password etc.

How to read URL Content from


webserver
The .NET framework provides two namespaces, System.Net and System.Net.Sockets for
network programming. The System.Net classes use to communicate with other applications by
using the HTTP, TCP, UDP and Sockets.
When we want to read the content of an HTML page from a remote webserver in C# we are
using WebRequest and WebResponse Classes. WebResponse return a StreamReader and we
can get the content from StreamReader . The following C# program shows how to read the
content of an HTML page using WebRequest and WebResponse Classes.
C# Source Code Download Print Source Code
How to read URL Content from webserver - Download

C# Tutorial

using System;
using System.Windows.Forms;
using System.Net;
using System.IO;

namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)


{
try
{
StreamReader inStream ;
WebRequest webRequest ;
WebResponse webresponse ;
webRequest = WebRequest.Create(textBox1.Text);
webresponse = webRequest.GetResponse();
inStream = new StreamReader(webresponse.GetResponseStream());
textBox2.Text = inStream.ReadToEnd();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
}

How to C# Socket programming


C# simplifies the network programming through its namespaces like System.Net and
System.Net.Sockets . A Socket is an End-Point of To and From (Bidirectional) communication
link between two programs (Server Program and Client Program ) running on the same network .
We need two programs for communicating a socket application in C#. A Server Socket Program
( Server ) and a Client Socket Program ( Client ) .
C# Server Socket Program: A C# Server Socket Program running on a computer has a socket
that bound to a Port Number on the same computer and listening to the client's incoming
requests.
C# Client Socket Program: A C# Client Socket Program have to know the IP Address
( Hostname ) of the computer that the C# Server Socket Program resides and the Port Number
assign for listening for client's request .
Once the connection is established between Server and Client , they can communicate (read or
write ) through their own sockets.

There are two types of communication protocol uses for Socket Programming in C# , they are
TCP/IP ( Transmission Control Protocol/Internet protocol ) Communication and UDP/IP ( User
Datagram Protocol/Internet protocol ) Communication .
In the following section we are going to communicate a C# Server Socket Program and C#
Client Socket Program using TCP/IP Communication Protocol.

C# Server Socket program


The C# Socket Programming has two sections.
1. C# Server Socket Program
2. C# Client Socket Program
Server Socket Program
The Server Socket Program here is a C# Console based Application . This program act as a
Server and listening to clients request . Here we assign a Port No. 8888 for the Server Socket , it
is an instance of the C# Class TcpListener , and call its start() method.
TcpListener serverSocket = new TcpListener(8888);
serverSocket.Start();
The next step is to create an infinite loop for monitoring the request from Client's side . When the
Server Socket accept a request from the Client side, it reads the data from NetworkStream and
also it write the response to NetworkStream .
From the following C# program you can understand how to create a Socket Server in C# . Create
a new C# Console Application Project and put the following source code into the project.
C# Source Code Download Print Source Code
C# Server Socket program - Download

C# Tutorial

using System;
using System.Net.Sockets;
using System.Text;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
TcpListener serverSocket = new TcpListener(8888);
int requestCount = 0;
TcpClient clientSocket = default(TcpClient);
serverSocket.Start();
Console.WriteLine(" >> Server Started");
clientSocket = serverSocket.AcceptTcpClient();
Console.WriteLine(" >> Accept connection from client");
requestCount = 0;

while ((true))
{
try
{
requestCount = requestCount + 1;
NetworkStream networkStream = clientSocket.GetStream();
byte[] bytesFrom = new byte[10025];
networkStream.Read(bytesFrom, 0,
(int)clientSocket.ReceiveBufferSize);
string dataFromClient =
System.Text.Encoding.ASCII.GetString(bytesFrom);
dataFromClient = dataFromClient.Substring(0,
dataFromClient.IndexOf("$"));
Console.WriteLine(" >> Data from client - " +
dataFromClient);
string serverResponse = "Server response " +
Convert.ToString(requestCount);
Byte[] sendBytes =
Encoding.ASCII.GetBytes(serverResponse);
networkStream.Write(sendBytes, 0, sendBytes.Length);
networkStream.Flush();
Console.WriteLine(" >> " + serverResponse);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}

clientSocket.Close();
serverSocket.Stop();
Console.WriteLine(" >> exit");
Console.ReadLine();
}
}
}

How to run this program ?


The C# Socket Programming has two sections.

1. C# Server Socket Program

2. C# Client Socket Program

When you finish coding and build the Server and Client program , First you have to start C#
Server Socket Program from DOS prompt , then you will get a message " Server Started " in
your DOS screen, where the server program is running .

Next step is to start C# Client Socket Program in the same computer or other computers on the
same network . When you start the client program , it will establish a connection to the Server
and get a message in client screen " Client Started " , at the same time you can see a message in
the Server screen " Accept connection from client " .

Now your C# Server Socket Program and C# Client Socket Program is get connected and
communicated . If you want to communicate the Server and Client again , click the button in
theclient program , then you can see new messages in the Server and Client programs displayed.

The above picture shows a Server and Client communication interfaces in C#.
C# Server Socket Program:
The Server Socket Program is done through a C# Console based application . Here the Server is
listening for the Client's request , and when the C# Server gets a request from Client socket , the
Server sends a response to the Client . Click the following link to see in detail of a C# Server
Socket Program.
C# Client Socket Program:
The C# Client Socket Program is a windows based application . When the C# Client program
execute , it will establish a connection to the C# Server program and send request to the Server ,
at the same time it also receive the response from C# Server . Click the following link to see in
detail of C# Client Socket Program.
How to run this program ?
The C# Socket Program has two sections.
1. C# Server Socket Program
2. C# Client Socket Program
When you finish coding and build the Server and Client program , First you have to start C#
Server Socket Program from DOS prompt , then you will get a message "Server Started" in your
DOS screen, where the server program is running .
Next step is to start C# Client Socket Program in the same computer or other computers on the
same network . When you start the client program , it will establish a connection to the Server
and get a message in client screen " Client Started " , at the same time you can see a message in
the Server screen "Accept connection from client" .
Now your C# Server Socket Program and C# Client Socket Program is get connected and
communicated . If you want to communicate the Server and Client again , click the button in
theclient program , then you can see new messages in the Server and Client programs displayed.

C# Tutorial

C# Client Socket program


The C# Socket Programming has two sections.
1. C# Server Socket Program
2. C# Client Socket Program
Client Socket Program
The C# Client Socket Program is the second part of the C# Server Socket Program . The C#
Client Socket Program is a Windows based application . The Client is connected to the Port 8888
of the C# Server Socket Program , and the IP Address (Computer Name) here we give as
127.0.0.1 , because the Server and Client running on the same machine .
clientSocket.Connect("127.0.0.1", 8888);
When the C# Client program starts , it will connect to the C# Server Socket Program and start to
reads data from NetworkStream , and also write to the NetworkStream . When you start the
client program you will get a message from Server "client started". When press the button at the
bottom of Client window, it will send a message to the Server and also receive response from the
Server.
C# Source Code Download Print Source Code
C# Client Socket program - Download

C# Tutorial

using System;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Text;

namespace WindowsApplication1
{
public partial class Form1 : Form
{
System.Net.Sockets.TcpClient clientSocket = new
System.Net.Sockets.TcpClient();
public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)


{
msg("Client Started");
clientSocket.Connect("127.0.0.1", 8888);
label1.Text = "Client Socket Program - Server Connected ...";
}

private void button1_Click(object sender, EventArgs e)


{
NetworkStream serverStream = clientSocket.GetStream();
byte[] outStream = System.Text.Encoding.ASCII.GetBytes("Message
from Client$");
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();

byte[] inStream = new byte[10025];


serverStream.Read(inStream, 0,
(int)clientSocket.ReceiveBufferSize);
string returndata =
System.Text.Encoding.ASCII.GetString(inStream);
msg("Data from Server : " + returndata);
}

public void msg(string mesg)


{
textBox1.Text = textBox1.Text + Environment.NewLine + " >> " +
mesg;
}
}
}

How to run this program ?


The C# Socket Programming has two sections.

1. C# Server Socket Program

2. C# Client Socket Program

When you finish coding and build the Server and Client program , First you have to start C#
Server Socket Program from DOS prompt , then you will get a message " Server Started " in
your DOS screen, where the server program is running .

Next step is to start C# Client Socket Program in the same computer or other computers on the
same network . When you start the client program , it will establish a connection to the Server
and get a message in client screen " Client Started " , at the same time you can see a message in
the Server screen " Accept connection from client " .
Now your C# Server Socket Program and C# Client Socket Program is get connected and
communicated . If you want to communicate the Server and Client again , click the button in
theclient program , then you can see new messages in the Server and Client programs displayed.

C# Multi threaded socket


programming
C# Multithreaded Socket Programming describes that a Multithreaded Socket Server can
communicate with more than one client at the same time in the same network. The Microsoft
.NET framework provides two namespaces, System.Net and System.Net.Sockets for managed
implementation of Internet protocols that applications can use to send or receive data over the
Internet .
In the previous chapter C# Socket Programming describes a Server Socket Program can
communicate with only one client at a time . That means, the C# Server Socket Program does not
accept more than one C# Client Socket Program connection . From the following picture you can
understand how to a C# Multithreaded Server can communicate with more than one C# Clientat
the same time .You can see the basics of Socket Programming in the previous section , before
you start this section take a look at C# Socket Programming .
The basic idea behind Multithreaded Socket Programming is, whenever the Server gets a
connection request from Client side, the Server create a separate Client Thread in Server side for
communicate with that particular Client Socket. That means, for each Client Socket there is a
separate Client Thread in Server side for independent communication. So the Client can
communicate independently with their own Client Thread in the Server side.
In the following sections you can see in details of How to a C# Multithreaded Socket
Programming can communicate with more than one client at the same time.
The C# Multithreaded Socket Programming has two sections.
1. C# Multi Threaded Server Socket Program
2. C# Multi Threaded Client Socket Program
How to run this program ?
Create C# Multi Threaded Server Socket Program and C# Multi Threaded Client Socket
Program in two separate C# projects .
After compile and build the projects, open a DOS prompt and run the Server Program first.
Then you will get the message "Server started" in Server side.
Next you start the Client program , then you can see the message from Server . You can start
more than one client at the same time and communicate with the Server program. If you plan to
run more than one client, it is better to run the client program's .exe file to copy in separate
folders and run from .exe file.

C# Multi threaded Server Socket


programming
MultiThreaded Server Socket Program here is a C# Console based application , that can handle
multiple clients at the same time. Network programming in windows is possible with sockets ,
peer-to-peer Microsoft Windows applications that act as servers and clients to send and receive
data. You can see the basics of C# Socket Programming in the previous section , before you start
this section take a look at C# Socket Programming .

The C# Multi Threaded Socket Program has two sections.


1. C# Multithreaded Server Socket Program
2. C# Multi Threaded Client Socket Program
Multithreaded Server Socket Program
Here we create a C# Server Socket from TcpListener Class and listen to PORT 8888 . When the
C# Server Socket gets a request from Client side , the Server passes the instance of the client
request to a separate class handleClient .For each call from Server Socket , the handleClient class
create new instances for independent communication with the client. In handleClient class there
is a Thread for handling the communication between the instance of C# Server side client and C#
Client from outside .
For each Client request , there is a new thread instant is created in C# Server for separate
communication with Client, so we can connect more than one client at the same time to the C#
Server and communicate independently to Server .
Create a new C# Console Application project and put the following source code in the C#
project.
C# Source Code Download Print Source Code
C# Multi threaded Server Socket programming - Download

C# Tutorial

using System;
using System.Threading;
using System.Net.Sockets;
using System.Text;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
TcpListener serverSocket = new TcpListener(8888);
TcpClient clientSocket = default(TcpClient);
int counter = 0;

serverSocket.Start();
Console.WriteLine(" >> " + "Server Started");

counter = 0;
while (true)
{
counter += 1;
clientSocket = serverSocket.AcceptTcpClient();
Console.WriteLine(" >> " + "Client No:" +
Convert.ToString(counter) + " started!");
handleClinet client = new handleClinet();
client.startClient(clientSocket, Convert.ToString(counter));
}

clientSocket.Close();
serverSocket.Stop();
Console.WriteLine(" >> " + "exit");
Console.ReadLine();
}
}

//Class to handle each client request separatly


public class handleClinet
{
TcpClient clientSocket;
string clNo;
public void startClient(TcpClient inClientSocket, string clineNo)
{
this.clientSocket = inClientSocket;
this.clNo = clineNo;
Thread ctThread = new Thread(doChat);
ctThread.Start();
}
private void doChat()
{
int requestCount = 0;
byte[] bytesFrom = new byte[10025];
string dataFromClient = null;
Byte[] sendBytes = null;
string serverResponse = null;
string rCount = null;
requestCount = 0;

while ((true))
{
try
{
requestCount = requestCount + 1;
NetworkStream networkStream = clientSocket.GetStream();
networkStream.Read(bytesFrom, 0,
(int)clientSocket.ReceiveBufferSize);
dataFromClient =
System.Text.Encoding.ASCII.GetString(bytesFrom);
dataFromClient = dataFromClient.Substring(0,
dataFromClient.IndexOf("$"));
Console.WriteLine(" >> " + "From client-" + clNo +
dataFromClient);

rCount = Convert.ToString(requestCount);
serverResponse = "Server to clinet(" + clNo + ") " +
rCount;
sendBytes = Encoding.ASCII.GetBytes(serverResponse);
networkStream.Write(sendBytes, 0, sendBytes.Length);
networkStream.Flush();
Console.WriteLine(" >> " + serverResponse);
}
catch (Exception ex)
{
Console.WriteLine(" >> " + ex.ToString());
}
}
}
}
}

The C# Multi Threaded Socket Program has two sections.


1. C# Multithreaded Server Socket Program

2. C# Multi Threaded Client Socket Program

How to run this program ?

Create C# Multithreaded Server Socket Program and C# Multi Threaded Client Socket Program
in two separate C# projects .

After compile and build the projects, open a DOS prompt and run the Server Program first.Then
you will get the message "Server started" in Server side.

Next you start the Client program , then you can see the message from Server . You can start
more than one client at the same time and communicate with the Server program. If you plan to
run more than one client, it is better to run the client program's .exe file to copy in separate
folders and run from .exe file.

C# Multi threaded Client Socket


programming
C# Multithreaded Client Socket Program here is a C# Windows based application and it can
connect to the Server and send the message to the Server. The C# Server is multithreaded so we
can connect more than one Client program to the Server .
The System.Net classes provide functionality that is similar to Microsoft WinInet API , it
allows classes to communicate with other applications by using the Hypertext Transfer Protocol
(HTTP), Transmission Control Protocol (TCP), User Datagram Protocol (UDP), and Socket
Internet protocols. You can see the basics of C# Socket Programming in the previous section ,
before you start this section take a look at C# Socket Programming section.
The C# Multi Threaded Socket Program has two sections.
1. C# Multi Threaded Server Socket Program
2. C# Multithreaded Client Socket Program
Multithreaded Client Socket Program
C# MultiThreaded Client Socket Program is a windows based application . Here the client
program is connected to Server's PORT 8888 , and IP Address here we give Server Address as "
127.0.0.1 " , because Server and Client program run on the same machine.
clientSocket.Connect("127.0.0.1", 8888);
When the Client gets connected to the C# Server , the Server makes a separate thread for Client's
communication . So we can connect more than one client and communicate at the same time.
Create a new C# Windows based application and put the following source code in the Project.
C# Source Code Download Print Source Code
C# Multi threaded Client Socket programming - Download

C# Tutorial

using System;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Text;

namespace WindowsApplication1
{
public partial class Form1 : Form
{
System.Net.Sockets.TcpClient clientSocket = new
System.Net.Sockets.TcpClient();
NetworkStream serverStream;

public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)


{
msg("Client Started");
clientSocket.Connect("127.0.0.1", 8888);
label1.Text = "Client Socket Program - Server Connected ...";
}

private void button1_Click(object sender, EventArgs e)


{
NetworkStream serverStream = clientSocket.GetStream();
byte[] outStream = System.Text.Encoding.ASCII.GetBytes("Message
from Client$");
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();

byte[] inStream = new byte[10025];


serverStream.Read(inStream, 0,
(int)clientSocket.ReceiveBufferSize);
string returndata =
System.Text.Encoding.ASCII.GetString(inStream);
msg("Data from Server : " + returndata);
}

public void msg(string mesg)


{
textBox1.Text = textBox1.Text + Environment.NewLine + " >> " +
mesg;
}
}
}

How to run this program ?


The C# Multi Threaded Socket Program has two sections.

1. C# Multi Threaded Server Socket Program

2. C# Multithreaded Client Socket Program

Create C# Multi Threaded Server Socket Program and C# Multithreaded Client Socket Program
in two separate C# projects .

After compile and build the projects, open a DOS prompt and run the Server Program first.Then
you will get the message "Server started" in Server side.

Next you start the Client program , then you can see the message from Server . You can start
more than one client at the same time and communicate with the Server program. If you plan to
run more than one client, it is better to run theclient program's .exe file to copy in separate
folders and run from .exe file.

Chapter 16. Email support


This chapter describes the out-of-the-box email support in jBPM jPDL.
16.1. Mail in jPDL
There are four ways of specifying when emails should be sent from a process.
16.1.1. Mail action
A mail action can be used when the sending of this email should not be shown as a node in the
process graph.
Anywhere you are allowed to specify actions in the process, you can specify a mail action like
this:
<mail actors="#{president}" subject="readmylips" text="nomoretaxes" />
The subject and text attributes can also be specified as an element like this:
<mail actors="#{president}" >
<subject>readmylips</subject>
<text>nomoretaxes</text>
</mail>

Each of the fields can contain JSF like expressions. For example:
<mail to='#{initiator}' subject='websale' text='your websale of #{quantity}
#{item} was approved' />
For more information about expressions, see Section 18.3, “Expressions”.
There are two attribute to specify recipients: actors and to. The to attribute should resolve to a
semicolon separated list of email addresses. The actors attribute should resolve to a semicolon
separated list of actorIds. Those actorIds will be resolved to email addresses with by means of
address resolving.
<mail to='admin@mycompany.com' subject='urgent' text='the mailserver is
down :-)' />
For more about how to specify recipients, see Section 16.3, “Specifying mail recipients”
Mails can be defined in templates and in the process you can overwrite properties of the
templates like this:
<mail template='sillystatement' actors="#{president}" />
More about templates can be found in Section 16.4, “Mail templates”
16.1.2. Mail node
Just the same as with mail actions, sending of an email can also be modelled as a node. In that
case, the runtime behaviour is just the same, but the email will show up as a node in the process
graph.
The attributes and elements supported by mail nodes are exactly the same as with the mail
actions.
<mail-node name="send email" to="#{president}" subject="readmylips"
text="nomoretaxes">
<transition to="the next node" />
</mail-node>
Mail nodes should have exactly one leaving transition.
16.1.3. Task assign mails
A notification email can be send when a task gets assigned to an actor. Just use the
notify="yes" attribute on a task like this:
<task-node name='a'>
<task name='laundry' swimlane="grandma" notify='yes' />
<transition to='b' />
</task-node>
Setting notify to yes, true or on will cause jBPM to send an email to the actor that will be
assigned to this task. The email is based on a template (see Section 16.4, “Mail templates”) and
contains a link to the task page of the web application.
16.1.4. Task reminder mails
Similarly as with assignments, emails can be send as a task reminder. The reminder element in
jPDL is based upon the timer. The most common attributes will be the duedate and the repeat.
The only difference is that no action has to be specified.
<task-node name='a'>
<task name='laundry' swimlane="grandma" notify='yes'>
<reminder duedate="2 business days" repeat="2 business hours"/>
</task>
<transition to='b' />
</task-node>

16.2. Expressions in mails


The fields to, recipients, subject and text can contain JSF-like expressions. For more
information about expressions, see Section 18.3, “Expressions”
The variables in the expressions can be : swimlanes, process variables, transient variables beans
configured in the jbpm.cfg.xml, ...
These expressions can be combined with the address resolving that is explained later in this
chapter. For example, suppose that you have a swimlane called president in your process, then
look at the following mail specification:
<mail actors="#{president}" subject="readmylips" text="nomoretaxes" />
That will send an email to to the person that acts as the president for that perticular process
execution.
16.3. Specifying mail recipients
16.3.1. Multiple recipients
In the actors and to fields, multiple recipients can be separated with a semi colon (;) or a colon
(:).
16.3.2. Address resolving
In all of jBPM, actors are referenced by actorId's. This is a string that servers as the identifier of
the process participant. An address resolver translates actorId's into email addresses.
Use the attribute actors in case you want to apply address resolving and use the attribute to in
case you are specifying email addresses directly and don't want to apply address resolving.
An address resolver should implement the following interface:
public interface AddressResolver extends Serializable {
Object resolveAddress(String actorId);
}
An address resolver should return 1 of 3 types: a String, a Collection of Strings or an array of
Strings. All strings should represent email addresses for the given actorId.
The address resolver implementation should be a bean configured in the jbpm.cfg.xml with name
jbpm.mail.address.resolver like this:
<jbpm-configuration>
...
<bean name='jbpm.mail.address.resolver'
class='org.jbpm.identity.mail.IdentityAddressResolver' singleton='true' />
</jbpm-configuration>
The identity component of jBPM includes an address resolver. That address resolver will look
for the User of the given actorId. If the user exists, the user's email is returned, otherwise null.
More on the identity component can be found in Section 11.11, “The identity component”.
16.4. Mail templates
Instead of specifying mails in the processdefinition.xml, mails can be specified in a template file.
When a template is used, each of the fields can still be overwritten in the processdefinition.xml.
The mail templates should be specified in an XML file like this:
<mail-templates>

<variable name="BaseTaskListURL" value="http://localhost:8080/jbpm/task?


id=" />

<mail-template name='task-assign'>
<actors>#{taskInstance.actorId}</actors>
<subject>Task '#{taskInstance.name}'</subject>
<text><![CDATA[Hi,
Task '#{taskInstance.name}' has been assigned to you.
Go for it: #{BaseTaskListURL}#{taskInstance.id}
Thanks.
---powered by JBoss jBPM---]]></text>
</mail-template>

<mail-template name='task-reminder'>
<actors>#{taskInstance.actorId}</actors>
<subject>Task '#{taskInstance.name}' !</subject>
<text><![CDATA[Hey,
Don't forget about #{BaseTaskListURL}#{taskInstance.id}
Get going !
---powered by JBoss jBPM---]]></text>
</mail-template>

</mail-templates>

As you can see in this example (BaseTaskListURL), extra variables can be defined in the mail
templates that will be availble in the expressions.
The resource that contains the templates should be configured in the jbpm.cfg.xml like this:
<jbpm-configuration>
...
<string name="resource.mail.templates" value="jbpm.mail.templates.xml" />
</jbpm-configuration>

16.5. Mail server configuration


The simplest way to configure the mail server is with the configuration property
jbpm.mail.smtp.host in the jbpm.cfg.xml like this:
<jbpm-configuration>
...
<string name="jbpm.mail.smtp.host" value="localhost" />
</jbpm-configuration>
Alternatively, when more properties need to be specified, a resource reference to a properties file
can be given with the key '' like this:
<jbpm-configuration>
...
<string name='resource.mail.properties' value='jbpm.mail.properties' />
</jbpm-configuration>

16.6. Customizing mail support


All the mail support in jBPM is centralized in one class: org.jbpm.mail.Mail This is an
ActionHandler implementation. Whenever an mail is specified in the process xml, this will result
in a delegation to the mail class. It is possible to inherit from the Mail class and customize
certain behaviour for your perticular needs. To configure your class to be used for mail
delegations, specify a 'mail.class.name' configuration string in the jbpm.cfg.xml like this:
<jbpm-configuration>
...
<string name='mail.class.name' value='com.your.specific.CustomMail' />
</jbpm-configuration>

16.7. Mail server


If you need a mailserver that is easy to install, checkout JBossMail Server or Apache James

Prev Up

Chapter 17. Logging


The purpose of logging is to keep track of the history of a process execution. As the runtime data
of a process execution changes, all the delta's are stored in the logs.
Process logging, which is covered in this chapter, is not to be confused with software logging.
Software logging traces the execution of a software program (usually for debugging purposes).
Process logging traces the execution of process instances.
There are various use cases for process logging information. Most obvious is the consulting of
the process history by participants of a process execution.
Another use case is Business Activity Monitoring (BAM). BAM will query or analyse the logs of
process executions to find usefull statistical information about the business process. E.g. how
much time is spend on average in each step of the process ? Where are the bottlenecks in the
process ? ... This information is key to implement real business process management in an
organisation. Real business process management is about how an organisation manages their
processes, how these are supported by information technology *and* how these two improve the
other in an iterative process.
Next use case is the undo functionality. Process logs can be used to implement the undo. Since
the logs contain the delta's of the runtime information, the logs can be played in reverse order to
bring the process back into a previous state.
17.1. Creation of logs
Logs are produced by jBPM modules while they are running process executions. But also users
can insert process logs. A log entry is a java object that inherits from
org.jbpm.logging.log.ProcessLog. Process log entries are added to the LoggingInstance.
The LoggingInstance is an optional extension of the ProcessInstance.
Various kinds of logs are generated by jBPM : graph execution logs, context logs and task
management logs. For more information about the specific data contained in those logs, we refer
to the javadocs. A good starting point is the class org.jbpm.logging.log.ProcessLog since
from that class you can navigate down the inheritance tree.
The LoggingInstance will collect all the log entries. When the ProcessInstance is saved, all
the logs in the LoggingInstance will be flushed to the database. The logs-field of a
ProcessInstance is not mapped with hibernate to avoid that logs are retrieved from the
database in each transactions. Each ProcessLog is made in the context of a path of execution
(Token) and hence, the ProcessLog refers to that token. The Token also serves as an index-
sequence generator for the index of the ProcessLog in the Token. This will be important for log
retrieval. That way, logs that are produced in subsequent transactions will have sequential
sequence numbers. (wow, that a lot of seq's in there :-s ).
The API method for adding process logs is the following.
public class LoggingInstance extends ModuleInstance {
...
public void addLog(ProcessLog processLog) {...}
...
}
The UML diagram for logging information looks like this:

Figure 17.1. The jBPM logging information class diagram


A CompositeLog is a special kind of log entry. It serves as a parent log for a number of child
logs, thereby creating the means for a hierarchical structure in the logs. The API for inserting a
log is the following.
public class LoggingInstance extends ModuleInstance {
...
public void startCompositeLog(CompositeLog compositeLog) {...}
public void endCompositeLog() {...}
...
}
The CompositeLogs should always be called in a try-finally-block to make sure that the
hierarchical structure of logs is consistent. For example:
startCompositeLog(new MyCompositeLog());
try {
...
} finally {
endCompositeLog();
}

17.2. Log configurations


For deployments where logs are not important, it suffices to remove the logging line in the jbpm-
context section of the jbpm.cfg.xml configuration file:
<service name='logging' factory='org.jbpm.logging.db.DbLoggingServiceFactory'
/>
In case you want to filter the logs, you need to write a custom implementation of the
LoggingService that is a subclass of DbLoggingService. Also you need to create a custom
logging ServiceFactory and specify that one in the factory attribute.
17.3. Log retrieval
As said before, logs cannot be retrieved from the database by navigating the LoggingInstance to
its logs. Instead, logs of a process instance should always be queried from the database. The
LoggingSession has 2 methods that serve this purpose.
The first method retrieves all the logs for a process instance. These logs will be grouped by token
in a Map. The map will associate a List of ProcessLogs with every Token in the process instance.
The list will contain the ProcessLogs in the same ordered as they were created.
public class LoggingSession {
...
public Map findLogsByProcessInstance(long processInstanceId) {...}
...
}
The second method retrieves the logs for a specific Token. The returned list will contain the
ProcessLogs in the same ordered as they were created.
public class LoggingSession {
public List findLogsByToken(long tokenId) {...}
...
}

17.4. Database warehousing


Sometimes you may want to apply data warehousing techniques to the jbpm process logs. Data
warehousing means that you create a separate database containing the process logs to be used for
various purposes.
There may be many reasons why you want to create a data warehouse with the process log
information. Sometimes it might be to offload heavy queryies from the 'live' production database.
In other situations it might be to do some extensive analysis. Data warehousing even might be
done on a modified database schema which is optimized for its purpose.
In this section, we only want to propose the technique of warehousing in the context of jBPM.
The purposes are too diverse, preventing a generic solution to be included in jBPM that could
cover all those requirements.

Prev Up

Potrebbero piacerti anche