`
yangghost
  • 浏览: 13376 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

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 s	port字符串
     * @return	port数值
     */
    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);
    }
}
分享到:
评论

相关推荐

    mina2推送demo客户端

    《MINA2推送Demo客户端详解及应用》 MINA(Multi-purpose Infrastructure for Network Applications)是一个高性能、异步的网络通信框架,由Apache软件基金会开发,主要用于构建网络应用程序,如TCP/IP和UDP/IP协议...

    mina2服务端客户端实例,保证能够正常运行

    标签中的"mina"和"mina2"指代Apache MINA框架的不同版本,"例子"表示这是一个示例代码集合,"服务端"和"客户端"则明确了示例涵盖了网络通信的两端——服务器端和客户端的实现。 根据提供的压缩包文件名称列表"mina...

    mina客户端简单代码示例

    2. **创建IoSession**:IoSession是Mina的核心概念,代表了客户端和服务器之间的会话。客户端需要初始化一个IoConnector来建立连接,并通过connect()方法创建IoSession。 3. **定义ProtocolCodecFilter**:为了进行...

    mina 同步客户端,异步客户端

    2. **同步客户端**:在同步模式下,客户端每次发送请求后都会等待服务器的响应。这种方式简单易懂,但效率较低,因为每个请求都需要占用一个线程直到响应返回。在MINA中,同步客户端通常使用`IoHandler`接口来处理...

    Apache Mina2服务器和客户端简单实例

    Apache Mina2是一个高度可扩展且高性能的网络通信框架,主要设计用于简化开发网络应用,如TCP/IP和UDP协议的服务端和客户端。它提供了一种事件驱动、非阻塞I/O模型,使得开发者能够更专注于业务逻辑,而不是底层的...

    Mina 服务端客户端示例程序

    2. **事件驱动**:Mina使用事件驱动架构,通过监听器接口(IoHandler)来处理网络事件,如连接建立、数据接收、连接关闭等。当这些事件发生时,对应的回调方法会被触发。 3. **过滤器链**:Mina的过滤器(Filter)...

    Mina开发之客户端

    《Mina开发之客户端详解》 Apache Mina(Minimum Asynchronous Network)是一个高度可扩展的、高性能的网络应用框架,主要用于构建服务器端的网络应用程序。它简化了网络编程的复杂性,提供了基于事件驱动和异步I/O...

    mina server开发服务端/客户端代码

    2. Session:代表了客户端和服务端之间的连接,具有读写数据、管理属性和关闭连接的能力。 3. Filter Chain:Mina使用过滤器链来处理进来的数据和事件,每个过滤器可以执行特定的操作,如数据编码解码、日志记录或...

    mina连接 mina心跳连接 mina断线重连

    在Mina中,连接是指客户端与服务端之间建立的通信链路。它支持多种传输协议,如TCP/IP(Socket)、UDP(Datagram)等。Mina提供了一种事件驱动的模型,通过IoSession接口来管理连接,包括读写数据、添加监听器、关闭...

    mina传文件案例,客户端加服务端

    本案例将深入探讨如何使用Mina作为服务端,结合Socket客户端实现文件的传输。 一、Apache Mina框架介绍 Apache Mina,全称为“Minimalist Application Networking Abstraction”,是一个提供了统一的API来处理多种...

    基于mina的一个Memcached客户端首发

    标题中的“基于mina的一个Memcached客户端首发”指出我们要讨论的是一个使用Apache MINA框架实现的Memcached客户端。Apache MINA是一个网络应用框架,主要用于简化开发高性能且高度可伸缩的网络应用程序,如服务器和...

    mina客户端例子

    在这个"mina客户端例子"中,我们将探讨如何利用MINA构建一个简单的客户端,实现基于NIO(Non-blocking I/O)的游戏开发和即时通讯工具。 首先,让我们了解NIO。在Java中,传统的I/O模型是阻塞的,这意味着当进行...

    mina2 cs 客户端服务器通信 已经实现完整通信代码

    在“MINA2 CS客户端服务器通信”中,我们关注的是如何利用MINA2框架实现客户端与服务器之间的有效通信。下面将详细介绍MINA2框架以及如何实现客户端和服务器的通信。 MINA2全称为"Multi-purpose Infrastructure for...

    mina 长连接 客户端+服务端

    2. **客户端实现**: - 创建一个SocketConnector,这是客户端的核心,负责发起连接请求到服务端。 - 定义IoHandler,处理客户端的连接、读写事件。 - 设置必要的过滤器,如在客户端也需要配置协议处理器,确保...

    mina通信服务器端客户端源码.rar

    代码利用mina框架实现了服务器端和客户端,客户端的登录请求、客户端向服务器端请求图片文件的功能。代码分为服务端和客户端,开发环境eclipse。服务器代码可在web项目中使用,客户端代码可以在Android开发时使用,...

    apache-mina例子

    这个例子是关于如何使用Apache Mina实现一个简单的服务端和客户端通信的示例。在这个案例中,`MinaTimeServer`是服务端程序,它负责监听客户端的连接请求,并发送时间信息;而`MinaClient`则是客户端程序,它连接到...

    练练手,用mina2.0搭建一个nio客户端

    标题中的“练练手,用mina2.0搭建一个nio客户端”表明了本文将探讨如何使用Mina 2.0框架构建一个基于非阻塞I/O(NIO)的客户端应用。Mina是一个开源的Java框架,常用于开发高性能、高并发的网络通信应用,如TCP/IP和...

    mina框架中socket使用,有服务端和客户端。

    2. **Socket编程**:Socket是网络通信的基本组件,它在MINA框架中被用来建立和管理网络连接。Socket提供了一种进程间通信(IPC)的方式,允许两个远程系统之间交换数据。MINA框架中的Socket服务端和客户端通过Socket...

    Mina长连接(Android客户端-Java服务器)简单应用

    《Mina长连接在Android客户端与Java服务器中的应用详解》 Mina(Minimal Asynchronous Network)是一个开源的网络通信框架,广泛应用于Java平台,尤其在处理高性能、高并发的网络应用时表现出色。本篇文章将深入...

Global site tag (gtag.js) - Google Analytics