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);
}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值