读书人

mina2官方例证chat客户端

发布时间: 2012-07-02 17:46:22 作者: rapoo

mina2官方例子chat客户端
这是ChatClientSupport:

package org.apache.mina.example.chat.client;import java.net.SocketAddress;import javax.net.ssl.SSLContext;import org.apache.mina.core.filterchain.IoFilter;import org.apache.mina.core.future.ConnectFuture;import org.apache.mina.core.service.IoHandler;import org.apache.mina.core.session.IoSession;import org.apache.mina.example.echoserver.ssl.BogusSslContextFactory;import org.apache.mina.filter.ssl.SslFilter;import org.apache.mina.filter.codec.ProtocolCodecFilter;import org.apache.mina.filter.codec.textline.TextLineCodecFactory;import org.apache.mina.filter.logging.LoggingFilter;import org.apache.mina.filter.logging.MdcInjectionFilter;import org.apache.mina.transport.socket.nio.NioSocketConnector;/** * A simple chat client for a given user. * * @author <a href="http://mina.apache.org">Apache MINA Project</a> */public class ChatClientSupport {    private final IoHandler handler;//客户端handler    private final String name;//用户名    private IoSession session;//连接    public ChatClientSupport(String name, IoHandler handler) {        if (name == null) {            throw new IllegalArgumentException("Name can not be null");        }        this.name = name;        this.handler = handler;    }    /**     * 连接chat服务器并返回连接结果     * @param connector 客户端连接     * @param address服务器地址     * @param useSsl是否启用ssl     * @return     */    public boolean connect(NioSocketConnector connector, SocketAddress address,            boolean useSsl) {    //已连接        if (session != null && session.isConnected()) {            throw new IllegalStateException(                    "Already connected. Disconnect first.");        }                try {            IoFilter LOGGING_FILTER = new LoggingFilter();            IoFilter CODEC_FILTER = new ProtocolCodecFilter(                    new TextLineCodecFactory());            //添加MdcInjectionFilter过滤器            connector.getFilterChain().addLast("mdc", new MdcInjectionFilter());            //添加协议编解码过滤器            connector.getFilterChain().addLast("codec", CODEC_FILTER);            //添加日志过滤器            connector.getFilterChain().addLast("logger", LOGGING_FILTER);            //启用ssl,添加ssl过滤器            if (useSsl) {            //edit me                SSLContext sslContext = BogusSslContextFactory                        .getInstance(false);                SslFilter sslFilter = new SslFilter(sslContext);                sslFilter.setUseClientMode(true);                connector.getFilterChain().addFirst("sslFilter", sslFilter);            }            //设置客户端handler            connector.setHandler(handler);            //返回连接Future            ConnectFuture future1 = connector.connect(address);            //等待连接成功,相当于异步转同步            future1.awaitUninterruptibly();            //连接失败            if (!future1.isConnected()) {                return false;            }            //连接成功,获取连接,如果没有上面的等待,由于connect()方法是异步的,session可能无法取得            session = future1.getSession();            //发送登录信息            login();            return true;        } catch (Exception e) {            return false;        }    }    /**     * 发送登录信息     */    public void login() {        session.write("LOGIN " + name);    }    /**     * 发送广播信息     * @param message     */    public void broadcast(String message) {        session.write("BROADCAST " + message);    }    /**     * 发送退出信息     */    public void quit() {        if (session != null) {            if (session.isConnected()) {                session.write("QUIT");                // Wait until the chat ends.                //等待直到获得服务器关闭连接的响应                session.getCloseFuture().awaitUninterruptibly();            }            //关闭客户端连接            session.close(true);        }    }}

这是SwingChatClientHandler:
package org.apache.mina.example.chat.client;import org.apache.mina.core.service.IoHandler;import org.apache.mina.core.service.IoHandlerAdapter;import org.apache.mina.core.session.IoSession;import org.apache.mina.example.chat.ChatCommand;/** * {@link IoHandler} implementation of the client side of the simple chat protocol. * * @author <a href="http://mina.apache.org">Apache MINA Project</a> */public class SwingChatClientHandler extends IoHandlerAdapter {//回调接口    public interface Callback {        void connected();//连接        void loggedIn();//登录        void loggedOut();//退出        void disconnected();//断开连接        void messageReceived(String message);//接收信息        void error(String message);//报错    }    private final Callback callback;    public SwingChatClientHandler(Callback callback) {        this.callback = callback;    }    /**     * 连接打开     * 回调callback接口的connected方法     */    @Override    public void sessionOpened(IoSession session) throws Exception {        callback.connected();    }    /**     * 接收信息     *      */    @Override    public void messageReceived(IoSession session, Object message)            throws Exception {        String theMessage = (String) message;        //将接收信息分成3部分        String[] result = theMessage.split(" ", 3);        //第二部分是状态码        String status = result[1];        //第一部分是命令参数        String theCommand = result[0];        //根据命令参数生成ChatCommand对象        ChatCommand command = ChatCommand.valueOf(theCommand);        //状态码OK处理        if ("OK".equals(status)) {                    switch (command.toInt()) {            //广播信息            case ChatCommand.BROADCAST:            //回调callback的messageReceived()方法                if (result.length == 3) {                    callback.messageReceived(result[2]);                }                break;                //登录            case ChatCommand.LOGIN:            //回调callback的loggedIn()方法                callback.loggedIn();                break;              //退出            case ChatCommand.QUIT:            //回调callback的loggedOut()方法                callback.loggedOut();                break;            }            //错误处理        } else {        //回调callback的error()方法            if (result.length == 3) {                callback.error(result[2]);            }        }    }    /**     * 连接关闭     * 回调callback接口的disconnected方法     */    @Override    public void sessionClosed(IoSession session) throws Exception {        callback.disconnected();    }}

这是ConnectDialog链接窗口:
package org.apache.mina.example.chat.client;import java.awt.BorderLayout;import java.awt.Frame;import java.awt.HeadlessException;import java.awt.event.ActionEvent;import javax.swing.AbstractAction;import javax.swing.BoxLayout;import javax.swing.JButton;import javax.swing.JCheckBox;import javax.swing.JDialog;import javax.swing.JLabel;import javax.swing.JPanel;import javax.swing.JTextField;/** * TODO Add documentation * 连接窗口 *  * @author <a href="http://mina.apache.org">Apache MINA Project</a> * */public class ConnectDialog extends JDialog {    private static final long serialVersionUID = 2009384520250666216L;    private String serverAddress;//服务器地址 IP:PORT    private String username;//用户名    private boolean useSsl;//启用ssl    private boolean cancelled = false;//edit me    public ConnectDialog(Frame owner) throws HeadlessException {        super(owner, "Connect", true);        serverAddress = "localhost:1234";//默认的服务器地址        username = "user" + Math.round(Math.random() * 10);//随机用户名        /*         * 一大堆swing的东西....         */        final JTextField serverAddressField = new JTextField(serverAddress);        final JTextField usernameField = new JTextField(username);        final JCheckBox useSslCheckBox = new JCheckBox("Use SSL", false);        JPanel content = new JPanel();        content.setLayout(new BoxLayout(content, BoxLayout.PAGE_AXIS));        content.add(new JLabel("Server address"));        content.add(serverAddressField);        content.add(new JLabel("Username"));        content.add(usernameField);        content.add(useSslCheckBox);        JButton okButton = new JButton();        okButton.setAction(new AbstractAction("OK") {            private static final long serialVersionUID = -2292183622613960604L;            public void actionPerformed(ActionEvent e) {                serverAddress = serverAddressField.getText();                username = usernameField.getText();                useSsl = useSslCheckBox.isSelected();                ConnectDialog.this.dispose();            }        });        JButton cancelButton = new JButton();        cancelButton.setAction(new AbstractAction("Cancel") {            private static final long serialVersionUID = 6122393546173723305L;            public void actionPerformed(ActionEvent e) {                cancelled = true;                ConnectDialog.this.dispose();            }        });        JPanel buttons = new JPanel();        buttons.add(okButton);        buttons.add(cancelButton);        getContentPane().add(content, BorderLayout.CENTER);        getContentPane().add(buttons, BorderLayout.SOUTH);    }    public boolean isCancelled() {        return cancelled;    }    public String getServerAddress() {        return serverAddress;    }    public String getUsername() {        return username;    }    public boolean isUseSsl() {        return useSsl;    }}

这是SwingChatClient,chat客户端,实现了callback接口:
package org.apache.mina.example.chat.client;import java.awt.BorderLayout;import java.awt.Dimension;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.net.InetSocketAddress;import java.net.SocketAddress;import javax.swing.AbstractAction;import javax.swing.BorderFactory;import javax.swing.Box;import javax.swing.BoxLayout;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing.JScrollBar;import javax.swing.JTextArea;import javax.swing.JTextField;import javax.swing.border.EmptyBorder;import org.apache.mina.example.chat.client.SwingChatClientHandler.Callback;import org.apache.mina.transport.socket.nio.NioSocketConnector;/** * Simple chat client based on Swing & MINA that implements the chat protocol. *chat客户端,实现了callback接口 * @author <a href="http://mina.apache.org">Apache MINA Project</a> */public class SwingChatClient extends JFrame implements Callback {    private static final long serialVersionUID = 1538675161745436968L;    private JTextField inputText;    private JButton loginButton;    private JButton quitButton;    private JButton closeButton;    private JTextField serverField;    private JTextField nameField;    private JTextArea area;    private JScrollBar scroll;    private ChatClientSupport client;    private SwingChatClientHandler handler;    private NioSocketConnector connector;    public SwingChatClient() {        super("Chat Client based on Apache MINA");        connector = new NioSocketConnector();        loginButton = new JButton(new LoginAction());        loginButton.setText("Connect");        quitButton = new JButton(new LogoutAction());        quitButton.setText("Disconnect");        closeButton = new JButton(new QuitAction());        closeButton.setText("Quit");        inputText = new JTextField(30);        inputText.setAction(new BroadcastAction());        area = new JTextArea(10, 50);        area.setLineWrap(true);        area.setEditable(false);        scroll = new JScrollBar();        scroll.add(area);        nameField = new JTextField(10);        nameField.setEditable(false);        serverField = new JTextField(10);        serverField.setEditable(false);        JPanel h = new JPanel();        h.setLayout(new BoxLayout(h, BoxLayout.LINE_AXIS));        h.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));        JLabel nameLabel = new JLabel("Name: ");        JLabel serverLabel = new JLabel("Server: ");        h.add(nameLabel);        h.add(Box.createRigidArea(new Dimension(10, 0)));        h.add(nameField);        h.add(Box.createRigidArea(new Dimension(10, 0)));        h.add(Box.createHorizontalGlue());        h.add(Box.createRigidArea(new Dimension(10, 0)));        h.add(serverLabel);        h.add(Box.createRigidArea(new Dimension(10, 0)));        h.add(serverField);        JPanel p = new JPanel();        p.setLayout(new BoxLayout(p, BoxLayout.LINE_AXIS));        p.setBorder(new EmptyBorder(10, 10, 10, 10));        JPanel left = new JPanel();        left.setLayout(new BoxLayout(left, BoxLayout.PAGE_AXIS));        left.add(area);        left.add(Box.createRigidArea(new Dimension(0, 5)));        left.add(Box.createHorizontalGlue());        left.add(inputText);        JPanel right = new JPanel();        right.setLayout(new BoxLayout(right, BoxLayout.PAGE_AXIS));        right.add(loginButton);        right.add(Box.createRigidArea(new Dimension(0, 5)));        right.add(quitButton);        right.add(Box.createHorizontalGlue());        right.add(Box.createRigidArea(new Dimension(0, 25)));        right.add(closeButton);        p.add(left);        p.add(Box.createRigidArea(new Dimension(10, 0)));        p.add(right);        getContentPane().add(h, BorderLayout.NORTH);        getContentPane().add(p);        closeButton.addActionListener(new ActionListener() {            public void actionPerformed(ActionEvent e) {                client.quit();                connector.dispose();                 dispose();            }        });        setLoggedOut();        setDefaultCloseOperation(EXIT_ON_CLOSE);    }    /**     * 登录操作     * @author jzyang     *     */    public class LoginAction extends AbstractAction {        private static final long serialVersionUID = 3596719854773863244L;        public void actionPerformed(ActionEvent e) {        //弹出连接窗口            ConnectDialog dialog = new ConnectDialog(SwingChatClient.this);            dialog.pack();            dialog.setVisible(true);            if (dialog.isCancelled()) {                return;            }            //将对话框的地址解析成SocketAddress对象            SocketAddress address = parseSocketAddress(dialog                    .getServerAddress());            //用户名            String name = dialog.getUsername();                        handler = new SwingChatClientHandler(SwingChatClient.this);            client = new ChatClientSupport(name, handler);            nameField.setText(name);            serverField.setText(dialog.getServerAddress());            //连接服务器,不成功则弹出提示对话框            if (!client.connect(connector, address, dialog.isUseSsl())) {                JOptionPane.showMessageDialog(SwingChatClient.this,                        "Could not connect to " + dialog.getServerAddress()                                + ". ");            }        }    }    private class LogoutAction extends AbstractAction {        private static final long serialVersionUID = 1655297424639924560L;        public void actionPerformed(ActionEvent e) {            try {                client.quit();                setLoggedOut();            } catch (Exception e1) {                JOptionPane.showMessageDialog(SwingChatClient.this,                        "Session could not be closed.");            }        }    }    private class BroadcastAction extends AbstractAction {        /**         *         */        private static final long serialVersionUID = -6276019615521905411L;        public void actionPerformed(ActionEvent e) {            client.broadcast(inputText.getText());            inputText.setText("");        }    }    private class QuitAction extends AbstractAction {        private static final long serialVersionUID = -6389802816912005370L;        public void actionPerformed(ActionEvent e) {            if (client != null) {                client.quit();            }            SwingChatClient.this.dispose();        }    }    /**     * 退出后,     * 将输入,退出,设置为不可用,登录按钮可用     */    private void setLoggedOut() {        inputText.setEnabled(false);        quitButton.setEnabled(false);        loginButton.setEnabled(true);    }    /**     * 登录后,     * 提示区域为空,将输入,退出,设置为可用,登录按钮不可用     */    private void setLoggedIn() {        area.setText("");        inputText.setEnabled(true);        quitButton.setEnabled(true);        loginButton.setEnabled(false);    }    /**     * 增加提示信息     * @param text 提示信息     */    private void append(String text) {        area.append(text);    }    /**     * 弹出错误信息     * @param message 错误信息     */    private void notifyError(String message) {        JOptionPane.showMessageDialog(this, message);    }    /**     * 解析socket地址,返回InetSocketAddress对象     * @param s     * @return     */    private SocketAddress parseSocketAddress(String s) {        s = s.trim();        int colonIndex = s.indexOf(":");        if (colonIndex > 0) {            String host = s.substring(0, colonIndex);            int port = parsePort(s.substring(colonIndex + 1));            return new InetSocketAddress(host, port);        } else {            int port = parsePort(s.substring(colonIndex + 1));            return new InetSocketAddress(port);        }    }    /**     * 将字符串装换成数字     * @param sport字符串     * @returnport数值     */    private int parsePort(String s) {        try {            return Integer.parseInt(s);        } catch (NumberFormatException nfe) {            throw new IllegalArgumentException("Illegal port number: " + s);        }    }    public void connected() {        //client.login();    }    /**     * 断开连接     */    public void disconnected() {        append("Connection closed.\n");        setLoggedOut();    }    public void error(String message) {        notifyError(message + "\n");    }    /**     * 登录并提示登录信息     */    public void loggedIn() {        setLoggedIn();        append("You have joined the chat session.\n");    }    /**     * 退出并提示退出信息     */    public void loggedOut() {        append("You have left the chat session.\n");        setLoggedOut();    }    /**     * 提示接收信息     */    public void messageReceived(String message) {        append(message + "\n");    }    public static void main(String[] args) {        SwingChatClient client = new SwingChatClient();        client.pack();        client.setVisible(true);    }}

读书人网 >开源软件

热点推荐