IRCConnection

By Aion- on Oct 08, 2012

This snippet connects to a server and port of your choice and reads input. It does not handle output: you will have to do it yourself. An example will be provided in this description.

What I like about this snippet is that it can easily be modified into an event driven irc lib. I will probably be using it as a base for the client I am working on.

Here is an example of how to send outputs using the main method:

public static void main(String[] args) { IRCConnection connection = new IRCConnection("irc.sxci.net", 6667); try { connection.connect(); Scanner in = new Scanner(System.in); while (in.hasNextLine()) { connection.sendRaw(in.nextLine()); if (!connection.isConnected()) { break; } } } catch (IOException e) { System.out.println("Ooops!\n" + e); } }

Image (green is output):

f_204352_ewntZ2doVUtgtRsq0WjhRq8L7.png
import java.io.*;
import java.net.Socket;
import java.util.*;

/**
 * @author Aion
 *         Created on 08/10/12
 */
public class IRCConnection {

    private final int port;
    private final String server;

    private Socket socket;

    private Timer readTimer;
    private Timer eventProcessorTimer;

    private LinkedList<IRCEvent> eventQueue = new LinkedList<>();

    public IRCConnection(String server) {
        this(server, 6667);
    }

    public IRCConnection(String server, int port) {
        this.server = server;
        this.port = port;
    }

    public void connect() throws IOException {
        if (isConnected()) {
            System.out.println("We're already connected!");
            return;
        }
        socket = new Socket(server, port);

        readTimer = new Timer();
        readTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                read();
            }
        }, 0, 200);

        eventProcessorTimer = new Timer();
        eventProcessorTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                processEvent();
            }
        }, 0, 200);
    }

    public void disconnect() throws IOException {
        if (!isConnected()) {
            System.out.println("We're not connected!");
            return;
        }
        socket.close();
        socket = null;
        readTimer.cancel();
        eventProcessorTimer.cancel();
    }

    public boolean isConnected() {
        return socket != null && socket.isConnected();
    }

    private void processEvent() {
        synchronized (eventQueue) {
            if (eventQueue.isEmpty()) {
                try {
                    eventQueue.wait();
                } catch (InterruptedException e) {
                    System.out.println("Event queue interrupted\n " + e);
                }
            }
            IRCEvent event = eventQueue.poll();
            String prefix = event.getPrefix();
            String command = event.getCommand();
            String param = event.getParameter();

            String input = String.format("Prefix: %s Command: %s Param: %s", prefix, command, param);
            System.out.println(input);
        }
    }

    private void read() {
        if (isConnected()) {
            try {
                BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                String input = br.readLine();
                while ((input = br.readLine()) != null) {
                    synchronized (eventQueue) {
                        eventQueue.push(new IRCEvent(input));
                        eventQueue.notifyAll();
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void sendRaw(String output) throws IOException {
        if (!isConnected()) {
            System.out.println("We're not connected!");
            return;
        }
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        writer.write(output + "\r\n");
        writer.flush();
    }

    public static class IRCEvent extends EventObject {

        protected final String prefix;
        protected final String command;
        protected final String param;

        public IRCEvent(String raw) {
            super(raw);

            String prefix = "";
            String command = "";
            String param = "";

            String[] split = raw.split(" ", 3);
            int index = 0;

            if (raw.startsWith(":")) {
                prefix = split[index++].substring(1);
            }

            command = split[index++];
            param = split[index++];

            this.prefix = prefix;
            this.command = command;
            this.param = param;
        }

        public String getCommand() {
            return command;
        }

        public String getParameter() {
            return param;
        }

        public String getPrefix() {
            return prefix;
        }

    }

}

Comments

Sign in to comment.
Aion-   -  Oct 10, 2012

Good luck with that!

 Respond  
Sorasyn   -  Oct 09, 2012

Yeah, that's just the connection. You've inspired me to do a rebuild of an IRC client I made almost a year ago from the ground up. :)

Just got done rebuilding the Socket architecture to fully support multiple server connections as the bottom layer. Just working on the UI now, which has to change since it's current UI can't support multiple servers very well, if at all. If I can manage to finish that up, all that'll need to be done is the tying up of a few loose ends.

 Respond  
Aion-   -  Oct 09, 2012

I thought this was normal: whenever I get to "Found your hostname", it seems to freeze for about 10 seconds and then proceeds. It also happens on mIRC. I believed it was caused by the server trying to find my identd so I disabled it, but this was in vain.

 Respond  
Sorasyn   -  Oct 08, 2012

Seems a little long winded to just initiate, read, and write. I do suppose some of that is parsing the strings and processing of data though. May be able to hard code in some catch algorithms to automatically reply to Ping calls so the connection doesn't have to rely on outside support to maintain the connection.

 Respond  
Aion-   -  Oct 08, 2012

Thanks!

I'm trying to apply the concepts of OOP as much as possible because it makes it just so much easier.

 Respond  
Sorasyn   -  Oct 08, 2012

Looks nice. :) I was in the process of making a Socket multiplexer for my IRC client to handle multiple server connections at once. Although I like how you broke it up into classes, may have to keep that in mind, mine looks like a jumbled mess. Lol.

 Respond  
Are you sure you want to unfollow this person?
Are you sure you want to delete this?
Click "Unsubscribe" to stop receiving notices pertaining to this post.
Click "Subscribe" to resume notices pertaining to this post.