[vox-tech] Chat program in 100 lines of code!

2010-10-20 Thread Brian Lavender
I read a PERL column  that Randal Schwartz wrote a few years back
(maybe 10 years back) about using a gpg signed email and the body with an
image or some content that could be used to update a website. You would
send the message and a procmail recipe would intercept the message and
pipe it through a PERL script.

So, what if we could just write programs like this? Ones that could send
messages back and forth? Well, I recently discovered Java Message Service
(JMS) and it looks very cool. I was looking through the O'Reilly Java
Message service book and I was able to write a chat program with just
a few lines of code and the ActiveMQ message broker.

The following code is from Chapter 2 of the Java Message Service, 2nd
Ed by Mark Richards et al, 2009, ISBN-13 978-0-596-52204-9. Some of the
description in the book didn't make sense, so here is my implementation.

First, make sure you have Java installed. I use OpenJDK.

Download ActiveMQ
http://activemq.apache.org/download.html

Remember the directory when you unpacked the activeMQ.
$ export ACTIVEMQ_HOME=wherever you put it

Add the following to your classpath. The following also adds the current
working directory to your CLASSPATH, so if you don't have it, you will
probably need it to run the java Chat program below.

$ export CLASSPATH=ACTIVEMQ_HOME/activemq-all-5.4.1.jar:.:$CLASSPATH

Edit the config file and add the following configuration to the
conf/activemq.xml configuration file right after the /destinationPolicy
end directive.

$ cat conf/activemq.xml

destinations
topic name=topic1 physicalName=jms.topic1 /
/destinations

Start your ActiveMQ messaging broker. I assume it is a broker. I believe
it will create a default security policy, so you might have to follow
a few directiions.

$ cd $ACTIVEMQ_HOME
$ bin/activemq start

Change to some other directory such as a source folder.

$ cd ~/src

Create the file jndi.properties. Content is as follows:
$ cat jndi.properties

java.naming.factory.initial = 
org.apache.activemq.jndi.ActiveMQInitialContextFactory
java.naming.provider.url = tcp://localhost:61616
java.naming.security.principal=system
java.naming.security.credentials=manager
connectionFactoryNames = TopicCF
topic.topic1 = jms.topic1

Make a ch02 subdirectory.
$ mkdir ch02

Content is the following for the java Chat program:
$ cat Chat.java

package ch02;

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

public class Chat implements javax.jms.MessageListener{
private TopicSession pubSession;
private TopicPublisher publisher;
private TopicConnection connection;
private String username;

/* Constructor used to Initialize Chat */
public Chat(String topicFactory, String topicName, String username) 
throws Exception {

// Obtain a JNDI connection using the jndi.properties file
InitialContext ctx = new InitialContext();

// Look up a JMS connection factory
TopicConnectionFactory conFactory = 
(TopicConnectionFactory)ctx.lookup(topicFactory);

// Create a JMS connection
TopicConnection connection = conFactory.createTopicConnection();

// Create two JMS session objects
TopicSession pubSession = connection.createTopicSession(
false, Session.AUTO_ACKNOWLEDGE);
TopicSession subSession = connection.createTopicSession(
false, Session.AUTO_ACKNOWLEDGE);

// Look up a JMS topic
Topic chatTopic = (Topic)ctx.lookup(topicName);

// Create a JMS publisher and subscriber
TopicPublisher publisher = 
pubSession.createPublisher(chatTopic);
TopicSubscriber subscriber = 
subSession.createSubscriber(chatTopic, null, true);

// Set a JMS message listener
subscriber.setMessageListener(this);

// Intialize the Chat application variables
this.connection = connection;
this.pubSession = pubSession;
this.publisher = publisher;
this.username = username;

// Start the JMS connection; allows messages to be delivered
connection.start( );
}

/* Receive Messages From Topic Subscriber */
public void onMessage(Message message) {
try {
TextMessage textMessage = (TextMessage) message;
String text = textMessage.getText( );
System.out.println(text);
} catch (JMSException jmse){ jmse.printStackTrace( ); }
}

/* Create and Send Message Using Publisher */
protected void writeMessage(String text) throws JMSException {
TextMessage message = pubSession.createTextMessage( );
message.setText(username+: +text);
publisher.publish(message);
}

/* Close the JMS Connection */
public void close( ) throws JMSException {
connection.close( );
}

/* Run the Chat Client */
public static void main(String [] args){
try{
if (args.length!=3)

Re: [vox-tech] Chat program in 100 lines of code!

2010-10-20 Thread Bill Kendrick
On Wed, Oct 20, 2010 at 09:12:52AM -0700, Brian Lavender wrote:
 I read a PERL column  that Randal Schwartz wrote a few years back
 (maybe 10 years back) about using a gpg signed email and the body with an
 image or some content that could be used to update a website. You would
 send the message and a procmail recipe would intercept the message and
 pipe it through a PERL script.

Heh, I once wrote a multi-user chat (kind of like IRC, with private
messages and who's online?' list in less than 300 lines of Action!
(kinda Pascal-ish, C-ish language for the Atari 8-bit, obviously
targetting the 6502 CPU).

(That didn't count comments or blank lines, but plenty of keywords
that are basically the Action! version of { and } blocks... and those
are required, even for one-liners.  Also, there's no else if,
you have to do it as an if then [else] fi block inside an 'else'.)

Good times.  Relatively useless.  It uses a product called Multiplexer (MUX)
that connected Ataris via cartridge ports, required each 'slave' system
to have an altered OS ROM chip installed, and required one 'master' system.
It was big for multi-line BBS use, though!

Woah, way off-topic now, sorry! ;)

-bill!
___
vox-tech mailing list
vox-tech@lists.lugod.org
http://lists.lugod.org/mailman/listinfo/vox-tech


Re: [vox-tech] Chat program in 100 lines of code!

2010-10-20 Thread Brian Lavender
On Wed, Oct 20, 2010 at 09:12:52AM -0700, Brian Lavender wrote:
 Add the following to your classpath. The following also adds the current
 working directory to your CLASSPATH, so if you don't have it, you will
 probably need it to run the java Chat program below.
 
 $ export CLASSPATH=ACTIVEMQ_HOME/activemq-all-5.4.1.jar:.:$CLASSPATH

The above should be as follows. Doh!

$ export CLASSPATH=$ACTIVEMQ_HOME/activemq-all-5.4.1.jar:.:$CLASSPATH

-- 
Brian Lavender
http://www.brie.com/brian/

Program testing can be used to show the presence of bugs, but never to
show their absence!

Professor Edsger Dijkstra
1972 Turing award recipient
___
vox-tech mailing list
vox-tech@lists.lugod.org
http://lists.lugod.org/mailman/listinfo/vox-tech


Re: [vox-tech] Chat program in 100 lines of code!

2010-10-20 Thread Brian Lavender
On Wed, Oct 20, 2010 at 09:56:07AM -0700, Bill Kendrick wrote:
 On Wed, Oct 20, 2010 at 09:12:52AM -0700, Brian Lavender wrote:
  I read a PERL column  that Randal Schwartz wrote a few years back
  (maybe 10 years back) about using a gpg signed email and the body with an
  image or some content that could be used to update a website. You would
  send the message and a procmail recipe would intercept the message and
  pipe it through a PERL script.
 
 Heh, I once wrote a multi-user chat (kind of like IRC, with private
 messages and who's online?' list in less than 300 lines of Action!
 (kinda Pascal-ish, C-ish language for the Atari 8-bit, obviously
 targetting the 6502 CPU).
 
 (That didn't count comments or blank lines, but plenty of keywords
 that are basically the Action! version of { and } blocks... and those
 are required, even for one-liners.  Also, there's no else if,
 you have to do it as an if then [else] fi block inside an 'else'.)
 
 Good times.  Relatively useless.  It uses a product called Multiplexer (MUX)
 that connected Ataris via cartridge ports, required each 'slave' system
 to have an altered OS ROM chip installed, and required one 'master' system.
 It was big for multi-line BBS use, though!

Sounds like ActiveMQ is your new multiplexer. 

I will have to check out the sugar protocol too. I believe it is what 
Abiword uses to give real time collaboration.

-- 
Brian Lavender
http://www.brie.com/brian/

Program testing can be used to show the presence of bugs, but never to
show their absence!

Professor Edsger Dijkstra
1972 Turing award recipient
___
vox-tech mailing list
vox-tech@lists.lugod.org
http://lists.lugod.org/mailman/listinfo/vox-tech


Re: [vox-tech] Chat program in 100 lines of code!

2010-10-20 Thread Bill Kendrick
On Wed, Oct 20, 2010 at 10:04:30AM -0700, Brian Lavender wrote:
 I will have to check out the sugar protocol too. I believe it is what 
 Abiword uses to give real time collaboration.

Yes.  Tux Paint needs some Sugarization.

-bill!
___
vox-tech mailing list
vox-tech@lists.lugod.org
http://lists.lugod.org/mailman/listinfo/vox-tech


Re: [vox-tech] Chat program in 100 lines of code!

2010-10-20 Thread Bill Broadley
Very cool, nice walk though.  Kudos to Brian for a great post.

Posts like Brian's definitely lower the barrier to entry.  I enjoy
cut/paste type intros so you can tinker with something quickly and
painlessly.

I've been tinkering with similar with Python's twisted library.  I
figured I'd do a similar intro for a chat client using the python
twisted library.

1) Install twisted (apt-get/yum install python-twisted) or very similar
2) mkdir chat_server
3) go to
http://www.koders.com/python/fidD65298C63F7F8C0BFA09681B5981427544C470A9.aspx?s=wxpython
   And click download [1]
4) twistd -y chatserver.py
5) in two windows type telnet localhost 1025
6) binary package = 1MB or so (vs 44MB for ActiveMQ)
7) python chat server = 12MB resident (vs 200MB for ActiveMQ)

The differences I noted:
* 37 lines instead of 100 ish
* No nickname prefixes
* No editing of files or setting environment variables.
* Twisted is a library (to enable clients or servers) not a network
  service/daemon (like ActiveMQ).


For a more complete example I tinkered with ampchat:
1) apt-get install python-twisted
2) hg clone http://ripton.net/hg/ampchat
3) cd ampchat
4) python chatserver.py
5) in new window: python chatserver.py  file - connect login: a password: a
6) in new window: python chatserver.py  file - connect login: b password: b

The differences I noted:
* 580 lines instead of 100 ish
* client - server architecture
* GUI
* Usernames and passwords
* Shows who is connected.
* No editing of files or setting environment variables.
* can send messages to everyone or any subset of users.

Has anyone here written anything non-trivial in twisted?  ActiveMQ?

For the curious my interest in this is wanting to implement a simple
put/get encrypted protocol for binary blobs for a p2p backup system I'm
writing.

[1] Authoritative site
http://twistedsphinx.funsize.net/projects/core/examples/index.html has a
broken link for chatserver.py.  Also available in the twisted source
available at twistmatrix.com site.

___
vox-tech mailing list
vox-tech@lists.lugod.org
http://lists.lugod.org/mailman/listinfo/vox-tech