Logging in C# with log4net

logging

There are some examples out there, but I’ve found that most of are either too complicated or are too specific.
In the end I decided that the only way to fix the problem is to write a general tutorial on Log4Net configuration myself.

Basics

Use NuGet to download and install the latest version of Log4Net.

nuget

Config files

Now you need to configure Log4Net.

Read More »

 

Google Map Geocoding Tutorial with Example

google-map-reverse-geocodingGoogle Map API has been a great way to show geographical information on web. A lot of mashup tools like this, have been created around Google Maps to show a wide variety of data. In my previous article about Introduction to Google Maps API, I had described basic APIs to integrate Google Map in your webpage. In this small article we will discuss a great feature of Google Maps API that can be used to locate any City/Country/Place on Map. This is called Geocoding.
20756_Free Shipping Plus VIP Exclusive Perks & Savings with code: CX13J027
Google Maps API provides a wonderful API called Geocoding API that enables you to fetch any location and pin point it on Google Map. GClientGeocoder is the class that we use to get the geocoder that get us the location. We will use getLatLng() method to get latitude/longitude of any location.
Check the following code.

var place =  "New York";
geocoder = new GClientGeocoder();
geocoder.getLatLng(place, function(point) {
    if (!point) {
        alert(place + " not found");
    } else {
        var info = "<h3>"+place+"</h3>Latitude: "+point.y+"  Longitude:"+point.x;
        var marker = new GMarker(point);
        map.addOverlay(marker);
        marker.openInfoWindowHtml(info);
    }
});

In above code snippet we passed string “New York” and a handler function to getLatLng() method of GClientGeocoder. GClientGeocoder class will call google server for the location and when it gets the result, it pass the result to the handler function that we specified. Thus handler function will get point (GPoint) object from which we can get the latitude and longitude of location. In above code we have created a marker and placed it on the map.

Online Demo

Google Map Reverse Geocode Example

Create your own Search Engine(Interface) using Google Custom Search API

google-api-real-time-search
Google Custom Search API are wonderful tools to create some awesome search engine like tools. Also if you want to add a search option to your website and customize the look and feel of your search results, Google Custom Search API serve best to you.
Ring in Spring with Stunning Lingerie from Journelle and get $25 OFF purchases of $200 or more! Use promo code: SPRING200. Offer valid 2/22/13-4/30/13. Shop Now

I have created a Real Time Search engine (I call it real time as it search as you type). I am really impressed by the speed/response of Google Search API.

DEMO

google-search-technology

DEMO

The Code

I will show the code for one of the search api that I implemented in demo page. Let us see how to implement Web Search API.

Step 1: Generate Google Search API Key and Include JavaScript

In order to use Google Search API, you have to first generate a Key for you. Go to following page and signup your self for the Key.
Sign up for Google API Key

Next step is to include the Google Search API javascript. Don’t forget to mention your key in the below code.

<script src="http://www.google.com/jsapi?key=YOURKEY" type="text/javascript"></script>
<script type="text/javascript">
    google.load('search', '1');
</script>

Primary

Step 2: Add HTML Container for Web Search

We will create a textbox and a button that will take input for search. And a DIV that will be populated by results:

<input type="text" title="Real Time Search" name="searchbox"/>
<input type="button" id="searchbtn" value="Search" onclick="search(searchbox.value)"/>
<div class="data" id="web-content"></div>

When user will write a query and push Search button, a request will be made to Google Search using Custom Search API and the results are fetched. These results are then copied into the DIV.

Step 3: JavaScript to call Google Search API

We will use following JavaScript to call the Google Search API and copy the results in our container DIV.
The code in plain english is:
1. Create an object to connect Google Web search using class google.search.WebSearch.
2. Set a callback function that will get call once the results for the search are fetched.
3. Call the execute() method with search query as argument.
4. In callback function, iterate through the results and copy it to container DIV.

webSearch = new google.search.WebSearch();
webSearch.setSearchCompleteCallback(this, webSearchComplete, [webSearch]);
function webSearchComplete (searcher, searchNum) {
    var contentDiv = document.getElementById('web-content');
    contentDiv.innerHTML = '';
    var results = searcher.results;
    var newResultsDiv = document.createElement('div');
    newResultsDiv.id = 'web-content';
    for (var i = 0; i < results.length; i++) {
      var result = results[i];
      var resultHTML = '<div>';
      resultHTML += '<a href="' + result.unescapedUrl + '" target="_blank"><b>' +
                        result.titleNoFormatting + '</b></a><br/>' +
                        result.content +
                        '<div/>';
      newResultsDiv.innerHTML += resultHTML;
    }
    contentDiv.appendChild(newResultsDiv);
}
function search(query) {
    webSearch.execute(query);
}

Click for Online Demo

Enhanced by Zemanta

Deploying Java Servlet applications on Windows with IIS

IIS

Java platform is extremely successful in building robust and high performance web applications. Platform independence is one of the strength of Java engine and Helicon Zoo now provides a convenient way to deploy and run Java web applications on Windows platform with Microsoft IIS. To deploy Java Servlet application on IIS 7 you will only need to follow this simple instruction:

Platfrom installation

  1. Download and install Web Platform Installer.
  2. Run Web Platform Installer and click “Options”.
  3. Add Helicon Zoo feed into Display additional scenarios box:  http://www.helicontech.com/zoo/feed. New “Zoo” tab will appear.
  4. Go to the Zoo, Packages and install Java Hosting Package.
  5. Accept licenses to start installation process.

Alternatively, instead of installing Java Hosting Package you can install Modules –> Helicon Zoo Module and Engines –> Jetty separately. This is minimal requirement to run Java Servlet applications under Microsoft IIS web server. If you want to run Java Servlets under IIS Express and WebMatrix in your development environment, then you will also need to install Helicon Zoo Module for IIS Express form Engines section.

This is enough configuration to run most of Java Servlet applications directly form IIS.

Installing application

Launch IIS Manager and create new web-site or an application within a web-site. Copy your Java application into the root folder of this IIS application. Java application could be either a single .war file or set of unpacked files with directory structure, including web-inf folder. Then just create the following web.config:

 <?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <heliconZoo>
      <application name="jetty.project" >
        <environmentVariables>
          <!-- Uncomment line below if you want to set contexts directory -->
          <!--  <add name="CONTEXTS_DIR" value="%APPL_VIRTUAL_PATH%" /> -->

          <!-- Optional variables: -->
          <!-- <add name="CONTEXT_PATH" value="%APPL_VIRTUAL_PATH%" /> -->
          <!-- <add name="WAR_EXTRACT_PATH" value="%APPL_PHYSICAL_PATH%" /> -->

          <!-- A WAR file or start directory to run -->
          <add name="WAR_FILE" value="my_application.war" />
        </environmentVariables>
        </application>
    </heliconZoo>

        <handlers>
          <add name="jetty.project#x86" scriptProcessor="java.jetty"
            path="*" verb="*" modules="HeliconZoo_x86"
            preCondition="bitness32" resourceType="Unspecified"
            requireAccess="Script" />
          <add name="jetty.project#x64" scriptProcessor="java.jetty"
            path="*" verb="*" modules="HeliconZoo_x64"
            preCondition="bitness64" resourceType="Unspecified"
            requireAccess="Script" />
        </handlers>
  </system.webServer>
</configuration>

Please take a look at <environmentVariables> section.

  • CONTEXTS_DIR — optional path to directory with .xml files which describe Jetty contexts. If this variable isn’t set, Zoo looks for “contexts” folder in the root of application. If no such folder found, Zoo presumes the application has single context and uses variables described below.
  • CONTEXT_PATH — optional virtual path of the application. Default value is taken from APPL_VIRTUAL_PATH variable.
  • WAR_FILE — optional path to a .war file or directory with extracted application.
  • WAR_EXTRACT_PATH — optional .war file extraction path. Is set to application’s root folder by default.

Here is an example of context.xml file that you may use instead of setting WAR file name explicitly. This allows to run multiple applications and contexts in a single IIS web site.

contexts/context.xml

<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">

<Configure class="org.eclipse.jetty.webapp.WebAppContext">

   <Set name="contextPath">/application</Set>
   <Set name="war">my_application.war</Set>
   <Set name="tempDirectory">application_dir</Set>

</Configure>

WARNING: Since WAR files need to be extracted before execution you will need to have a folder with write permissions.  In default IIS installation all application pools are executed with permissions of IIS_IUSRS group which does not have write permissions to the web application folders. You will need to provide write permissions to the user running Application Pool or IIS_IUSRS group to the folder containing Java application or specify other folder using WAR_EXTRACT_PATH variable with write permissions provided.Now you can open IIS web site in the browser and see your Java web application running.

That’s it! Installation process is clear and automatic and will only take several minutes.

5 Responses to Deploying Java Servlet applications on Windows with IIS

  1. Peter says:

    Downloaded and installed as described in the article (http://www.helicontech.com/articles/deploying-java-servlet-applications-on-windows-with-iis/).

    However for some weird reason I can successfully view the Java app via IIS when using http://localhost/appname but if I do the same thing http:///appname on another machine I get a a 404 from IIS and if I do it on the server itself I get a 404 from Jetty instead.

    This is running on a 64bit Win2008R2 Std server VM with an IIS app set up to use a ASP.NET 4.0 integrated app pool.
    The folder the IIS app points to contains the contents of the WAR file, i.e. \web-inf and \xforms-jsp and the web.config with the described contents from the article.

    Any ideas on what could be wrong would be much appreciated.

    • Slavik says:

      Hello.
      Please try and use CONTEXT_PATH variable as follows:
      <add name=”CONTEXTS_PATH” value=”/appname” />

      Make sure “appname” is an application. If it’s not, open IIS manager, navigate to that folder and in the context menu click “Convert to Application”.

  2. jules says:

    I installed on a Windows 7 64 bit machine and then downloaded the jenkins.war file and tried to deploy it:
    But I get:
    HTTP ERROR: 503
    Problem accessing /test. Reason:
    Service Unavailable
    Powered by Jetty://

    ??

    • Slov says:

      I think installing Jenkins on IIS may deserve a separate article.
      First you will need to upgrade your Jetty installation as we have fixed some functions. Just delete C:\jetty folder and install again using Helicon Zoo feed.
      Then you will need to use contexts folder, instead of setting WAR file explicitly as Jenkins require additional configurations.
      Please remove all “environmentVariables” from web.config, create contexts folder, and create context.xml file in this folder with the following content:

      < ?xml version=”1.0″?>
      < !DOCTYPE Configure PUBLIC “-//Jetty//Configure//EN” “http://www.eclipse.org/jetty/configure.dtd”&gt;

      Test Realm
      /jenkins
      jenkins.war

      After that navigate to http://localhost/jenkins (not to the root folder). It should work now.

      • Slov says:

        A bug with tags. Try again:

        <?xml version=”1.0″?>
        <!–DOCTYPE Configure PUBLIC “-//Jetty//Configure//EN” “http://www.eclipse.org/jetty/configure.dtd”>–>

        <Configure class=”org.eclipse.jetty.webapp.WebAppContext”>
        <Get name=”securityHandler”>
        <Set name=”loginService”>
        <New class=”org.eclipse.jetty.security.HashLoginService”>
        <Set name=”name”>Test Realm</Set>
        </New>
        </Set>
        </Get>

        <Set name=”contextPath”>/jenkins</Set>
        <Set name=”war”>jenkins.war</Set>
        <Set name=”tempDirectory”>jenkins</Set>
        </Configure>

Reference :http://www.helicontech.com/articles/deploying-java-servlet-applications-on-windows-with-iis/

C# Chat: Part 2 – Building the Chat Server

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

This is the second part of a tutorial that teaches you how to create a C# chat application. In Part 1 – Building the Chat Clientwe’ve looked at how to create the chat application that connects to a chat server, and here we now look at how to build the chat server.

The Chat Server

The Chat Server application is a tad more complex than the Chat Client application because it needs to hold information on all the connected clients, await for messages from each and send incoming messages to all. I commented all the code so hopefully you won’t have any problems figuring it out without much commentary on the side from me.

Fire up a new instance of Visual Studio 2005 and in a new Windows Application project draw the following form:

Chat Server

The only controls we are interested in are the two TextBoxes (txtIp and txtLog) and the btnListen button. The IP address inside txtIp is the one where you want your chat server to be listening for incoming connections. You should use your local IP address, which if you’re not in a network it could be 192.168.0.1, but it’s best that you check using the ipconfig /all command in the MS-DOS Command Prompt window. The multi-line TextBox will hold information about connected clients and the messages that they are exchanging.

In the code view, start with the following using statements:

using System.Threading;

using System.Net;

using System.Net.Sockets;

using System.IO;

Move inside the class and declare a delagate which we will need in order to update the txtLog TextBox from another thread :

private delegate void UpdateStatusCallback(string strMessage);

Double-click the Start Listening button and you should arrive to it Click event. Have the event handler look like this:

private void btnListen_Click(object sender, EventArgs e)

{

// Parse the server’s IP address out of the TextBox

IPAddress ipAddr = IPAddress.Parse(txtIp.Text);

// Create a new instance of the ChatServer object

ChatServer mainServer = new ChatServer(ipAddr);

// Hook the StatusChanged event handler to mainServer_StatusChanged

ChatServer.StatusChanged += new StatusChangedEventHandler(mainServer_StatusChanged);

// Start listening for connections

mainServer.StartListening();

// Show that we started to listen for connections

txtLog.AppendText(“Monitoring for connections…\r\n”);

}

A couple of objects are being instantiated, including a ChatServer object. We will write the ChatServer class very soon, and you will see that it handles all the incoming connections. In turn, it will make use of another class that we will write, called Connection.
The next thing we do is to set up an event handler for the StatusChanged event, which is a custom event that we’re going to write very soon. It will inform us when a client has connected, a new message has been received, a client has disconnected, etc.
Finally the StartListening() method tells the ChatServer object to start listening for incoming connections.

Believe it or not, there are only a few more lines of code to go in this class. One of them is the event handler that we hooked earlier, and the other is the UpdateStatus() method that gets called when an update needs to be made to the form. It’s needed because we use Invoke() and the delegate we created earlier to make a cross-thread call (since the ChatServer will be working in a different thread):

public void mainServer_StatusChanged(object sender, StatusChangedEventArgs e)

{

// Call the method that updates the form

this.Invoke(new UpdateStatusCallback(this.UpdateStatus), new object[] { e.EventMessage });

}

private void UpdateStatus(string strMessage)

{

// Updates the log with the message

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

}

And we’re done. Done with the Form1 class, of course. You should now create another file (I called mine ChatServer.cs) and inside it make sure you have all these using statements:

using System;

using System.Collections.Generic;

using System.Text;

using System.Net;

using System.Net.Sockets;

using System.IO;

using System.Threading;

using System.Collections;

We’ll need to use an event that notifies the form class when a new client has connected, disconnected, sent a message, etc. In order to create our own custom event, we need to first define its arguments. More exactly we want a string argument that tells us what type of event has occured (user has connected, user has disconnected, user x says y, etc..) If you’re not familiar with events and delegates you might want to read the Delegates and Events in C# tutorial from a week ago. Here is the class that gets and sets the event arguments:

// Holds the arguments for the StatusChanged event

public class StatusChangedEventArgs : EventArgs

{

// The argument we’re interested in is a message describing the event

private string EventMsg;

// Property for retrieving and setting the event message

public string EventMessage

{

get

{

return EventMsg;

}

set

{

EventMsg = value;

}

}

// Constructor for setting the event message

public StatusChangedEventArgs(string strEventMsg)

{

EventMsg = strEventMsg;

}

}

Moving on, outside this class we declare the actual delegate for the event handler:

// This delegate is needed to specify the parameters we’re passing with our event

public delegate void StatusChangedEventHandler(object sender, StatusChangedEventArgs e);

And now before we actually get to fire this event, we define the ChatServer class, in all its glory. Remember this is the class that we used back in Form1.cs:

class ChatServer

{

// This hash table stores users and connections (browsable by user)

public static Hashtable htUsers = new Hashtable(30); // 30 users at one time limit

// This hash table stores connections and users (browsable by connection)

public static Hashtable htConnections = new Hashtable(30); // 30 users at one time limit

// Will store the IP address passed to it

private IPAddress ipAddress;

private TcpClient tcpClient;

// The event and its argument will notify the form when a user has connected, disconnected, send message, etc.

public static event StatusChangedEventHandler StatusChanged;

private static StatusChangedEventArgs e;

// The constructor sets the IP address to the one retrieved by the instantiating object

public ChatServer(IPAddress address)

{

ipAddress = address;

}

// The thread that will hold the connection listener

private Thread thrListener;

// The TCP object that listens for connections

private TcpListener tlsClient;

// Will tell the while loop to keep monitoring for connections

bool ServRunning = false;

// Add the user to the hash tables

public static void AddUser(TcpClient tcpUser, string strUsername)

{

// First add the username and associated connection to both hash tables

ChatServer.htUsers.Add(strUsername, tcpUser);

ChatServer.htConnections.Add(tcpUser, strUsername);

// Tell of the new connection to all other users and to the server form

SendAdminMessage(htConnections[tcpUser] + ” has joined us”);

}

// Remove the user from the hash tables

public static void RemoveUser(TcpClient tcpUser)

{

// If the user is there

if (htConnections[tcpUser] != null)

{

// First show the information and tell the other users about the disconnection

SendAdminMessage(htConnections[tcpUser] + ” has left us”);

// Remove the user from the hash table

ChatServer.htUsers.Remove(ChatServer.htConnections[tcpUser]);

ChatServer.htConnections.Remove(tcpUser);

}

}

// This is called when we want to raise the StatusChanged event

public static void OnStatusChanged(StatusChangedEventArgs e)

{

StatusChangedEventHandler statusHandler = StatusChanged;

if (statusHandler != null)

{

// Invoke the delegate

statusHandler(null, e);

}

}

// Send administrative messages

public static void SendAdminMessage(string Message)

{

StreamWriter swSenderSender;

// First of all, show in our application who says what

e = new StatusChangedEventArgs(“Administrator: ” + Message);

OnStatusChanged(e);

// Create an array of TCP clients, the size of the number of users we have

TcpClient[] tcpClients = new TcpClient[ChatServer.htUsers.Count];

// Copy the TcpClient objects into the array

ChatServer.htUsers.Values.CopyTo(tcpClients, 0);

// Loop through the list of TCP clients

for (int i = 0; i < tcpClients.Length; i++)

{

// Try sending a message to each

try

{

// If the message is blank or the connection is null, break out

if (Message.Trim() == “” || tcpClients[i] == null)

{

continue;

}

// Send the message to the current user in the loop

swSenderSender = new StreamWriter(tcpClients[i].GetStream());

swSenderSender.WriteLine(“Administrator: ” + Message);

swSenderSender.Flush();

swSenderSender = null;

}

catch // If there was a problem, the user is not there anymore, remove him

{

RemoveUser(tcpClients[i]);

}

}

}

// Send messages from one user to all the others

public static void SendMessage(string From, string Message)

{

StreamWriter swSenderSender;

// First of all, show in our application who says what

e = new StatusChangedEventArgs(From + ” says: ” + Message);

OnStatusChanged(e);

// Create an array of TCP clients, the size of the number of users we have

TcpClient[] tcpClients = new TcpClient[ChatServer.htUsers.Count];

// Copy the TcpClient objects into the array

ChatServer.htUsers.Values.CopyTo(tcpClients, 0);

// Loop through the list of TCP clients

for (int i = 0; i < tcpClients.Length; i++)

{

// Try sending a message to each

try

{

// If the message is blank or the connection is null, break out

if (Message.Trim() == “” || tcpClients[i] == null)

{

continue;

}

// Send the message to the current user in the loop

swSenderSender = new StreamWriter(tcpClients[i].GetStream());

swSenderSender.WriteLine(From + ” says: ” + Message);

swSenderSender.Flush();

swSenderSender = null;

}

catch // If there was a problem, the user is not there anymore, remove him

{

RemoveUser(tcpClients[i]);

}

}

}

public void StartListening()

{

// Get the IP of the first network device, however this can prove unreliable on certain configurations

IPAddress ipaLocal = ipAddress;

// Create the TCP listener object using the IP of the server and the specified port

tlsClient = new TcpListener(1986);

// Start the TCP listener and listen for connections

tlsClient.Start();

// The while loop will check for true in this before checking for connections

ServRunning = true;

// Start the new tread that hosts the listener

thrListener = new Thread(KeepListening);

thrListener.Start();

}

private void KeepListening()

{

// While the server is running

while (ServRunning == true)

{

// Accept a pending connection

tcpClient = tlsClient.AcceptTcpClient();

// Create a new instance of Connection

Connection newConnection = new Connection(tcpClient);

}

}

}

Overwhelmed? It’s really not that complicated if you take it line by line and read the comments. It starts by defining two hash tables. These two hash tables will hold the username and the TCP connection associated with it. We need two of them because at one point we’ll want to retrieve the TCP connection by giving the username, and at some other point we’ll want to retrieve the username by giving the TCP connection. The 30 defines how many users the chat server can hold at one given point, but you can easily go into hundreds if needed, without worrying about a performance decrease.

The AddUser() method is obvious – it adds a new user to the hash tables, and thus to our list of connected chat clients. The RemoveUser() method does the opposite. The OnStatusChanged will fire the StatusChanged event, which is right now handled inside Form1.cs. Thus, it’s our way of updating the form with the latest message from inside this ChatServer object.

The SendAdminMessage sends an administrative message to all connected clients. You can see how it loops through the hash table and attempts to send them the message. If the message didn’t get through, they probably disconnected and we then remove them. This is very similar to what the SendMessage() method does, only that this time it sends a message from a specific chat client to all the others.

The StartListening() method is the one we called inside Form1, and it’s the fire starter, the instigator. It defines the first needed objects and starts a new thread that keeps listening for connections, and that is the KeepListening() method. And that’s where our story continues, because if you look inside the KeepListening() method you will see we create a new object of type Connection. That’s because each user connected to our server will have its own instance of Connection. If there are 10 users currently connected, there will be 10 instances of the Connection object. So let’s look at the final class of our chat server:

// This class handels connections; there will be as many instances of it as there will be connected users

class Connection

{

TcpClient tcpClient;

// The thread that will send information to the client

private Thread thrSender;

private StreamReader srReceiver;

private StreamWriter swSender;

private string currUser;

private string strResponse;

// The constructor of the class takes in a TCP connection

public Connection(TcpClient tcpCon)

{

tcpClient = tcpCon;

// The thread that accepts the client and awaits messages

thrSender = new Thread(AcceptClient);

// The thread calls the AcceptClient() method

thrSender.Start();

}

private void CloseConnection()

{

// Close the currently open objects

tcpClient.Close();

srReceiver.Close();

swSender.Close();

}

// Occures when a new client is accepted

private void AcceptClient()

{

srReceiver = new System.IO.StreamReader(tcpClient.GetStream());

swSender = new System.IO.StreamWriter(tcpClient.GetStream());

// Read the account information from the client

currUser = srReceiver.ReadLine();

// We got a response from the client

if (currUser != “”)

{

// Store the user name in the hash table

if (ChatServer.htUsers.Contains(currUser) == true)

{

// 0 means not connected

swSender.WriteLine(“0|This username already exists.”);

swSender.Flush();

CloseConnection();

return;

}

else if (currUser == “Administrator”)

{

// 0 means not connected

swSender.WriteLine(“0|This username is reserved.”);

swSender.Flush();

CloseConnection();

return;

}

else

{

// 1 means connected successfully

swSender.WriteLine(“1”);

swSender.Flush();

// Add the user to the hash tables and start listening for messages from him

ChatServer.AddUser(tcpClient, currUser);

}

}

else

{

CloseConnection();

return;

}

try

{

// Keep waiting for a message from the user

while ((strResponse = srReceiver.ReadLine()) != “”)

{

// If it’s invalid, remove the user

if (strResponse == null)

{

ChatServer.RemoveUser(tcpClient);

}

else

{

// Otherwise send the message to all the other users

ChatServer.SendMessage(currUser, strResponse);

}

}

}

catch

{

// If anything went wrong with this user, disconnect him

ChatServer.RemoveUser(tcpClient);

}

}

}

It doesn’t look too complicated, does it? There’s the constructor that initializes the TcpClient object, then there’s CloseConnection() which is called when we want to get rid of a currently connected client, and finally there’s AcceptClient() which checks for the username validity and if all is fine, it adds the user to the hash tables. If anything goes bad, it removes the user.

I’ll leave you chew on the code for a while now. It’s pretty much as easy as it can get for a C# based chat/server application, but that also means it can use more error handling. Also if you have any suggestions to improve the code or to fix a bug, feel free to post a comment below.

Chat Server Application

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

Step by step instructions to download and install LoadRunner

In the past few months, HP has done a lot of changes to the download location for various software that they offer. Here are the new and updated step-by-step instructions to download and install HP LoadRunner.

  1. Go to LoadRunner Download location.
  2. Hit TRIALS AND DEMOS dropdown and click HP LOADRUNNER 11.0 EVALUATION. download-loadrunner-trial
  3. You will be asked to sign-in to HP Passport Single Sign On service. In case you’ve not registered earlier, complete the ‘New User registration’ form and you will be redirected to evaluation software terms of use. download-loadrunner-sign-in
  4. Click “I Agree” as shown below download-loadrunner-terms-of-use
  5. Download the two files 1) Software_HP_LoadRunner_11.00_T7177_15013.zip and 2) Software_HP_LoadRunner_11.00_T7177_15013.z01 as shown below. [You can also download this file to read more instructions from HP]download-loadrunner-both-files
  6. The two files shown above are around 3.2 GB (1.5 GB + 1.8GB) in size. It may take around 2-3 hrs to download (depending upon your internet speed)
  7. Make sure both files are present in the same folder and both files have exactly the same name except for the extension (.zip and .z01).
  8. Download and install Winzip or WinRar. (7zip won’t work here)
  9. Double click on the .zip file and you will see .iso file.download-loadrunner-iso-trial
  10. Extract this iso file using your favorite unzipping software.( I prefer a nice and free utility software called 7zip which can be downloaded here.  You can download and install this utility.)
  11. Once extracted, go inside the folder T7177-15013 and open Install.pdf  file.
  12. Install.pdf contains step-by-step instructions on installing LoadRunner on Windows and Unix platform. Just remember that wherever the instructions refer to installation disk you should go to the folder T7177-15013
  13. That’s It. HP LoadRunner is now installed. Enjoy!

Calling Stored Procedures from ASP.NET and VB.NET

The Microsoft Visual Studio .NET logo.

Let us see how can we create and call Stored procedures, in a .NET Environment, i.e Visual Studio.We use .NET 2.0 and Visual Studio 2005 for all the examples.fs

Writing stored procedures has never been easy as Microsoft has almost integrated SQL Server with Visual Studio 2005. In the past most of the developers has wondered can’t we have a good editor for creating stored procedures. One of the main advantage of creating procedures in Visual Studio is it creates the basic stub for you and further more, it has inbuilt syntax checking which makes the job easier for us.

In order to create a stored procedure from Visual Studio, first you need to create a data connection from the Server Explorer and follow the below steps.

Step 1: Open Visual Studio 2005.

Step 2: Create a VB.NET / C# Windows / Web Application  Project.

Step 3: Open the Server Explorer by Selecting View -> Server Explorer.

stored_procedures_VB.NET

Step 4: Create a Data Connection to your server you can do this by Right Clicking on the Data Connection Tree and Selecting “Add New Connection”.

Step 5: It will Prompt for the Provider Type you can select .NET SQL Server Provider as it gives more performance.

Step 6: After giving all the credentials once the connection is active expand the database that you are having.

Step 7: Expand the Stored Procedure Tree.

Step 8: To Create a New Procedure Right Click and Select “Add New Procedure”.

Step 9: The IDE will give you a Stub where you can replace the Name of the Procedure and Arguments.

Those who are familiar with Visual Studio IDE would love to create procedures here rather then doing it in Query Analyzer or in SQL Enterprise Manager, though it doesn’t provide any fancy auto complete drop downs its still the best I believe to create stored procedures.

TIP: The Maximum number of parameters in a stored procedure is 2100.

Calling Stored Procedure

Hope everyone have used SQLCommand / OLEDB Command objects in .NET. Here we can call stored procedures in two different forms, one without using parameter objects which is not recommended for conventional development environments, the other one is the familiar model of using Parameters.

In the first method you can call the procedure using Exec command followed by the procedure name and the list of parameters, which doesn’t need any parameters.

Example:

Dim SQLCon As New SqlClient.SqlConnection
SQLCon.ConnectionString = “Data Source=Server;User ID=User;Password=Password;”
SQLCon.Open()

Calling Stored Procedures with Exec command

SQLCmd.CommandText = “Exec SelectRecords ‘Test’, ‘Test’, ‘Test'”
SQLCmd.Connection = SQLCon ‘Active Connection

The second most conventional method of calling stored procedures is to use the parameter objects and get the return values using them. In this method we need to set the “SQLCommandType” to “StoredProcedure” remember you need to set this explicitly as the the default type for SQLCommand is SQLQuery”.

Here is an example to call a simple stored procedure.

Example – I (A Stored Procedure Returns Single Value)

In order to get XML Results from the Stored Procedure you need to first ensure that your stored procedure is returning a valid XML. This can be achieved using FOR XML [AUTO | RAW | EXPLICIT] clause in the select statements. You can format XML using EXPLICIT Keyword, you need to alter your Query accordingly

‘Set up Connection object and Connection String for a SQL Client
Dim SQLCon As New SqlClient.SqlConnection
SQLCon.ConnectionString = “Data Source=Server;User ID=User;Password=Password;”
SQLCon.Open()SQLCmd.CommandText = “SelectRecords” ‘ Stored Procedure to Call
SQLCmd.CommandType = CommandType.StoredProcedure ‘Setup Command Type
SQLCmd.Connection = SQLCon ‘Active Connection

The procedure can be called by adding Parameters in at least two different methods, the simplest way to add parameters and respective values is using

SQLCmd.Parameters.AddWithValue(“S_Mobile”, “Test”)
SQLCmd.Parameters.AddWithValue(“S_Mesg”, “Test”)
SQLCmd.Parameters.AddWithValue(“LastMsgID”, “”)

In this above method, you doesn’t necessarily know the actually data type that you had in your procedure and all parameters are validated according to the type declared in your procedure but only thing is all the validations will occur in SQL and not in your client code.

We still need to declare the last parameter as Output and we need to do that explicitly as the default type is Input. So here we are going to declare the last parameter as Output by

SQLCmd.Parameters(“LastMsgID”).Direction = ParameterDirection.Outputfs

If you want to declare parameters properly then you need to use the below method to add all the parameters with its data type, direction. Also if you are using stored procedures to update all the rows in a dataset then you need to declare parameters in the below fashion and give SouceColumn value as the Column name in the DataTable.

SQLCmd.Parameters.Add(New SqlClient.SqlParameter(“S_Mobile”, SqlDbType.VarChar, 10, ParameterDirection.Input, False, 30, 0, “”, DataRowVersion.Current, “91000000000”))SQLCmd.Parameters.Add(New SqlClient.SqlParameter(“S_Mesg”, SqlDbType.VarChar, 160, ParameterDirection.Input, False, 30, 0, “”, DataRowVersion.Current, “Calling Stored Procedures from VB.NET”))

SQLCmd.Parameters.Add(New SqlClient.SqlParameter(“LastMsgID”, SqlDbType.BigInt, 5, ParameterDirection.Output, False, 5, 0, “”, DataRowVersion.Current, 0))

‘ The Above Procedure has two input parameters and one output parameter you can notice the same in the “Parameter Direction”
SQLCmd.ExecuteNonQuery() ‘We are executing the procedure here by calling Execute Non Query.

MsgBox(SQLCmd.Parameters(“LastMsgID”).Value) ‘You can have the returned value from the stored procedure from this statement. Its all similar to ASP / VB as the only difference is the program structure.

Example – II (Stored Procedure to get Table Result Set)

In order to get the result sets from the stored procedure, the best way is to use a DataReader to get the results. In this example we are getting the results from the Stored Procedure and filling the same in a DataTable.

Here we need to additionally declare a SQLDataReader and DataTable

Dim SQLDBDataReader As SqlClient.SqlDataReader
Dim SQLDataTable As New DataTableSQLCmd.CommandText = “GetAuthors”
SQLCmd.CommandType = CommandType.StoredProcedure
SQLCmd.Connection = SQLCon
SQLCmd.Parameters.Add(New SqlClient.SqlParameter(“AuthorName”, SqlDbType.VarChar, 100, ParameterDirection.Input, False, 30, 0, “”, DataRowVersion.Current, “Y%”)) SQLDBDataReader = SQLCmd.ExecuteReader() SQLDataTable.Columns.Add(“AuthorName”, GetType(Int32), “”) SQLDataTable.Columns.Add(“AuthorLocation”, GetType(String), “”)

Dim FieldValues(1) As Object ‘A Temporary Variable to retrieve all columns in a row and fill them in Object array

While (SQLDBDataReader.Read)
SQLDBDataReader.GetValues(FieldValues)
SQLDataTable.Rows.Add(FieldValues)

End While

Example – III (Calling Simple Stored Procedure to get XML Result Set)

In order to get XML Results from the Stored Procedure you need to first ensure that your stored procedure is returning a valid XML. This can be achieved using FOR XML [AUTO | RAW | EXPLICIT] clause in the select statements. You can format XML using EXPLICIT Keyword, you need to alter your Query accordingly.

CREATE PROCEDURE GetRecordsXML (@AuthorName varchar(100))
ASSelect Author_ID, Author_Name, Author_Location Where Author_Name LIKE  @AuthorName from Authors FOR XML AUTO

RETURN

When you use the above procedure you can get XML Results with TableName as Element and Fields as Attributes

Dim SQLXMLReader As Xml.XmlReader

SQLCmd.CommandText = “GetAuthorsXML”
SQLCmd.CommandType = CommandType.StoredProcedure
SQLCmd.Connection = SQLCon
SQLCmd.Parameters.Add(New SqlClient.SqlParameter(“AuthorName”, SqlDbType.VarChar, 100, ParameterDirection.Input, False, 30, 0, “”, DataRowVersion.Current, “Y%”))
SQLDBDataReader = SQLCmd.ExecuteReader()

SQLXMLReader = SQLCmd.ExecuteXmlReader()
While (SQLXMLReader.Read)
MsgBox(SQLXMLReader.ReadOuterXml)
End While

You can further process this XML or write XSL to display results in a formatted manner. But in order to get formatted XML Results, we need to use EXPLICIT case which we can see in our next article on SQL Queries & XML.

Find Out Your Visitor’s Position Using HTML5 Geolocation

Geolocation is a way for the user to retrieve their position and share where they are. This can be done in a few ways, by using a GPS as the one in your new smartphone or connected to your computer is the most precise method. But for users without GPS the browser will use your IP and or try to find nearby WLAN stations, however this is not as precise but gives some idea of where they are. Exactly how this is done is not a W3C standard and each browser have their own way to do it.

Even though geolocation is really complicated it’s quite easy for you to implement. In this tutorial I will show you how to retrieve the user’s position and display it on a map using Google Maps. So lets get started.

Step 1. Create the HTML layout

We start of by creating a simple HTML page containing three div tags. One for the current status, one to display the data retrieved and one for displaying the user’s position on a map.

1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html>
  <head>
    <title>HTML5 Geolocation</title>
  </head>
  <body onload="initialize()">
    <div id="status"></div>
    <div id="data"></div>
    <div id="map_canvas" style="width: 640px; height: 480px"></div>
  </body>
</html>

We also include the Google Maps API, it’s important to set sensors=false in the URL, otherwise Google will try to find out the user’s position for us.

The initialize function we’re calling on load will try to fetch the position for us.

Step 2. Retrieve the Position

Next it’s time to create our initialize function which will call the geolocation API to get the position data.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Initialize geolocation
function initialize() {
  if (navigator.geolocation) {
    document.getElementById('status').innerHTML = 'Checking...';
    navigator.geolocation.getCurrentPosition(
      onSuccess,
      onError, {
        enableHighAccuracy: true,
        timeout: 20000,
        maximumAge: 120000
      });
  }
  else {
    document.getElementById('status').innerHTML = 'Geolocation not supported.';
  }
}

First we check if the browser actually supports geolocation. Browser who supports geolocation are Internet Explorer 9, Firefox 3.5+, Chrome 5+, Opera 10.6+ and Safari 5+. So it’s quite widely supported already, but if the user has an old browser we show them a message telling them that geolocation is not supported.

Next we set the status message to “Checking…” to tell the user that we’re trying to fetch the location data since this might take some time. Then we call navigator.geolocation.getCurrentPosition which will try to retrieve the user’s position, it calls the onSuccess function if it succeeds, otherwise it will call the onError. These functions will be created in the next two steps.

There’s also a few optional parameters to the getCurrentPosition function. These are enableHighAccuracy which tells the web browser to try using the clients GPS if possible, the default value for this is false. The timeout parameter tells the browser how long we’re ready to wait to get the position in milliseconds, the default value is infinite. Lastly we have the maximumAge parameter which tells the browser how old the position cache is allowed to be in milliseconds, the default value for maximumAge is 0 which turns off cache completely.

Since geolocation is a big privacy concern the W3C standards requires the user to agree to share their position before the location is sent to the website, so when we call the getCurrentPosition a information bar will be shown to the user where the user has to allow us to get the position, if the user denies the onError will be function will be called.

Tip

Don’t rely fully on getting the user’s location since the user might deny your site from retrieving the position or something might go wrong. Always have a fallback solution if retrieving the position is critical.

Step 3. On Success

Next we add an onSuccess function to our script section. This function will display the data received and call the loadMap function to load our map.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Map position retrieved successfully
function onSuccess(position) {
  var data = '';
  data += 'latitude: ' + position.coords.latitude + '<br/>';
  data += 'longitude: ' + position.coords.longitude + '<br/>';
  data += 'altitude: ' + position.coords.altitude + '<br/>';
  data += 'accuracy: ' + position.coords.accuracy + '<br/>';
  data += 'altitudeAccuracy: ' + position.coords.altitudeAccuracy + '<br/>';
  data += 'heading: ' + position.coords.heading + '<br/>';
  data += 'speed: ' + position.coords.speed + '<br/>';
  document.getElementById('data').innerHTML = data;
  loadMap(position.coords.latitude, position.coords.longitude);
}

This function is quite self explanatory, we build a string with the retrieved data found in the position variable and shows it to our user. You will always get the latitude, longitude and accuracy values but the rest is optional and will probably only be set if the user has a GPS which the data is retrieved from.

Lastly we call the loadMap function and give the latitude and longitude to show where the user is on a map.

Step 4. On Error

Since geolocation is quite complex a lot can go wrong and we need an error handler. There’s four different error codes, 0 is an unknown error, 1 occurs if you deny the browser from retrieving your location, 2 occurs if the browse somehow fails to retrieve the location and 3 if our timeout variable is too short and the timeout expired.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Error handler
function onError(err) {
  var message;
  switch (err.code) {
    case 0:
      message = 'Unknown error: ' + err.message;
      break;
    case 1:
      message = 'You denied permission to retrieve a position.';
      break;
    case 2:
      message = 'The browser was unable to determine a position: ' + error.message;
      break;
    case 3:
      message = 'The browser timed out before retrieving the position.';
      break;
  }
  document.getElementById('status').innerHTML = message;
}

This function is also quite easy to understand, we get the error as a parameter to our function and shows the user a message depending on the error code retrieved.

Step 5. Display the Map

Next we display a map in our map_canvas div. This has really nothing to do with the HTML5 geolocation. So I won’t explain this for you, but it shouldn’t be too hard to understand.

Tip

If you want to learn more about Google maps check out their API here.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Integration with google maps
function loadMap(lat, lng) {
  var latlng = new google.maps.LatLng(lat, lng);
  var settings = {
    zoom: 14,
    center: latlng,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };
  var map = new google.maps.Map(document.getElementById('map_canvas'), settings);
  var marker = new google.maps.Marker({
    position: latlng,
    map: map,
    title: 'Your Position!'
  }); 
  document.getElementById('status').innerHTML = 'Position Found!';
}

That’s all for today. You can try out or download the finished code below.

Example

Try out the finished example here: Example.

Download

Download the source from here: Download