Вы находитесь на странице: 1из 27

Developing Chat Room

Application with JMS


Professor: Sheau-Ling Hsieh , Ph.D
Team : 9634501, Chi-Hua Chen 9634508, Chang-Min Chen
9634509, Ying-Yu Lin 9634512, Hsin-Ying Hsieh
9634519, Ming-Chia Li 9634524, Chia-Wei Hsu
9634528, Yin-Lung Lu

Institute of Information Management,


National Chiao Tung University, Hsinchu, Taiwan.
Developing Chat Room Application with JMS

Contents

1 Introduction ..................................................................................................... 2
2 Objective .......................................................................................................... 3
3 Hardware & Software Environment............................................................... 3
3.1 Hardware................................................................................................ 3
3.2 Software.................................................................................................. 3
4 Approach(Design)............................................................................................ 3
5 Implementation................................................................................................ 4
5.1 Common objects and functions in JMS topic ....................................... 4
5.2 Structure................................................................................................. 5
5.3 Server Setup ........................................................................................... 6
5.4 Development Example ........................................................................... 6
6 Results (Execution) .......................................................................................... 8
7 Alternatives...................................................................................................... 9
8 Discussion and Conclusion (Problem Encountered) .....................................10
9 References .......................................................................................................11

Appendix : Source Code..........................................................................................12


 Frame1.java ........................................................................................... 12
 ChatManGUI.java.................................................................................. 17
 ChatMan.java......................................................................................... 19
 MQUtility.java ....................................................................................... 23

1
Developing Chat Room Application with JMS

1 Introduction
The Java Message Service (JMS) API is a Java Message Oriented Middleware
(MOM) API for sending messages between two or more clients.

JMS defines an API for accessing services from a messaging provider; that is, it
is not a product itself. It is a set of interface classes that messaging provider vendors
implement. Applications that use the JMS API can then communicate with the
messaging provider the vendor supplies. The JMS API has become the industry
standard interface for Java applications to create, send, receive and read messages
using messaging providers that support the JMS API. The standard is associated with
the Java 2 Enterprise Edition (J2EE) platform. J2EE is a set of standards for a
component-based way to develop, assemble and deploy enterprise applications. J2EE
containers implement a standard runtime environment that provides quality of service
items such as security, transaction support and thread pooling.

JMS client

Connection
Destination
Factory

JNDI Namespace

Consumer Producer

Message Message

Connection::Session

JMS provider

Figure 1. JMS programming model

2
Developing Chat Room Application with JMS

In the above diagram, the JMS provider implements the JMS API. It is the entity
with which the JMS client interacts. The JMS client establishes a connection and a
session through which the interaction takes place. The JMS client establishes the
connection based on configuration information in the connection factory and
identifies where a message is to be sent to or retrieved from based on the destination.

Both the connection factory and destination objects are listed in the Java Naming
and Directory Interface (JNDI) namespace. JNDI is the Java industry standard API for
accessing naming and directory services. Since the connection factory and destination
are administered objects by JNDI, it means the JMS client can connect to different
JMS providers without changing JMS client code; that is, it creates portability. It also
means that attributes which often can and do change dynamically such as the
destination can be changed independent of the JMS client code.

2 Objective
Understand the structure of JMS in depth and use JMS to develop an example
application to describe the development process for creating distributed, object-based
applications for Java. Learn the process of middleware development, and understand
the JMS infrastructure and how it works.

3 Hardware & Software Environment


3.1 Hardware
AMD Semprom(tm) 1.00 GHz
512 MB RAM, Physical Address Extension

3.2 Software
SwiftMQ V2.1.3 (JMS Server)

4 Approach(Design)
Introduction of JMS
There are two JMS models which are showed as below,
• Point-to-point: it is a one to one model. Every message is handled by
sequence.
• Publish/Subscribe: it is a one to many models. Author can publish messages
whatever there is any subscriber.
According to above characteristic of JMS, model of Publish/Subscribe is chosen
in this project.

3
Developing Chat Room Application with JMS

5 Implementation
5.1 Common objects and functions in JMS topic
JNDI and TopicConnectionFactory
• JNDI (Java Naming and Directory) provides application based on Java
technology with a unified interface to multiple naming and directory services.
• Property setting would not be the same in different provider JNDI.
• TopicConnectionFactory which is unable to get by JMS can be got by JNDI
• Managing connection between client and server is function of
TopicConnectionFactory.
• TopicConnection is built by TopicConnectionFactory

TopicConnection, TopicSession, and Topic


• TopicConnection represents connection between client and server.
• TopicConnections defines some methods which provide functions of
connection management, like start (), stop (), close (), etc.
• Topic Session of publishing and Topic Session of subscribing are built by
TopicConnection.
• Topic is discovered by JNDI.
• TopicPublisher and TopicSubscriber are built by TopicSession and Topic.

TopicPublisher and TopicSubscriber


• TopicPublisher, sending asynchronous messages to a specific topic at JMS
server.
• TopicSubscriber, receiving messages from a specific topic.
• There is a MessageListener which handles incoming messages in
TopicSubscriber.
• Chat class implements MessageListener.

Message
• onMessage() is one of MessageListener methods which prints out incoming
messages at Client side.
• writeMessage(), sending messages to JMS server
• TextMessage, packaging messages.
• TextMessage, there are header and string which is stored message information.

4
Developing Chat Room Application with JMS

5.2 Structure

5.2.1 Structure is showed as below,

Subscriber
Publisher Subject
Subscriber

Figure 2. Publish/Subscribe Architecture

5.2.2 Appling the above model to multi-chat rooms,

User 1 User 2

Topic

User 3 User 4

Figure 3. Multi-Chat Rooms Architecture

(a) When someone is publishing message, he/she acts as a publisher.


On the other hand, other users act ac a Subscriber.
(b) Publisher sends his/her own message to Topic and Topic will
forward this message to online subscribers.
(c) Because of Topic just supports asynchronous messages, subscribers
have to remain online.

5
Developing Chat Room Application with JMS

5.3 Server Setup

(a) Unzip swiftmq_2_1_3.zip to specific path.

(b) In order to starting server, running


swiftmq_2_1_3\scripts\win32\smqr1.bat at CMD.

5.4 Development Example

Jbuilder enterprise 2005 is used in following example,

(a) New project

6
Developing Chat Room Application with JMS

(b) Imports files from swiftmq_2_1_3\swiftmq_2_1_3\jars

Files of swiftmq_2_1_3\swiftmq_2_1_3\jars

• Steps of importing files,

7
Developing Chat Room Application with JMS

(c) Java files

6 Results (Execution)
6.1 MQUtility.java

Reading property from files, for example, Topic connection and JNDI
reference.

6.2 ChatMan.java

Implementing terminal function menu.

• Entering Account

8
Developing Chat Room Application with JMS

• Chatting

6.3 Frame1.java

Implementation chat room graphic user interface.

6.4 ChatManGUI.java

Presenting chat room graphic user interface with Java Swing.

7 Alternatives
Data Distribution Service (DDS) is an alternative to JMS. This spec was
designed and is supported by OMG (Object Management Group). The concepts are
fairly familiar to anyone who has done JMS.

DDS is newer standard based on fundamentally different paradigms than JMS,


with regards to data modeling, dataflow routing, discovery, and data typing; these
differences enable applications designers with powerful new architectural
possibilities. Despite these differences, the user experience of writing to DDS APIs

9
Developing Chat Room Application with JMS

is similar to that of JMS APIs. DDS offers several enhanced capabilities with respect
to data filtering and transformation, connectivity monitoring, redundancy and
replication, and delivery effort. DDS offers new capabilities with respect to
data-object lifecycle management, predictable delivery, delivery ordering, transport
priority, resource management, and status notifications. JMS offers some capabilities
not offered by DDS. These include client application acknowledgements, full
transaction support, message priority, and point-to-point semantics requiring a
message to be delivered to exactly one of many consumers.

8 Discussion and Conclusion (Problem


Encountered)
Most pub-sub systems we see today deal with frequently published data and tend
to provide real-time monitoring and status updates. Pub-sub is good for these kinds of
operations. Many pub-sub implementations have a peculiar limitation that makes
them only suitable for applications with frequently published data-more specifically,
applications in which it doesn't matter if you miss a message because there will be
another one in a few minutes.

The reason pub-sub usually only works in these types of applications is that
pub-sub doesn't usually have the concept of a persistent, or durable subscription. For
example, suppose you are publishing flight cancellations for LaGuardia Airport.
Although it's true that they do seem to occur often enough that there will be another
one in a few minutes, you really don't want to miss one. Now, suppose you have a
program that makes a list of passengers who need to be rebooked for the next
available flight (tomorrow, next week, sometime next year, and and so on). If the
program shuts down for a few minutes, it might miss three or four cancel lations! You
want the message server to hold on to your messages while your program is down.

JMS supports durable subscription. After you create a durable subscription, the
JMS server keeps any messages you miss while your program isn't running. To create
a durable subscription, use the createDurableSubscriber method in the TopicSession
class:

public TopicSubscriber createDurableSubscriber(Topic topic, String subscriptionName)

10
Developing Chat Room Application with JMS

You must always use the same subscription name when reconnecting your
program to its durable subscription. That is, you must always ask for subscription
name (not the topic name) when resuming that subscription. Messages can have an
expiration time, so when a message expires, the server can safely remove it from the
durable subscription. This helps keep the database size down when we you don't
resume a durable subscription for a long time.

9 References
[1] Sun Microsystems, Java Naming and Directory Interface (JNDI),
http://java.sun.com/products/jndi/
[2] O’reilly, Java Message Service(JMS),
http://www.oreilly.com
[3] IBM, Java Message Service (JMS) programming model,
http://publib.boulder.ibm.com/
[4] RTI, Data Distribution Service (DDS) and Java Message Service (JMS),
http://www.rti.com/mk/JMS.html

11
Developing Chat Room Application with JMS

Appendix : Source Code


 Frame1.java
package p5;

import javax.jms.*;
import javax.naming.*;
import java.util.*;
import java.io.*;

import java.awt.*;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyAdapter;
import javax.swing.text.BadLocationException;
import javax.swing.text.StyledDocument;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;

public class Frame1 extends JFrame implements MessageListener{

String id = "default user of "+new Date();


private TopicConnection topicConnection;
private TopicSession pubSession;
private TopicSession subSession;
private TopicPublisher publisher;
private TopicSubscriber subscriber;

JPanel contentPane;
BorderLayout borderLayout1 = new BorderLayout();
JTextField jTextField1 = new JTextField();
JScrollPane jScrollPane1 = new JScrollPane();
JTextPane jTextPane1 = new JTextPane();
JPanel jPanel1 = (JPanel) getContentPane();

12
Developing Chat Room Application with JMS

static Color red = new Color(255, 0, 0);


static Color blue = new Color(0, 0, 255);
public void sendText(String text)
{
try
{
TextMessage textMesg = pubSession.createTextMessage();
// set message property
textMesg.setStringProperty("id", id);
textMesg.setText(text);
publisher.publish(textMesg);
System.out.println(this.id+"<< "+text);
SimpleAttributeSet s1 = new SimpleAttributeSet();
StyleConstants.setForeground(s1, blue);
String CRLF = System.getProperty("line.separator");
StyledDocument doc = jTextPane1.getStyledDocument();
doc.insertString(doc.getLength(), text+CRLF, s1);
jTextPane1.setDocument(doc);
jTextField1.setText(null);
}
catch(Exception e)
{
System.out.println(e);
}
}

public void onMessage(Message mesg)


{
try
{
TextMessage textMesg = (TextMessage)mesg;
String text = textMesg.getText();
String id = textMesg.getStringProperty("id");
// only display messages from other users
if(!id.equals(this.id)) { //if
//System.out.println(id + ">> " + text);
SimpleAttributeSet s1 = new SimpleAttributeSet();
StyleConstants.setForeground(s1, red);

13
Developing Chat Room Application with JMS

String CRLF = System.getProperty("line.separator");


StyledDocument doc = jTextPane1.getStyledDocument();
doc.insertString(doc.getLength(), id + ">> " +text+CRLF, s1);
jTextPane1.setDocument(doc);
jTextField1.setText(null);
} //if
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
}

public void end() throws JMSException


{
topicConnection.close();
}

public Frame1(String id) {


this();
this.id = id;
}

public Frame1() {
try {
setDefaultCloseOperation(EXIT_ON_CLOSE);
jbInit();
} catch (Exception exception) {
exception.printStackTrace();
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
MQUtility mq = null;
TopicConnectionFactory topicConnectionFactory = null;
Topic topic = null;
try {
mq = new MQUtility("C:\\Documents and
Settings\\Andy\\jbproject\\andyTest0721", "mq.config");
topicConnectionFactory =

14
Developing Chat Room Application with JMS

(TopicConnectionFactory)mq.getConnectionFactory();
topicConnection =
topicConnectionFactory.createTopicConnection();

topic = (Topic)mq.getDestination();

subSession = topicConnection.createTopicSession(false,
Session.AUTO_ACKNOWLEDGE);
pubSession = topicConnection.createTopicSession(false,
Session.AUTO_ACKNOWLEDGE);

subscriber = subSession.createSubscriber(topic);
publisher = pubSession.createPublisher(topic);

subscriber.setMessageListener(this);
topicConnection.start();

} catch (Exception e) {
System.out.println(e.getMessage());
}
}

/**
* Component initialization.
*
* @throws java.lang.Exception
*/
private void jbInit() throws Exception {
contentPane = (JPanel) getContentPane();
contentPane.setLayout(borderLayout1);
setSize(new Dimension(400, 300));
setTitle("聊天軟體 ver. 5.0");
jTextField1.addActionListener(new
Frame1_jTextField1_actionAdapter(this));
jTextField1.addKeyListener(new
Frame1_jTextField1_keyAdapter(this));
contentPane.add(jTextField1, java.awt.BorderLayout.SOUTH);
contentPane.add(jScrollPane1, java.awt.BorderLayout.CENTER);

15
Developing Chat Room Application with JMS

jScrollPane1.getViewport().add(jTextPane1);
}

public void jTextField1_actionPerformed(ActionEvent e) {

public void jTextField1_keyPressed(KeyEvent e) {


String sentence = jTextField1.getText();
if (e.getKeyCode() == 10 && !jTextField1.getText().equals(""))
{ //if
sendText(sentence);
} //if
}
}

class Frame1_jTextField1_keyAdapter extends KeyAdapter {


private Frame1 adaptee;
Frame1_jTextField1_keyAdapter(Frame1 adaptee) {
this.adaptee = adaptee;
}

public void keyPressed(KeyEvent e) {


adaptee.jTextField1_keyPressed(e);
}
}

class Frame1_jTextField1_actionAdapter implements ActionListener {


private Frame1 adaptee;
Frame1_jTextField1_actionAdapter(Frame1 adaptee) {
this.adaptee = adaptee;
}

public void actionPerformed(ActionEvent e) {


adaptee.jTextField1_actionPerformed(e);
}
}

16
Developing Chat Room Application with JMS

 ChatManGUI.java
package p5;

import java.awt.*;

import javax.swing.*;

public class ChatManGUI {


boolean packFrame = false;

/**
* Construct and show the application.
*/
public ChatManGUI() {
Frame1 frame = new Frame1();
// Validate frames that have preset sizes
// Pack frames that have useful preferred size info, e.g. from their
layout
if (packFrame) {
frame.pack();
} else {
frame.validate();
}

// Center the window


Dimension screenSize =
Toolkit.getDefaultToolkit().getScreenSize();
Dimension frameSize = frame.getSize();
if (frameSize.height > screenSize.height) {
frameSize.height = screenSize.height;
}
if (frameSize.width > screenSize.width) {
frameSize.width = screenSize.width;
}
frame.setLocation((screenSize.width - frameSize.width) / 2,
(screenSize.height - frameSize.height) / 2);
frame.setVisible(true);

17
Developing Chat Room Application with JMS

try {
jbInit();
} catch (Exception ex) {
ex.printStackTrace();
}
}

public ChatManGUI(String id) {


Frame1 frame = new Frame1(id);
// Validate frames that have preset sizes
// Pack frames that have useful preferred size info, e.g. from their
layout
if (packFrame) {
frame.pack();
} else {
frame.validate();
}

// Center the window


Dimension screenSize =
Toolkit.getDefaultToolkit().getScreenSize();
Dimension frameSize = frame.getSize();
if (frameSize.height > screenSize.height) {
frameSize.height = screenSize.height;
}
if (frameSize.width > screenSize.width) {
frameSize.width = screenSize.width;
}
frame.setLocation((screenSize.width - frameSize.width) / 2,
(screenSize.height - frameSize.height) / 2);
frame.setVisible(true);
try {
jbInit();
} catch (Exception ex) {
ex.printStackTrace();
}
}

18
Developing Chat Room Application with JMS

/**
* Application entry point.
*
* @param args String[]
*/
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel(UIManager.

getSystemLookAndFeelClassName());
} catch (Exception exception) {
exception.printStackTrace();
}

new ChatManGUI("bjohnlee");
}
});
}

private void jbInit() throws Exception {


}
}

 ChatMan.java
package p5;

import javax.jms.*;
import javax.naming.*;
import java.util.*;
import java.io.*;

public class ChatMan implements MessageListener {


public ChatMan() {

19
Developing Chat Room Application with JMS

try {
jbInit();
} catch (Exception ex) {
ex.printStackTrace();
}
}

String id;
private TopicConnection topicConnection;
private TopicSession pubSession;
private TopicSession subSession;
private TopicPublisher publisher;
private TopicSubscriber subscriber;

public ChatMan(String id) {


this.id = id;
MQUtility mq = null;
TopicConnectionFactory topicConnectionFactory = null;
Topic topic = null;
try {
mq = new MQUtility("C:\\Documents and
Settings\\Andy\\jbproject\\andyTest0721", "mq.config");
topicConnectionFactory =
(TopicConnectionFactory)mq.getConnectionFactory();
topicConnection =
topicConnectionFactory.createTopicConnection();

topic = (Topic)mq.getDestination();

subSession = topicConnection.createTopicSession(false,
Session.AUTO_ACKNOWLEDGE);
pubSession = topicConnection.createTopicSession(false,
Session.AUTO_ACKNOWLEDGE);

subscriber = subSession.createSubscriber(topic);
publisher = pubSession.createPublisher(topic);

subscriber.setMessageListener(this);

20
Developing Chat Room Application with JMS

topicConnection.start();

} catch (Exception e) {
System.out.println(e.getMessage());
}
}

public void sendText(String text)


{
try
{
TextMessage textMesg = pubSession.createTextMessage();
// set message property
textMesg.setStringProperty("id", id);
textMesg.setText(text);
publisher.publish(textMesg);
System.out.println(this.id+"<< "+text);
}
catch(JMSException e)
{
System.out.println(e);
}
}

public void end() throws JMSException


{
topicConnection.close();
}

public void onMessage(Message mesg)


{
try
{
TextMessage textMesg = (TextMessage)mesg;
String text = textMesg.getText();
String id = textMesg.getStringProperty("id");
// only display messages from other users
if(!id.equals(this.id))

21
Developing Chat Room Application with JMS

System.out.println(id + ">> " + text);


}
catch(JMSException e)
{
System.out.println(e.getMessage());
}
}

public static void main(String[] args) {


try {
System.out.println("please insert your id:");
BufferedReader reader = new BufferedReader(new
InputStreamReader(System.in));
String input = reader.readLine();
ChatMan c1 = new ChatMan(input);
input = null;
while (true) { //1
input = reader.readLine();
if (input.equals("exit")) {
System.out.println("機制結束");
System.exit(0);
} else { //2
c1.sendText(input);
} //2
} //1
} catch (Exception e) {
System.out.println( e.getMessage() );
}

private void jbInit() throws Exception {


}

22
Developing Chat Room Application with JMS

 MQUtility.java
package p5;

import javax.naming.*;
import java.util.*;
import java.io.*;

public class MQUtility


{
private Context jndiContext;
private String contextFactory;
private String url;
private String connectionFactory;
private String destination;
private String username;
private String password;

public MQUtility(String dir, String configFile)


throws FileNotFoundException, IOException
{
Properties mqConfig = loadConfig(dir, configFile);
url = mqConfig.getProperty("mq.url");
contextFactory = mqConfig.getProperty("mq.contextFactory");
connectionFactory = mqConfig.getProperty("mq.connectionFactory");
destination = mqConfig.getProperty("mq.destination");
username = mqConfig.getProperty("mq.username");
password = mqConfig.getProperty("mq.password");
}

public Object getConnectionFactory() throws Exception


{
return jndiLookup(connectionFactory);
}

public Object getDestination() throws Exception


{
return jndiLookup(destination);

23
Developing Chat Room Application with JMS

// use initial context factory and provider URL from the configuration file
public Object jndiLookup(String name) throws NamingException
{
return jndiLookup(contextFactory, url, name);
}

// specify initial context factory and provider URL to lookup for name
public Object jndiLookup(String contextFactory, String url, String name)
throws NamingException
{
if(name == null)
throw new NamingException("Name to look up is empty");

if(jndiContext == null)
{
try
{
Properties jndiProperties = new Properties();
// initial context factory
jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY,
contextFactory);
// naming server
jndiProperties.put(Context.PROVIDER_URL, url);
jndiContext = new InitialContext(jndiProperties);
}
catch(NamingException e)
{
System.out.println("Could not create JNDI context: " + url);
throw e;
}
}

Object nameObj = null;

try
{

24
Developing Chat Room Application with JMS

nameObj = jndiContext.lookup(name);
}
catch(NamingException e)
{
System.out.println("JNDI lookup error: " + name);
throw e;
}

return nameObj;
}

public String getConnectionFactoryName()


{
if(connectionFactory != null)
connectionFactory.trim();

return connectionFactory;
}

public String getDestinationName()


{
if(destination != null)
destination.trim();

return destination;
}

public String getUsername()


{
if(username != null)
username.trim();

return username;
}

public String getPassword()


{
if(password != null)

25
Developing Chat Room Application with JMS

password.trim();

return password;
}

// loads configurations with format like name=value from a file.


public static Properties loadConfig(String dir, String filename)
throws FileNotFoundException, IOException
{
File inFile = null;
Properties prop = null;

inFile = new File(dir, filename);

if(inFile.exists())
{
prop = new Properties();
prop.load(new FileInputStream(inFile));
}
else
throw new FileNotFoundException("Can not find '" +
inFile.toString() + "'");

return prop;
}

public void close() throws NamingException


{
jndiContext.close();
}
}

26

Вам также может понравиться