mail server

62
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. Download source files - 345 Kb Download demo - 298 Kb Introduction /w EPDw UKM TA y

Upload: gunzayn-sarthya

Post on 23-Nov-2014

135 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Mail Server

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.

Download source files - 345 Kb Download demo - 298 Kb

IntroductionThe 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

/w EPDwUKMTAy

Page 2: Mail Server

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.

SocketsIn 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:

Collapsepublic IPAddress(long address)

Page 3: Mail Server

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:

CollapseIPAddress 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 socketsThe 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 socketsIn 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:

Page 4: Mail Server

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:

CollapseIPEndPoint 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:

Page 5: Mail 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:

CollapseIPEndPoint 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 applicationsSockets 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/serverAfter 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 serverThe 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.

Page 6: Mail Server

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:

CollapsebwListener = 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:

Collapsepublic event CommandReceivedEventHandler CommandReceived;

Occurs when a command is received from a remote client.

Collapsepublic event CommandSentEventHandler CommandSent;

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

Collapsepublic event CommandSendingFailedEventHandler CommandFailed;

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

Collapsepublic event DisconnectedEventHandler Disconnected;

Occurs when a client is disconnected from this server.

Sending and receiving data

Page 7: Mail Server

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();

Page 8: Mail Server

//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:

Collapsewhile ( 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;

Page 9: Mail Server

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();}

Page 10: Mail Server

About the command clientThe 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:

Collapsepublic event CommandReceivedEventHandler CommandReceived;

Occurs when a command is received from a remote client.

Collapsepublic event CommandSentEventHandler CommandSent;

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

Collapsepublic event CommandSendingFailedEventHandler CommandFailed;

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

Collapsepublic event ServerDisconnectedEventHandler ServerDisconnected;

Occurs when the client is disconnected.

Collapsepublic event DisconnectedEventHandler DisconnectedFromServer;

Occurs when this client is disconnected from the remote server.

Collapsepublic event ConnectingSuccessedEventHandler ConnectingSuccessed;

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

Collapsepublic event ConnectingFailedEventHandler ConnectingFailed;

Occurs when this client fails on connecting to the server.

Collapsepublic event NetworkDeadEventHandler NetworkDead;

Occurs when the network fails.

Page 11: Mail Server

Collapsepublic event NetworkAlivedEventHandler NetworkAlived;

Occurs when the network starts to work.

ConclusionIn 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.

LicenseThis 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

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.

Page 12: Mail Server

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;

Page 13: Mail Server

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()

Page 14: Mail Server

{ 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.

Page 15: Mail Server

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()); } } }}

Page 16: Mail Server

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()); } }}

Page 17: Mail Server

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         

Page 18: Mail Server

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.

Page 19: Mail Server

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("[email protected]"); mail.To.Add("to_address"); mail.Subject = "Test Mail - 1";

mail.IsBodyHtml = true; string htmlBody;

htmlBody = "Write some HTML code here";

mail.Body = htmlBody;

Page 20: Mail Server

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         

Page 21: Mail Server

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("[email protected]"); 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#

Page 22: Mail Server

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("[email protected]"); mail.To.Add("[email protected]"); mail.Subject = "Test Mail"; mail.Body = "This is for testing SMTP mail from GMAIL";

SmtpServer.Port = 587;

Page 23: Mail Server

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;

Page 24: Mail Server

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.

Page 25: Mail Server

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);

Page 26: Mail Server

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 " +

Page 27: Mail Server

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.

Page 28: Mail Server

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.

Page 29: Mail Server

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

Page 30: Mail Server

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

Page 31: Mail Server

{ 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 .

Page 32: Mail Server

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 .

Page 33: Mail Server

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.

Page 34: Mail Server

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.

        

Page 35: Mail Server

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 .

Page 36: Mail Server

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;

Page 37: Mail Server

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 + ") " +

Page 38: Mail Server

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

Page 39: Mail Server

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.

Page 40: Mail Server

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 ..."; }

Page 41: Mail Server

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.

Page 42: Mail Server

Chapter 16. Email supportThis chapter describes the out-of-the-box email support in jBPM jPDL.

16.1. Mail in jPDLThere 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='[email protected]' 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:

Page 43: Mail Server

<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

Page 44: Mail Server

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>

Page 45: Mail Server

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 templatesInstead 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

Page 46: Mail Server

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 supportAll 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 serverIf you need a mailserver that is easy to install, checkout JBossMail Server or Apache James

Prev  Up

Chapter 17. LoggingThe 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.

Page 47: Mail Server

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 logsLogs 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) {...} ...

Page 48: Mail Server

}

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 configurationsFor 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 retrievalAs 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.

Page 49: Mail Server

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 warehousingSometimes 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