首先看一下运行效果图
关于mina在这里就不多说,google一搜很多对其介绍.
本文主要就是想在swt中采用mina来实现聊天.
首先我把源代码贴出来
MinaServerUI类是服务端界面类
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.util.Set;
import org.apache.mina.common.IoAcceptor;
import org.apache.mina.common.IoSession;
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.transport.socket.nio.NioSocketAcceptor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import com.cayden.mina.TimeServerHandler;
public class MinaServerUI {
private static final int PORT = 9123;//定义监听端口
private Text text;
private List list;
private TimeServerHandler timeServerHandler=new TimeServerHandler(this);
/**
* Launch the application
* @param args
*/
public static void main(String[] args) {
try {
MinaServerUI window = new MinaServerUI();
window.open();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Open the window
*/
public void open() {
final Display display = Display.getDefault();
final Shell shell = new Shell();
shell.addShellListener(new ShellAdapter() {
public void shellClosed(final ShellEvent e) {
System.exit(1);
}
});
shell.setSize(518, 410);
shell.setText("MINA服务端");
//
shell.open();
list = new List(shell, SWT.BORDER);
list.setBounds(10, 10, 399, 246);
text = new Text(shell, SWT.BORDER);
text.setBounds(10, 295, 399, 62);
final Button button = new Button(shell, SWT.NONE);
button.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(final SelectionEvent e) {
String str=text.getText();
timeServerHandler.setMessages(str);
list.add("服务端:"+str);
text.setText("");
}
});
button.setText("发送");
button.setBounds(440, 335, 48, 22);
final Button button_1 = new Button(shell, SWT.NONE);
button_1.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(final SelectionEvent e) {
/**
* 为开启服务重新开线程
*/
new Thread(){
public void run(){
try{
IoAcceptor acceptor = new NioSocketAcceptor();
acceptor.getFilterChain().addLast( "logger", new LoggingFilter() );
acceptor.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" ))));//指定编码过滤器
acceptor.setHandler(timeServerHandler);//指定业务逻辑处理器
acceptor.setDefaultLocalAddress( new InetSocketAddress(PORT) );//设置端口号
acceptor.bind();//启动监听
}catch (Exception e1) {
// TODO: handle exception
System.out.println(e1.getMessage());
}
}
}.start();
}
});
button_1.setText("开启");
button_1.setBounds(440, 9, 48, 22);
shell.layout();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
}
public Text getText() {
return text;
}
public List getList() {
return list;
}
}
TimeServerHandler是服务端的处理类
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import org.apache.mina.common.IdleStatus;
import org.apache.mina.common.IoAcceptor;
import org.apache.mina.common.IoHandlerAdapter;
import org.apache.mina.common.IoSession;
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.transport.socket.nio.NioSocketAcceptor;
import org.eclipse.swt.widgets.Display;
import com.cayden.swtmina.MinaServerUI;
public class TimeServerHandler extends IoHandlerAdapter {
private MinaServerUI minaServerUI;
private String messages="";
public TimeServerHandler(MinaServerUI minaServerUI){
this.minaServerUI=minaServerUI;
}
@Override
public void exceptionCaught(IoSession session, Throwable cause)
throws Exception {
// TODO Auto-generated method stub
super.exceptionCaught(session, cause);
}
@Override
public void messageSent(IoSession session, Object message) throws Exception {
// TODO Auto-generated method stub
super.messageSent(session, message);
System.out.println("Message written...");
}
/**
* 当会话关闭时被触发
*/
@Override
public void sessionClosed(IoSession session) throws Exception {
// TODO Auto-generated method stub
super.sessionClosed(session);
System.out.println("会话关闭");
}
@Override
public void sessionIdle(IoSession session, IdleStatus status)
throws Exception {
// TODO Auto-generated method stub
super.sessionIdle(session, status);
}
/**
* 当会话开始时被触发
*/
@Override
public void sessionOpened(final IoSession session) throws Exception {
// TODO Auto-generated method stub
super.sessionOpened(session);
this.setServerList("服务开启...");
session.write("Hello ,you are success...");
/**
* 开启线程进行发送控制
*/
new Thread(){
public void run(){
while(true){
if(!"".equals(messages)&&null!=messages){
session.write(messages);
setMessages(null);
}
}
}
}.start();
}
/**
* 当会话创建时被触发
*/
@Override
public void sessionCreated(IoSession session) {
//显示客户端的ip和端口
System.out.println(session.getRemoteAddress().toString());
}
/**
* 当接收到消息后被触发
*/
@Override
public void messageReceived(final IoSession session, Object message ) throws Exception
{
String str = message.toString();
System.out.println("收到客户信息:"+str);
if( str.trim().equalsIgnoreCase("quit") ) {
this.setServerList("客户端:/n"+"客户关闭...");
session.close();//结束会话
return;
}
else{
this.setServerList("客户端:/n"+str);
}
// new Thread(){
// public void run(){
// while(true){
//// if(!"".equals(messages)&&null!=messages){
//// session.write(messages);
//// messages=null;
//// }
// if(list.size()>0){
// System.out.println("list.size()="+list.size());
// session.write(list.get(0));
// list.remove(0);
// }
// }
// }
// }.start();
}
@SuppressWarnings("unused")
private void setDealChatServer(){
Display.getDefault().syncExec(new Runnable(){
public void run(){
minaServerUI.getText().setText("");
}
});
}
/**
* 设置服务端的显示信息
* @param str
*/
@SuppressWarnings("unused")
private void setServerList(final String str){
Display.getDefault().syncExec(new Runnable(){
public void run(){
minaServerUI.getList().add(str);
}
});
}
public void setMessages(String messages) {
this.messages = messages;
}
}
MinaClientUT是客户端的界面类
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import org.apache.mina.common.ConnectFuture;
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.transport.socket.nio.NioSocketConnector;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import com.cayden.mina.TimeClientHandler;
public class MinaClientUT {
private Text text=null;
private List list;
private TimeClientHandler timeClientHandler=new TimeClientHandler(this);
ConnectFuture cf=null;
/**
* Launch the application
* @param args
*/
public static void main(String[] args) {
try {
MinaClientUT window = new MinaClientUT();
window.open();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Open the window
*/
public void open() {
final Display display = Display.getDefault();
final Shell shell = new Shell();
shell.addShellListener(new ShellAdapter() {
public void shellClosed(final ShellEvent e) {
cf.getSession().write("quit");
}
});
shell.setSize(518, 410);
shell.setText("MINA客户端");
//
shell.open();
list = new List(shell, SWT.BORDER);
list.setBounds(10, 10, 399, 246);
text = new Text(shell, SWT.BORDER);
text.setBounds(10, 295, 399, 62);
final Button button = new Button(shell, SWT.NONE);
button.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(final SelectionEvent e) {
String str=text.getText();
cf.getSession().write(str);
list.add("客户端:/n"+str);
text.setText("");
}
});
button.setText("发送");
button.setBounds(440, 335, 48, 22);
final Button button_1 = new Button(shell, SWT.NONE);
button_1.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(final SelectionEvent e) {
new Thread(){
public void run(){
NioSocketConnector connector = new NioSocketConnector();
connector.getFilterChain().addLast( "logger", new LoggingFilter() );
connector.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" )))); //设置编码过滤器
connector.setConnectTimeout(30);
connector.setHandler(timeClientHandler);//设置事件处理器
cf = connector.connect(
new InetSocketAddress("127.0.0.1", 9123));//建立连接
cf.awaitUninterruptibly();//等待连接创建完成
cf.getSession().write("hello");//发送消息
// cf.getSession().write("quit");//发送消息
cf.getSession().getCloseFuture().awaitUninterruptibly();//等待连接断开
connector.dispose();
}
}.start();
}
});
button_1.setText("连接");
button_1.setBounds(440, 9, 48, 22);
shell.layout();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
}
public Text getText() {
return text;
}
public List getList() {
return list;
}
}
TimeClientHandler是客户端的处理类
import org.apache.mina.common.IdleStatus;
import org.apache.mina.common.IoHandlerAdapter;
import org.apache.mina.common.IoSession;
import org.eclipse.swt.widgets.Display;
import com.cayden.swtmina.MinaClientUT;
public class TimeClientHandler extends IoHandlerAdapter {
private MinaClientUT minaClientUT;
public TimeClientHandler(MinaClientUT minaClientUT){
this.minaClientUT=minaClientUT;
}
@Override
public void exceptionCaught(IoSession session, Throwable cause)
throws Exception {
// TODO Auto-generated method stub
super.exceptionCaught(session, cause);
}
@Override
public void messageSent(IoSession session, Object message) throws Exception {
// TODO Auto-generated method stub
super.messageSent(session, message);
}
@Override
public void sessionClosed(IoSession session) throws Exception {
// TODO Auto-generated method stub
super.sessionClosed(session);
}
@Override
public void sessionCreated(IoSession session) throws Exception {
// TODO Auto-generated method stub
super.sessionCreated(session);
}
@Override
public void sessionIdle(IoSession session, IdleStatus status)
throws Exception {
// TODO Auto-generated method stub
super.sessionIdle(session, status);
}
@Override
public void sessionOpened(IoSession session) throws Exception {
// TODO Auto-generated method stub
super.sessionOpened(session);
}
public TimeClientHandler() {
}
@Override
public void messageReceived(IoSession session, Object message) throws Exception {
System.out.println(message);//显示接收到的消息
this.setServerList(message.toString());
}
@SuppressWarnings("unused")
private void setDealChatServer(){
Display.getDefault().syncExec(new Runnable(){
public void run(){
minaClientUT.getText().setText("");
}
});
}
/**
* 设置服务端的显示信息
* @param str
*/
@SuppressWarnings("unused")
private void setServerList(final String str){
Display.getDefault().syncExec(new Runnable(){
public void run(){
minaClientUT.getList().add("服务端:/n"+str);
}
});
}
}
以上四个类就包含整个程序.
需要注意的是,我在由服务端发送消息给客户端的时候是在服务端的处理类里面的 sessionOpened方法里面写了个线程
然后用死循环,我是这样处理服务端发送消息,大家看了后,若有更好方法可以直接留言.谢谢.