ArtsAutosBooksBusinessEducationEntertainmentFamilyFashionFoodGamesGenderHealthHolidaysHomeHubPagesPersonal FinancePetsPoliticsReligionSportsTechnologyTravel

How to Create a Chat Room in Java

Updated on March 31, 2013
Source

When you start to think about how to create your own personal chat room, probably the first thing that you think of is related to network I/O, sockets, etc. and maybe you begin to feel discouraged. Don't be! There is a great solution that makes implementing an application like this easy: JGroups.

What is JGroups? It is a reliable multicast system written in the Java language. From Wikipedia: "Multicast is the delivery of a message or information to a group of destination computers simultaneously in a single transmission from the source".

In simple words, we can imagine our chat room as a group. Each user represents a node in this group, and every time a message is sent by a node, it is delivered to all the other nodes in the group.

The chat that we are going to create
The chat that we are going to create

Basic Concepts of JGroups

In our chat room we can forget sockets and other low level network elements, but we have to learn some basic concepts about JGroups before continuing.

As already stated, we can see our chat room as a group. To join a group and to send/receive messages, we need channels. Every channel has its own address and it is connected to a group using the group name. So a group can have many channels associated to it (in our case, one channel per user).

Channels can always retrieve a list of the member addresses in the group (basically a user can see who is in the chat room). We can even be notified when a user leaves/joins the chat room.

It's Code Time!

import org.jgroups.JChannel;
import org.jgroups.Message;
import org.jgroups.ReceiverAdapter;
import org.jgroups.View;
import org.jgroups.util.Util;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.LinkedList;
import java.util.List;

public class GUIChat extends ReceiverAdapter {

    final List<String> history = new LinkedList<String>();

    private JChannel channel;
    private String userName = System.getProperty("user");
    private JTextField textField;
    private JTextArea textArea;

    public static void main(String[] args) throws Exception {
        new GUIChat().start();
    }

    public void viewAccepted(View newView) {
        appendText("** in room: " + newView + "\n");
    }

    public void receive(Message msg) {
        String line = msg.getObject().toString();
        synchronized(history) {
            history.add(line);
            appendText(line);
        }
    }

    public void getState(OutputStream output) throws Exception {
        synchronized(history) {
            Util.objectToStream(history, new DataOutputStream(output));
        }
    }

    public void setState(InputStream input) throws Exception {
        List<String> list = (List<String>) Util.objectFromStream(new DataInputStream(input));
        synchronized(history) {
            history.clear();
            history.addAll(list);
        }
        appendText("received " + list.size() + " messages in chat history:\n");
        for(String str: list) appendText(str);
    }

    private void start() throws Exception {
        final JPanel panel = createPanel();
        channel = new JChannel();
        channel.setReceiver(this);
        channel.connect("ChatCluster");
        channel.getState(null, 10000);
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new JFrame("Simple Chat");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(panel);
                frame.pack();
                frame.setVisible(true);
            }
        });
    }

    private JPanel createPanel() {
        JPanel panel = new JPanel(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        c.gridwidth = GridBagConstraints.REMAINDER;
        c.fill = GridBagConstraints.HORIZONTAL;
        c.weightx = c.weighty = 1.0;
        textArea = new JTextArea(20, 40);
        textArea.setEditable(false);
        panel.add(new JScrollPane(textArea), c);

        c.weightx = c.weighty = 0.0;
        c.fill = GridBagConstraints.HORIZONTAL;

        JPanel messageContainer = new JPanel(new FlowLayout());
        messageContainer.add(new JLabel("Message:"));
        textField = new JTextField(40);
        textField.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                String line="[" + userName + "] " + textField.getText() + "\n";
                try {
                    channel.send(new Message(null, null, line));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        messageContainer.add(textField);

        JButton button = new JButton("Bye!");
        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                channel.close();
                System.exit(0);
            }
        });
        messageContainer.add(button);

        panel.add(messageContainer, c);
        return panel;
    }

    private void appendText(String newline) {
        textArea.append(newline);
        textField.setText("");
        textArea.setCaretPosition(textArea.getDocument().getLength());
    }

}

The code above represents an all-in-one client/server chat room based on JGroups and Swing. The main features are:

  • Keeping a chat history (as a list in memory) to send to any new user connected.
  • Sending and receiving messages to/from other users.
  • Being notified when someone leaves/joins the chat.

First of all, GUIChat class extends org.jgroups.ReceiverAdapter that has most of the code ready for us, and we limit to override only a few methods of it.

To start the chat, we need to define the channel and its group:

channel = new JChannel();
channel.setReceiver(this);
channel.connect("ChatCluster");
channel.getState(null, 10000);

and when we leave the chat the channel must be closed:

channel.close();

To keep the chat history updated, we use the method:

public void receive(Message msg)

This method is used when we receive messages from other users (and ourself) too. Indeed, don't forget that in a multicast system, messages are sent to all members of the group including the sender.

So when a message is received, it is appended on the history-list and displayed in the text area.

To send a message to the other members we use the method:

channel.send(new Message(null, null, line));

The constructor parameters for the Message class are, respectively, destination address, source address, and data to send. Null on the destination address will send the message to all the group's members.

When a new user joins the chat, the already present members send him/her the history with the method:

public void getState(OutputStream output) throws Exception

that 'streams' (marshalling) the history-list object.

The history received is converted (unmarshalling) to history-list object with the method:

public void setState(InputStream input) throws Exception

When a user joins or leaves the chat all the other members are notified via:

public void viewAccepted(View newView)

To have a better comprehension of the API and the functionalities of JGroups I recommend that you read the official documentation here.

Compiling and Running the Application

First, create a folder where you will create the GUIChat.java file with the code above. Then download from here the JGroups jar file (I have used jgroups-3.2.8.Final.jar).

To compile run:

javac -cp jgroups-3.2.8.Final.jar GUIChat.java

and to run the application:

java -cp .:jgroups-3.2.8.Final.jar -Duser=john -Djava.net.preferIPv4Stack=true GUIChat

You can run different instances of the chat on the same machine or on different machines in the same network.


Well, that's it guys, I hope you enjoyed it!

Comments

    0 of 8192 characters used
    Post Comment

    No comments yet.

    working

    This website uses cookies

    As a user in the EEA, your approval is needed on a few things. To provide a better website experience, hubpages.com uses cookies (and other similar technologies) and may collect, process, and share personal data. Please choose which areas of our service you consent to our doing so.

    For more information on managing or withdrawing consents and how we handle data, visit our Privacy Policy at: https://corp.maven.io/privacy-policy

    Show Details
    Necessary
    HubPages Device IDThis is used to identify particular browsers or devices when the access the service, and is used for security reasons.
    LoginThis is necessary to sign in to the HubPages Service.
    Google RecaptchaThis is used to prevent bots and spam. (Privacy Policy)
    AkismetThis is used to detect comment spam. (Privacy Policy)
    HubPages Google AnalyticsThis is used to provide data on traffic to our website, all personally identifyable data is anonymized. (Privacy Policy)
    HubPages Traffic PixelThis is used to collect data on traffic to articles and other pages on our site. Unless you are signed in to a HubPages account, all personally identifiable information is anonymized.
    Amazon Web ServicesThis is a cloud services platform that we used to host our service. (Privacy Policy)
    CloudflareThis is a cloud CDN service that we use to efficiently deliver files required for our service to operate such as javascript, cascading style sheets, images, and videos. (Privacy Policy)
    Google Hosted LibrariesJavascript software libraries such as jQuery are loaded at endpoints on the googleapis.com or gstatic.com domains, for performance and efficiency reasons. (Privacy Policy)
    Features
    Google Custom SearchThis is feature allows you to search the site. (Privacy Policy)
    Google MapsSome articles have Google Maps embedded in them. (Privacy Policy)
    Google ChartsThis is used to display charts and graphs on articles and the author center. (Privacy Policy)
    Google AdSense Host APIThis service allows you to sign up for or associate a Google AdSense account with HubPages, so that you can earn money from ads on your articles. No data is shared unless you engage with this feature. (Privacy Policy)
    Google YouTubeSome articles have YouTube videos embedded in them. (Privacy Policy)
    VimeoSome articles have Vimeo videos embedded in them. (Privacy Policy)
    PaypalThis is used for a registered author who enrolls in the HubPages Earnings program and requests to be paid via PayPal. No data is shared with Paypal unless you engage with this feature. (Privacy Policy)
    Facebook LoginYou can use this to streamline signing up for, or signing in to your Hubpages account. No data is shared with Facebook unless you engage with this feature. (Privacy Policy)
    MavenThis supports the Maven widget and search functionality. (Privacy Policy)
    Marketing
    Google AdSenseThis is an ad network. (Privacy Policy)
    Google DoubleClickGoogle provides ad serving technology and runs an ad network. (Privacy Policy)
    Index ExchangeThis is an ad network. (Privacy Policy)
    SovrnThis is an ad network. (Privacy Policy)
    Facebook AdsThis is an ad network. (Privacy Policy)
    Amazon Unified Ad MarketplaceThis is an ad network. (Privacy Policy)
    AppNexusThis is an ad network. (Privacy Policy)
    OpenxThis is an ad network. (Privacy Policy)
    Rubicon ProjectThis is an ad network. (Privacy Policy)
    TripleLiftThis is an ad network. (Privacy Policy)
    Say MediaWe partner with Say Media to deliver ad campaigns on our sites. (Privacy Policy)
    Remarketing PixelsWe may use remarketing pixels from advertising networks such as Google AdWords, Bing Ads, and Facebook in order to advertise the HubPages Service to people that have visited our sites.
    Conversion Tracking PixelsWe may use conversion tracking pixels from advertising networks such as Google AdWords, Bing Ads, and Facebook in order to identify when an advertisement has successfully resulted in the desired action, such as signing up for the HubPages Service or publishing an article on the HubPages Service.
    Statistics
    Author Google AnalyticsThis is used to provide traffic data and reports to the authors of articles on the HubPages Service. (Privacy Policy)
    ComscoreComScore is a media measurement and analytics company providing marketing data and analytics to enterprises, media and advertising agencies, and publishers. Non-consent will result in ComScore only processing obfuscated personal data. (Privacy Policy)
    Amazon Tracking PixelSome articles display amazon products as part of the Amazon Affiliate program, this pixel provides traffic statistics for those products (Privacy Policy)
    ClickscoThis is a data management platform studying reader behavior (Privacy Policy)