C# Chat: Part 1 – Building the Chat Client

Download this Visual Studio 2005 project Download the Chat Client Application project(Visual Studio 2005)

Building a Chat Server and a Chat Client

To no avail I’ve been searching the web for a good C# chat client/server application that is not thousands of lines of code long. The only simple ones I could find were flawed or very buggy, but then again I tried to combine the good parts of all the tutorials I found into one application, and one tutorial that you can see here today. We are going to build a fairly larger application (a few hundred lines of codes) than the ones we’re used to here on Geekpedia, but we’re still going to keep it simple. In fact, there will be two applications: one is a chat server, that handles incoming connections, stores them in hash tables, and distributes new messages to everyone connected, and the other is of course, the chat client, which connects to the server, sends messages and listens for incoming messages. A little knowledge of C#’s networking objects, multi-threading, events and delegates will definitely help you understand this tutorial more easily. A good way to start learning about delegates, events and creating client-server applications is to read the Delegates and Events in C# tutorial first.
The chat server will be able to accept as many chat clients as allowed by the hash table (and you are able to define the limit of the hash table yourself), and it will also track all the messages that are going back and forth in its own chat window, so you should be able to scale this code to a full blown chat application as long as you add the necessary error handling and the bells and whistles.

 

The client application

The client application is, as you might have expected, the simpler one, since all it has to do is to attempt to connect to the chat server, request an username, start listening for messages and sending its own, and finally disconnecting.
Start Visual Studio 2005 and create a new C# Windows Application. I’ve given mine the obvious “Chat Client” name.

Chat Client Form

The first two TextBoxes (txtIp and txtUser) will hold the IP address of the server we want to connect to and the desired username. Before testing out this code keep in mind to change this IP address to the one of the computer in your network that runs the client. If you read the Delegates and Events in C# tutorial, you probably assume you can run the chat application and the server application on the same machine, without needing two different computers connected through a network or the Internet. And you would be right.
The Connect (btnConnect) and Send (btnSend) buttons are obvious, they’re for connecting to the server and sending messages. The large multi-line TextBox is named txtLog and it is where all the messages will be shown.The small TextBox at the bottom is called txtMessage and it is where the message to be sent to the server will be typed.

Now that we’re done with the actual design of the form, we can finally code. Since we will be making use of networking, streaming and threading objects, start by adding the following using statements:

using System.Net;

using System.Net.Sockets;

using System.IO;

using System.Threading;

We’re going to declare most of our objects inside the class, as private, since we don’t need them accessible from anywhere else outside the class:

// Will hold the user name

private string UserName = “Unknown”;

private StreamWriter swSender;

private StreamReader srReceiver;

private TcpClient tcpServer;

// Needed to update the form with messages from another thread

private delegate void UpdateLogCallback(string strMessage);

// Needed to set the form to a “disconnected” state from another thread

private delegate void CloseConnectionCallback(string strReason);

private Thread thrMessaging;

private IPAddress ipAddr;

private bool Connected;

And now that we have them declared, let’s put them to use. Let’s start with the btnConnect_Click event which can be automatically generated if you double click on the Connect button. Inside it we’re going to check whether or not we are connected to a server. If we are, we should call the method that initializes the connection, otherwise we call the method that closes the connection, also specifying a reason why to it:

private void btnConnect_Click(object sender, EventArgs e)

{

// If we are not currently connected but awaiting to connect

if (Connected == false)

{

// Initialize the connection

InitializeConnection();

}

else // We are connected, thus disconnect

{

CloseConnection(“Disconnected at user’s request.”);

}

}

All simple so far, so let’s move to InitializeConnection():

private void InitializeConnection()

{

// Parse the IP address from the TextBox into an IPAddress object

ipAddr = IPAddress.Parse(txtIp.Text);

// Start a new TCP connections to the chat server

tcpServer = new TcpClient();

tcpServer.Connect(ipAddr, 1986);

 

// Helps us track whether we’re connected or not

Connected = true;

// Prepare the form

UserName = txtUser.Text;

 

// Disable and enable the appropriate fields

txtIp.Enabled = false;

txtUser.Enabled = false;

txtMessage.Enabled = true;

btnSend.Enabled = true;

btnConnect.Text = “Disconnect”;

 

// Send the desired username to the server

swSender = new StreamWriter(tcpServer.GetStream());

swSender.WriteLine(txtUser.Text);

swSender.Flush();

 

// Start the thread for receiving messages and further communication

thrMessaging = new Thread(new ThreadStart(ReceiveMessages));

thrMessaging.Start();

}

Nothing too complicated happens in there. The IP address is parsed from the TextBox into an IPAddress object, and then we open a TCP connection to that address. The port is 1986 but it makes no difference as long as its free. We then prepare the controls on the form by disabling some and enabling the others. We also change the caption of btnConnect to now say Disconnect. Through a stream, we then tell the server which username we want, and immediately after that we start a new thread that calls the method ReceiveMessages() which will listen for incoming messages from now on. By putting this in a separate thread, our application is still fully usable while it is listening for messages from the server and keeping the connection alive.

It’s time to see what the ReceiveMessages() method is all about:

private void ReceiveMessages()

{

// Receive the response from the server

srReceiver = new StreamReader(tcpServer.GetStream());

// If the first character of the response is 1, connection was successful

string ConResponse = srReceiver.ReadLine();

// If the first character is a 1, connection was successful

if (ConResponse[0] == ‘1’)

{

// Update the form to tell it we are now connected

this.Invoke(new UpdateLogCallback(this.UpdateLog), new object[] { “Connected Successfully!” });

}

else // If the first character is not a 1 (probably a 0), the connection was unsuccessful

{

string Reason = “Not Connected: “;

// Extract the reason out of the response message. The reason starts at the 3rd character

Reason += ConResponse.Substring(2, ConResponse.Length – 2);

// Update the form with the reason why we couldn’t connect

this.Invoke(new CloseConnectionCallback(this.CloseConnection), new object[] { Reason });

// Exit the method

return;

}

// While we are successfully connected, read incoming lines from the server

while (Connected)

{

// Show the messages in the log TextBox

this.Invoke(new UpdateLogCallback(this.UpdateLog), new object[] { srReceiver.ReadLine() });

}

}

A new stream reader is hooked up to the TCP client. It will listen for incoming messages. But first of all, we read the first line coming from the server. The reason for that is that we know the first line contains a response telling us whether or not we connected successfully. Two reasons why we might’ve not connected successfully are if we attempted to use an username that is already taken, or if we attempted to use Administrator as the username, which is reserved for obvious purposes. The first character of the response given by the server tells us through a 1 that the connection was successful, and through a 0 if it was unsuccessful. And in that case, it also reads a reason as to why it was unsuccessful. That reason starts at the 3rd character of the message, since the first one is the number, and the second one is a pipe character. For example: 0|Username is already in use. Now you can see why if the first character is not a 1 we read the string that starts at the 3rd character and ends at the end of the line.

The this.Invoke() calls tell the form to update itself. We can’t directly update the form elements ourselves from this method because it’s in a separate thread (remember we called it using ThreadStart()) and cross-thread operations are illegal.

Finally, the while (Connected) loop keeps calling the srReceiver.ReadLine() method which checks for incoming messages from the server.

Next comes the method that we kept calling using this.Invoke() – all it does is to update the txtLog TextBox with the latest message:

// This method is called from a different thread in order to update the log TextBox

private void UpdateLog(string strMessage)

{

// Append text also scrolls the TextBox to the bottom each time

txtLog.AppendText(strMessage + “\r\n”);

}

So far we’ve seen how to receive messages from the server, but nothing about how to send them. When do we want to send a message? When the Send button is clicked or when the Enter key is pressed while txtMessage has the focus. This should be hooked up to the Click event of the btnSend button:

// We want to send the message when the Send button is clicked

private void btnSend_Click(object sender, EventArgs e)

{

SendMessage();

}

And this needs to be hooked up to the KeyPress event of txtMessage:

// But we also want to send the message once Enter is pressed

private void txtMessage_KeyPress(object sender, KeyPressEventArgs e)

{
// If the key is Enter

if (e.KeyChar == (char)13)

{

SendMessage();

}

}

You can see that both of them make a call to SendMessage, which we are going to see next:

// Sends the message typed in to the server

private void SendMessage()

{

if (txtMessage.Lines.Length >= 1)

{

swSender.WriteLine(txtMessage.Text);

swSender.Flush();

txtMessage.Lines = null;

}

txtMessage.Text = “”;

}

Quite simple, isn’t it? It just checks for the number of lines to be greater or equal to 1, and then writes that line to the TCP connection through the StreamWriter object. Calling Flush() ensures that the messages are being sent right away.

We seem to be almost done with the client application. But let’s not forget that when btnConnect was clicked, if we were already connected, we called a method called CloseConnection() – what happened to that? Well here it is:

// Closes a current connection

private void CloseConnection(string Reason)

{

// Show the reason why the connection is ending

txtLog.AppendText(Reason + “\r\n”);

// Enable and disable the appropriate controls on the form

txtIp.Enabled = true;

txtUser.Enabled = true;

txtMessage.Enabled = false;

btnSend.Enabled = false;

btnConnect.Text = “Connect”;

 

// Close the objects

Connected = false;

swSender.Close();

srReceiver.Close();

tcpServer.Close();

}

The form is being brought back to the not-connected state, and the TCP connection and streams are being closed. But what happens if the user doesn’t click Disconnect and just closes the application while the connection with the server is alive? We surely don’t want to leave the connection open like this till it dies by its own. Thankfully there is the ApplicationExit event that fires when the application closes, and that’s where we can close our connection. To hook up the event change your Form1 constructor to the following:

public Form1()

{

// On application exit, don’t forget to disconnect first

Application.ApplicationExit += new EventHandler(OnApplicationExit);

InitializeComponent();

}

And here is the event handler that does the actual disconnection:

// The event handler for application exit

public void OnApplicationExit(object sender, EventArgs e)

{

if (Connected == true)

{

// Closes the connections, streams, etc.

Connected = false;

swSender.Close();

srReceiver.Close();

tcpServer.Close();

}

}

Believe or not, we’re done with the chat client application. You should be able to compile and run it now, but of course there’s nothing to connect to because we haven’t developed the server. But that comes next in C# Chat: Part 2- Building the Chat Server. Here’s a little teaser of our applications in action, with the server in the shadow of the two:

Chat Clients

Spring supports remoting for six different RPC models:

Spring supports remoting for six different RPC models:

1. Remote Method Invocation (RMI)

2. Hessian

3. Burlap

4. HTTP invoker

5. EJB

6. JAX-RPC

In all the models, services are configured into the application through spring configuration file as spring managed beans. This is accomplished by using a proxy factory bean that enable us to wire remote services into the properties of our beans as if they were local objects.

Spring provides ‘RmiProxyFactoryBean‘ to use the RMI service and ‘RmiServiceExporter’ to export any spring managed bean as a RMI service.

For wiring a Hessian based service to Spring client, Spring’s ‘HessianProxyFactory Bean’ is used. To export a Hessian Service ‘HessianServiceExporter’ is used and similarly for wiring a Burlap service ‘BurlapProxyFactoryBean’ is used and ‘BurlapServiceExporter’ is used to export a burlap service.

For exporting beans as HTTP invoker services, ‘HttpInvokerServiceExporter‘ is used .To access an HTTP invoker service ‘HttpInvokerProxyFactoryBean‘ can be used.

Spring provides two proxy factory beans to access the Enterprise Java Beans. ‘LocalStatelessSessionProxyFactoryBean’ is used to access the EJB in the same container(local) and another one is

‘SimpleRemoteStatelessSessionProxyFactoryBean’ which is used to access the remote EJBs.

For all the above models spring provides service exporter classes that exports Java Beans as remote service. Spring does not provide any EJB Service Exporter and it provides four abstract support classes to make the development of Spring enabled EJB. They are 

1. AbstractMessageDrivenBean to develop MDBs that accept sources other than JMS.

2. AbstractJmsMessageDrivenBean to develop MDBs that accept messages from JMS sources.

3. AbstractStatelessSessionBean to develop stateless session bean.

4. AbstractStstefulSessionBean to develop stateful session bean.  

‘JaxRpcPostProxyFactoryBean’ is used to wire a web service into the spring application.

The client makes calls to the proxy to provide the service and the proxy calls the remote service on behalf of the client.

——————————————–

Now we shall see how to wire other RMI services into spring application and also how to export our own service.

Remote Method Invocation (RMI) Model:

RMI was first introduced in JDK 1.1.  But developing and accessing  RMI services involves various steps and also have lookups which makes the code hard to test. Spring simplifies the RMI by providing a ‘proxy factory bean’ that enables us to wire the RMI services into spring application as if they were local beans. Spring also provides a remote exporter that converts our ‘spring managed beans’ into RMI services.

Spring’s ‘RmiProxyFactoryBean’ is a factory bean that creates a proxy to RMI service. It is declared spring configuration file under the <bean> tag as follows,

<bean  id=”service1″ 

   class=”org.springframework.remoting.rmi.RmiProxyFactoryBean”>

   <property name=”serviceUrl“>

  <value>rmi://${hostname}/service1</value>  

   </property>

   <property name=”serviceInterface”>

  <value>service1</value>

   </property>

</bean>

The url of the RMI service is set through the ‘serviceUrl’ property. The ‘serviceInterface’ property specifies the interface that the service implements and only through that the client invokes methods on the service.

For using the service the implementation  code is wired to the RMI using the following code,

<bean id=”serviceimpl”>

   <property name=”service1″>

   <ref bean=”service1″/>

   </property>

</bean>

——————————————-

First set the path and classpath as before. Next edit the RMI service.

//f:\springdemo\rmserver.java

import java.rmi.*;

public  interface  rmserver  extends Remote

{

   String   getresult(String   s)  throws RemoteException;

}

———————————————-

//f:\springdemo\rmserverimpl.java

import java.rmi.*;

import java.rmi.server.*;

public class rmserverimpl extends UnicastRemoteObject

   implements rmserver

{

   public static void main(String args[])

   {

  try

  {

   rmserverimpl   ob = new rmserverimpl();

   Naming.rebind(“rmserver”,ob);

   System.out.println(“ready”);

  }

  catch(Exception e1)

   {System.out.println(“”+e1);}

   }

   public rmserverimpl() throws RemoteException

   {

   System.out.println(“constructor ok”);

   }

   public String getresult(String  a)  throws RemoteException

   {

   return “Hai…”+a;

   }

}

———————————————-

//f:\springdemo\rmserver.xml

<?xml version=”1.0″ encoding=”UTF-8″?>

<!DOCTYPE beans PUBLIC “-//SPRING//DTD BEAN//EN”

http://www.springframework.org/dtd/

 spring-beans.dtd”>

<beans>

  <bean id=”rmserver”

  class=”org.springframework.remoting.rmi.RmiProxyFactoryBean”>

   <property name=”serviceUrl”>

   <value>rmi://localhost/rmserver</value>  

   </property>

   <property name=”serviceInterface”>

   <value>rmserver</value>

   </property>

  </bean>

  <bean   id=”rmserverimpl”  class=”rmserverimpl”>

    <property name=”rmserver”>

  <ref bean=”rmserver”/>

  </property>

  </bean>

</beans>

———————————————

//f:\springdemo\rmspring.java

import java.rmi.*;

import org.springframework.beans.factory.*;

import org.springframework.beans.factory.xml.*;

import org.springframework.core.io.*;

public class  rmspring

{

   public static void main(String args[])

   {

  try

  {

   System.out.println(“Wait..”);

   Resource   res = new ClassPathResource(“rmi.xml”);

   BeanFactory   factory = new XmlBeanFactory(res);

   rmserver bean1 = (rmserver) factory.getBean(“rmserver”);

   String r=bean1.getresult(args[0]);

   System.out.println(r);

  }

  catch(Exception e1)

  {System.out.println(“”+e1);}

   }

}

—————————————

To run:

f:\springdemo>javac rmserver.java

f:\springdemo>javac rmserverimpl.java

f:\springdemo>rmic rmserverimpl (To create stub and skeleton)

f:\springdemo>javac rmspring.java

f:\springdemo>start rmiregistry (a blank window will appear)

f:\springdemo>java rmserverimpl

Open another Window and run the client code by giving the argument

f:\springdemo>java rmspring “sam”

We will get the output as:

Wait..
……
Hai… sam

Here we have removed the ‘lookup’ code in the client side.

—————————————————————–

Spring also supports the server side of RMI. Here the service itself is written with spring and it is exposed as an RMI service. Here the bean is written as a simple JavaBean. Also we need not generate the stub and skeleton using ‘rmic’ command and manually add it to RMI registry. Instead of these traditional procedure ‘RmiServiceExporter’ is used to export any Spring managed bean as an RMI service. It wrapps the bean in an adapter class. The adapter class is then bound to RMI registry and the proxies request the service.

<bean   class=”org.springframework.remoting.rmi.RmiServiceExporter“>

   <property name=”service1″>

   <ref bean=”service1″/>

   </property>

   <property name=”serviceName”>

  <value>service1</value>

   </property>

   <property name=”serviceInterface”>

  <value>service1</value>

   </property>

</bean>

The ‘serviceName property’ indicates the name of service and ‘serviceInterface’ specifies the interface implemented by the service. There is no need of ‘serviceUrl’ here

First set the path and classpath as before. Next edit the service.

//f:\springdemo\rmservice.java

public  interface  rmservice

{

  String   getresult(String  s);

}
——————————————

//f:\springdemo\rmserviceimpl.java

public class rmserviceimpl  implements  rmservice

{

   public static void main(String args[])

   {

  System.out.println(“ready”);

   }

   public rmserviceimpl()

   {

  System.out.println(“constructor ok”);

   }

   public String getresult(String  a)

   {

  return “Hai”+a;

   }

}

——————————————

//f:\springdemo\rmservice.xml

<?xml version=”1.0″ encoding=”UTF-8″?>

<!DOCTYPE beans PUBLIC “-//SPRING//DTD BEAN//EN”

http://www.springframework.org/dtd/  spring-beans.dtd”>

  <beans>

   <bean 3″>remoting.rmi.RmiServiceExporter”>

   <property name=”service”>

   <value>rmservice</value>  

   </property>

   <property name=”serviceName“>

   <value>service1</value>  

   </property>

   <property name=”serviceInterface“>

   <value>rmservice</value>

   </property>

   </bean>

   <bean id=”rmservice”>

   </bean>

</beans>

——————————————

//f:\springdemo\rmserviceclient.java

import java.io.*;

import org.springframework.beans.factory.*;

import org.springframework.beans.factory.xml.*;

import org.springframework.core.io.*;

class   rmserviceclient

{

   public static void main(String args[])

   {

  try

  {

   System.out.println(“Wait..”);

   Resource  res = new ClassPathResource(“rmservice.xml”);

   BeanFactory  factory = new  XmlBeanFactory(res);

   System.out.println(“factory created”);

   rmservice bean1 = (rmservice)factory.getBean(“rmservice”);

   String s = bean1.getresult(args[0]);

   System.out.println(s);

  }

  catch(Exception e1)

   {System.out.println(“”+e1);}

   }

}

—————————————

To run:

f:\springdemo>javac rmservice.java

f:\springdemo>javac rmserviceimpl.java

f:\springdemo>javac rmserviceclient.java

f:\springdemo>java rmsserviceclient

We will get Output as:

Wait..

Feb 12, 2012 10:55:07 PM  

   org.springframework.beans.factory.

   xml.XmlBeanDefinitionReader

   loadBeanDefinitions

INFO: Loading XML bean definitions from

  class path resource[rmservice.xml]

Feb 12, 2012 10:55:07 PM

   org.springframework.beans.factory.

   support.AbstractBeanFactory getBean

INFO: Creating shared instance of

  singleton bean ‘rmservice’

constructor   ok

Hai…sam  

Here the service interface doesn’t extend the ‘java.rmi.Remote’ method and ‘RemoteException’ is not thrown by the methods. There is no binding in the implementation code. Also we can direcly run the client. No run to run ‘rmserverimpl’ first. Also there is no need to run the RMI registry.

Web Services – Web Services Tutorials

In this section of the Web Services tutorial you will be familiarized with the Web Services.

Introduction

The next generation of distributed computing has arrived. A Web service is a unit of managed code that can be remotely invoked using HTTP, that is, it can be activated using HTTP requests.

Historically speaking, remote access to binary units required platform-specific and sometimes language-specific protocols. For example, DCOM clients access remote COM types using tightly coupled RPC calls. CORBA requires the use of tightly coupled protocol referred to as Internet Inter-ORB Protocol (IIOP), to activate remote types. Enterprise JavaBeans (EJBs) requires a Remote Method Invocation (RMI) Protocol and by and large a specific language (Java). Thus each of these remote invocation architectures needs proprietary protocols, which typically require a tight connection to the remote source.

One can access Web services using nothing but HTTP. Of all the protocols in existence today, HTTP is the one specific wire protocol that all platforms tend to agree on. Thus , using Web services, a Web service developer can use any language he wish and a Web service consumer can use standard HTTP to invoke methods a Web service provides. The bottom line is that we have true language and platform integration . Simple Object Access Protocol (SOAP) and XML are also two key pieces of the Web services architecture.

What is a Web Service

Web services constitute a distributed computer architecture made up of many different computers trying to communicate over the network to form one system. They consist of a set of standards that allow developers to implement distributed applications – using radically different tools provided by many different vendors – to create applications that use a combination of software modules called from systems in disparate departments or from other companies.

A Web service contains some number of classes, interfaces, enumerations and structures that provide black box functionality to remote clients. Web services typically define business objects that execute a unit of work (e.g., perform a calculation, read a data source, etc.) for the consumer and wait for the next request. Web service consumer does not necessarily need to be a browser-based client. Console-baed and Windows Forms-based clients can consume a Web service. In each case, the client indirectly interacts with the Web service through an intervening proxy. The proxy looks and feels like the real remote type and exposes the same set of methods. Under the hood, the proxy code really forwards the request to the Web service using standard HTTP or optionally SOAP messages.

Web Service Standards

Web services are registered and announced using the following services and protocols. Many of these and other standards are being worked out by the UDDI project, a group of industry leaders that is spearheading the early creation and design efforts.

Universal Description, Discovery, and Integration (UDDI) is a protocol for describing available Web services components. This standard allows businesses to register with an Internet directory that will help them advertise their services, so companies can find one another and conduct transactions over the Web. This registration and lookup task is done using XML and HTTP(S)-based mechanisms.

Simple Object Access Protocol (SOAP) is a protocol for initiating conversations with a UDDI Service. SOAP makes object access simple by allowing applications to invoke object methods or functions, residing on remote servers. A SOAP application creates a request block in XML, supplying the data needed by the remote method as well as the location of the remote object itself.

Web Service Description Language (WSDL), the proposed standard for how a Web service is described, is an XML-based service IDL (Interface Definitition Language) that defines the service interface and its implementation characteristics. WSDL is referenced by UDDI entries and describes the SOAP messages that define a particular Web service.

ebXML (e-business XML) defines core components, business processes, registry and repository, messaging services, trading partner agreements, and security.

Implementing Web Services

Here comes a brief step-by-step on how a Web service is implemented.

  • A service provider creates a Web service
  • The service provider uses WSDL to describe the service to a UDDI registry
  • The service provider registers the service in a UDDI registry and/or ebXML registry/repository.
  • Another service or consumer locates and requests the registered service by querying UDDI and/or ebXML registries.
  • The requesting service or user writes an application to bind the registered service using SOAP in the case of UDDI and/or ebXML
  • Data and messages are exchanged as XML over HTTP

Web Service Infrastructure

Even though Web services are being built using existing infrastructure, there exists a strong necessity for a number of innovative infrastructures. The core architectural foundation of Web services are XML, XML namespaces, and XML schema. UDDI, SOAP, WSDL, ebXML and security standards are being developed in parallel by different vendors

Web Services Technologies and Tools

There are a number of mechanisms for constructing Web services. Microsoft has come out with a new object-oriented language C# as the development language for Web services and .NET framework. Microsoft has an exciting tool called Visual Studio .NET in this regard. The back end database can be Microsoft SQL Server 2000 in Windows 2000 Professional.

Sun Microsystems has its own set of technologies and tools for facilitating Web services development. Java Servlets, Java Server Pages (JSPs), Enterprise JavaBeans (EJB) architecture and other Java 2 Enterprise Edition (J2EE) technologies play a very critical role in developing Web services.

There are a number of tools for developing Web services. They are Forte Java IDE, Oracle JDeveloper, and WebGain Studio.

Sun Microsystems has taken an initiative called Sun ONE (Open Network Environment) and is planning to push Java forward as a platform for Web services. It is developing Java APIs for XML-based remote procedure calls and for looking up services in XML registries – two more JAX family APIs: JAX/RPC (Java API for XML Remote Procedure Calls) and JAXR (Java API for XML Registries). These will wrap up implementations of Web services standards, such as SOAP and UDDI.

IBM also for its part has already developed a suite of early-access tools for Web services development. They are Web Services Toolkit (WSTK), WSDL Toolkit, and Web Services Development Environment (WSDE).

Apache Axis is an implementation of the SOAP (“Simple Object Access Protocol”) submission to W3C.

From the draft W3C specification:

SOAP is a lightweight protocol for exchanging structured information in a decentralized, distributed environment. It is an XML based protocol that consists of three parts: an envelope that defines a framework for describing what is in a message and how to process it, a set of encoding rules for expressing instances of application-defined datatypes, and a convention for representing remote procedure calls and responses.

Apache Axis is an Open Source SOAP server and client. SOAP is a mechanism for inter-application communication between systems written in arbitrary languages, across the Internet. SOAP usually exchanges messages over HTTP: the client POSTs a SOAP request, and receives either an HTTP success code and a SOAP response or an HTTP error code. Open Source means that you get the source, but that there is no formal support organization to help you when things go wrong.

Conclusion

For the last few years, XML has enabled heterogeneous computing environments to share information over the Web. It now offers a simplified means by which to share process as well. From a technical perspective, the advent of Web services is not a revolution in distributed computing. It is instead a natural evolution of XML application from structured representation of information to structured representation of inter-application messaging.

Prior to the advent of Web services, enterprise application integration (EAI) was very difficult due to differences in programming languages and middleware used within organizations. This led to the situation where interoperability was cumbersome and painful. With the arrival of Web services, any application can be integrated as long as it is Internet-enabled.

It is difficult to avoid the popularity and hype that is surrounding Web services. Each software vendor has some initiative concerning Web services and there is always great speculation about the future of the market for them. Whichever way it turns out, Web service architectures provide a very different way of thinking about software development. From client-server to n-tier systems, to distributed computing, Web service applications represent the culmination of each of these architectures in combination with the Internet.