首先看一下运行效果图
关于mina在这里就不多说,google一搜很多对其介绍.
本文主要就是想在swt中采用mina来实现聊天.
首先我把源代码贴出来
MinaServerUI类是服务端界面类
package com.cayden.swtmina; 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是服务端的处理类
/** * * 类IoHandlerAdapter用于定义业务逻辑 * sessionCreated() 当会话创建时被触发 * sessionOpened() 当会话开始时被触发 sessionClosed() 当会话关闭时被触发 sessionIdle() 当会话空闲时被触发 exceptionCaught() 当接口中其他方法抛出异常未被捕获时触发此方法 messageRecieved() 当接收到消息后被触发 messageSent() 当发送消息后被触发 */ package com.cayden.mina; 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是客户端的界面类
package com.cayden.swtmina; 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是客户端的处理类
package com.cayden.mina; 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方法里面写了个线程
然后用死循环,我是这样处理服务端发送消息,大家看了后,若有更好方法可以直接留言.谢谢.
若需要程序的,留下的你的邮箱,我会在第一时间发送给你.