这是ChatClientSupport:
这是SwingChatClientHandler:
这是ConnectDialog链接窗口:
这是SwingChatClient,chat客户端,实现了callback接口:
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客户端详解及应用》 MINA(Multi-purpose Infrastructure for Network Applications)是一个高性能、异步的网络通信框架,由Apache软件基金会开发,主要用于构建网络应用程序,如TCP/IP和UDP/IP协议...
标签中的"mina"和"mina2"指代Apache MINA框架的不同版本,"例子"表示这是一个示例代码集合,"服务端"和"客户端"则明确了示例涵盖了网络通信的两端——服务器端和客户端的实现。 根据提供的压缩包文件名称列表"mina...
2. **创建IoSession**:IoSession是Mina的核心概念,代表了客户端和服务器之间的会话。客户端需要初始化一个IoConnector来建立连接,并通过connect()方法创建IoSession。 3. **定义ProtocolCodecFilter**:为了进行...
2. **同步客户端**:在同步模式下,客户端每次发送请求后都会等待服务器的响应。这种方式简单易懂,但效率较低,因为每个请求都需要占用一个线程直到响应返回。在MINA中,同步客户端通常使用`IoHandler`接口来处理...
Apache Mina2是一个高度可扩展且高性能的网络通信框架,主要设计用于简化开发网络应用,如TCP/IP和UDP协议的服务端和客户端。它提供了一种事件驱动、非阻塞I/O模型,使得开发者能够更专注于业务逻辑,而不是底层的...
2. **事件驱动**:Mina使用事件驱动架构,通过监听器接口(IoHandler)来处理网络事件,如连接建立、数据接收、连接关闭等。当这些事件发生时,对应的回调方法会被触发。 3. **过滤器链**:Mina的过滤器(Filter)...
《Mina开发之客户端详解》 Apache Mina(Minimum Asynchronous Network)是一个高度可扩展的、高性能的网络应用框架,主要用于构建服务器端的网络应用程序。它简化了网络编程的复杂性,提供了基于事件驱动和异步I/O...
2. Session:代表了客户端和服务端之间的连接,具有读写数据、管理属性和关闭连接的能力。 3. Filter Chain:Mina使用过滤器链来处理进来的数据和事件,每个过滤器可以执行特定的操作,如数据编码解码、日志记录或...
在Mina中,连接是指客户端与服务端之间建立的通信链路。它支持多种传输协议,如TCP/IP(Socket)、UDP(Datagram)等。Mina提供了一种事件驱动的模型,通过IoSession接口来管理连接,包括读写数据、添加监听器、关闭...
本案例将深入探讨如何使用Mina作为服务端,结合Socket客户端实现文件的传输。 一、Apache Mina框架介绍 Apache Mina,全称为“Minimalist Application Networking Abstraction”,是一个提供了统一的API来处理多种...
标题中的“基于mina的一个Memcached客户端首发”指出我们要讨论的是一个使用Apache MINA框架实现的Memcached客户端。Apache MINA是一个网络应用框架,主要用于简化开发高性能且高度可伸缩的网络应用程序,如服务器和...
在这个"mina客户端例子"中,我们将探讨如何利用MINA构建一个简单的客户端,实现基于NIO(Non-blocking I/O)的游戏开发和即时通讯工具。 首先,让我们了解NIO。在Java中,传统的I/O模型是阻塞的,这意味着当进行...
在“MINA2 CS客户端服务器通信”中,我们关注的是如何利用MINA2框架实现客户端与服务器之间的有效通信。下面将详细介绍MINA2框架以及如何实现客户端和服务器的通信。 MINA2全称为"Multi-purpose Infrastructure for...
2. **客户端实现**: - 创建一个SocketConnector,这是客户端的核心,负责发起连接请求到服务端。 - 定义IoHandler,处理客户端的连接、读写事件。 - 设置必要的过滤器,如在客户端也需要配置协议处理器,确保...
代码利用mina框架实现了服务器端和客户端,客户端的登录请求、客户端向服务器端请求图片文件的功能。代码分为服务端和客户端,开发环境eclipse。服务器代码可在web项目中使用,客户端代码可以在Android开发时使用,...
这个例子是关于如何使用Apache Mina实现一个简单的服务端和客户端通信的示例。在这个案例中,`MinaTimeServer`是服务端程序,它负责监听客户端的连接请求,并发送时间信息;而`MinaClient`则是客户端程序,它连接到...
标题中的“练练手,用mina2.0搭建一个nio客户端”表明了本文将探讨如何使用Mina 2.0框架构建一个基于非阻塞I/O(NIO)的客户端应用。Mina是一个开源的Java框架,常用于开发高性能、高并发的网络通信应用,如TCP/IP和...
2. **Socket编程**:Socket是网络通信的基本组件,它在MINA框架中被用来建立和管理网络连接。Socket提供了一种进程间通信(IPC)的方式,允许两个远程系统之间交换数据。MINA框架中的Socket服务端和客户端通过Socket...
《Mina长连接在Android客户端与Java服务器中的应用详解》 Mina(Minimal Asynchronous Network)是一个开源的网络通信框架,广泛应用于Java平台,尤其在处理高性能、高并发的网络应用时表现出色。本篇文章将深入...