├── .gitignore ├── mina2-demos ├── .gitignore ├── src │ ├── main │ │ ├── resources │ │ │ ├── com │ │ │ │ └── waylau │ │ │ │ │ └── mina │ │ │ │ │ └── demo │ │ │ │ │ ├── echoserver │ │ │ │ │ └── ssl │ │ │ │ │ │ └── bogus.cert │ │ │ │ │ └── chat │ │ │ │ │ └── serverContext.xml │ │ │ └── log4j.properties │ │ └── java │ │ │ └── com │ │ │ └── waylau │ │ │ └── mina │ │ │ ├── App.java │ │ │ ├── demo │ │ │ ├── sumup │ │ │ │ ├── message │ │ │ │ │ ├── AbstractMessage.java │ │ │ │ │ ├── AddMessage.java │ │ │ │ │ └── ResultMessage.java │ │ │ │ ├── codec │ │ │ │ │ ├── AddMessageEncoder.java │ │ │ │ │ ├── Constants.java │ │ │ │ │ ├── SumUpProtocolCodecFactory.java │ │ │ │ │ ├── ResultMessageEncoder.java │ │ │ │ │ ├── AddMessageDecoder.java │ │ │ │ │ ├── AbstractMessageEncoder.java │ │ │ │ │ ├── ResultMessageDecoder.java │ │ │ │ │ └── AbstractMessageDecoder.java │ │ │ │ ├── Server.java │ │ │ │ ├── ClientSessionHandler.java │ │ │ │ ├── Client.java │ │ │ │ └── ServerSessionHandler.java │ │ │ ├── imagine │ │ │ │ ├── client │ │ │ │ │ ├── ImageListener.java │ │ │ │ │ ├── ImagePanel.java │ │ │ │ │ ├── ImageClient.java │ │ │ │ │ └── GraphicalCharGenClient.java │ │ │ │ ├── ImageResponse.java │ │ │ │ ├── ImageRequest.java │ │ │ │ ├── codec │ │ │ │ │ ├── ImageRequestDecoder.java │ │ │ │ │ ├── ImageRequestEncoder.java │ │ │ │ │ ├── ImageCodecFactory.java │ │ │ │ │ ├── ImageResponseEncoder.java │ │ │ │ │ └── ImageResponseDecoder.java │ │ │ │ └── server │ │ │ │ │ ├── ImageServer.java │ │ │ │ │ └── ImageServerIoHandler.java │ │ │ ├── simplechat │ │ │ │ ├── SimpleChatClientHandler.java │ │ │ │ ├── SimpleChatServer.java │ │ │ │ ├── SimpleChatClient.java │ │ │ │ └── SimpleChatServerHandler.java │ │ │ ├── chat │ │ │ │ ├── ChatCommand.java │ │ │ │ ├── SpringMain.java │ │ │ │ ├── client │ │ │ │ │ ├── SwingChatClientHandler.java │ │ │ │ │ ├── ConnectDialog.java │ │ │ │ │ ├── ChatClientSupport.java │ │ │ │ │ └── SwingChatClient.java │ │ │ │ ├── Main.java │ │ │ │ └── ChatProtocolHandler.java │ │ │ ├── time │ │ │ │ ├── TimeServerHandler.java │ │ │ │ └── MinaTimeServer.java │ │ │ ├── udp │ │ │ │ ├── ClientPanel.java │ │ │ │ ├── MemoryMonitorHandler.java │ │ │ │ ├── MemoryMonitor.java │ │ │ │ ├── client │ │ │ │ │ └── MemMonClient.java │ │ │ │ └── perf │ │ │ │ │ ├── UdpClient.java │ │ │ │ │ └── UdpServer.java │ │ │ └── echoserver │ │ │ │ ├── ssl │ │ │ │ ├── BogusTrustManagerFactory.java │ │ │ │ ├── SslServerSocketFactory.java │ │ │ │ ├── SslSocketFactory.java │ │ │ │ └── BogusSslContextFactory.java │ │ │ │ ├── EchoProtocolHandler.java │ │ │ │ └── Main.java │ │ │ └── TcpClient.java │ └── test │ │ └── java │ │ └── com │ │ └── waylau │ │ └── netty │ │ └── AppTest.java └── pom.xml └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | /.idea/ 3 | /.settings/ 4 | .classpath 5 | .project -------------------------------------------------------------------------------- /mina2-demos/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | /.idea/ 3 | /.settings/ 4 | .classpath 5 | .project -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # apache-mina-2-user-guide-demos 2 | Demos of [Apache MINA User Guide](https://github.com/waylau/apache-mina-2.x-user-guide) 《Apache MINA 2 用户指南》中文翻译,文中用到的例子源码 3 | -------------------------------------------------------------------------------- /mina2-demos/src/main/resources/com/waylau/mina/demo/echoserver/ssl/bogus.cert: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waylau/apache-mina-2-user-guide-demos/HEAD/mina2-demos/src/main/resources/com/waylau/mina/demo/echoserver/ssl/bogus.cert -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/App.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina; 2 | 3 | /** 4 | * Hello world! 5 | * 6 | * @author waylau.com 7 | * @date 2015-2-26 8 | */ 9 | public class App { 10 | public static void main(String[] args) { 11 | System.out.println("Hello World!"); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/sumup/message/AbstractMessage.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.sumup.message; 2 | 3 | import java.io.Serializable; 4 | 5 | public abstract class AbstractMessage implements Serializable { 6 | private int sequence; 7 | 8 | public int getSequence() { 9 | return sequence; 10 | } 11 | 12 | public void setSequence(int sequence) { 13 | this.sequence = sequence; 14 | } 15 | } -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/imagine/client/ImageListener.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.imagine.client; 2 | 3 | import java.awt.image.BufferedImage; 4 | 5 | /** 6 | * TODO Add documentation 7 | * 8 | * @author waylau.com 9 | * @date 2015-2-26 10 | */ 11 | public interface ImageListener { 12 | void onImages(BufferedImage image1, BufferedImage image2); 13 | 14 | void onException(Throwable throwable); 15 | 16 | void sessionOpened(); 17 | 18 | void sessionClosed(); 19 | } 20 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/simplechat/SimpleChatClientHandler.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.simplechat; 2 | 3 | import org.apache.mina.core.service.IoHandlerAdapter; 4 | import org.apache.mina.core.session.IoSession; 5 | 6 | /** 7 | * 说明:简单聊天室 客户端 处理类 8 | * 9 | * @author waylau.com 2015年4月10日 10 | */ 11 | public class SimpleChatClientHandler extends IoHandlerAdapter { 12 | @Override 13 | public void messageReceived(IoSession session, Object message) { 14 | String str = message.toString(); 15 | System.out.println(str); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/sumup/message/AddMessage.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.sumup.message; 2 | 3 | public class AddMessage extends AbstractMessage { 4 | private static final long serialVersionUID = -940833727168119141L; 5 | 6 | private int value; 7 | 8 | public AddMessage() { 9 | } 10 | 11 | public int getValue() { 12 | return value; 13 | } 14 | 15 | public void setValue(int value) { 16 | this.value = value; 17 | } 18 | 19 | @Override 20 | public String toString() { 21 | // it is a good practice to create toString() method on message classes. 22 | return getSequence() + ":ADD(" + value + ')'; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/sumup/codec/AddMessageEncoder.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.sumup.codec; 2 | 3 | import org.apache.mina.core.buffer.IoBuffer; 4 | import org.apache.mina.core.session.IoSession; 5 | 6 | import com.waylau.mina.demo.sumup.message.AddMessage; 7 | 8 | public class AddMessageEncoder extends 9 | AbstractMessageEncoder { 10 | public AddMessageEncoder() { 11 | super(Constants.ADD); 12 | } 13 | 14 | @Override 15 | protected void encodeBody(IoSession session, T message, IoBuffer out) { 16 | out.putInt(message.getValue()); 17 | } 18 | 19 | public void dispose() throws Exception { 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/imagine/ImageResponse.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.imagine; 2 | 3 | import java.awt.image.BufferedImage; 4 | 5 | /** 6 | * response sent by the server when receiving an {@link ImageRequest} 7 | * 8 | * @author waylau.com 9 | * @date 2015-2-26 10 | */ 11 | public class ImageResponse { 12 | 13 | private BufferedImage image1; 14 | 15 | private BufferedImage image2; 16 | 17 | public ImageResponse(BufferedImage image1, BufferedImage image2) { 18 | this.image1 = image1; 19 | this.image2 = image2; 20 | } 21 | 22 | public BufferedImage getImage1() { 23 | return image1; 24 | } 25 | 26 | public BufferedImage getImage2() { 27 | return image2; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/sumup/codec/Constants.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.sumup.codec; 2 | 3 | public class Constants { 4 | public static final int TYPE_LEN = 2; 5 | 6 | public static final int SEQUENCE_LEN = 4; 7 | 8 | public static final int HEADER_LEN = TYPE_LEN + SEQUENCE_LEN; 9 | 10 | public static final int BODY_LEN = 12; 11 | 12 | public static final int RESULT = 0; 13 | 14 | public static final int ADD = 1; 15 | 16 | public static final int RESULT_CODE_LEN = 2; 17 | 18 | public static final int RESULT_VALUE_LEN = 4; 19 | 20 | public static final int ADD_BODY_LEN = 4; 21 | 22 | public static final int RESULT_OK = 0; 23 | 24 | public static final int RESULT_ERROR = 1; 25 | 26 | private Constants() { 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/sumup/codec/SumUpProtocolCodecFactory.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.sumup.codec; 2 | 3 | import org.apache.mina.filter.codec.demux.DemuxingProtocolCodecFactory; 4 | 5 | import com.waylau.mina.demo.sumup.message.AddMessage; 6 | import com.waylau.mina.demo.sumup.message.ResultMessage; 7 | 8 | public class SumUpProtocolCodecFactory extends DemuxingProtocolCodecFactory { 9 | public SumUpProtocolCodecFactory(boolean server) { 10 | if (server) { 11 | super.addMessageDecoder(AddMessageDecoder.class); 12 | super.addMessageEncoder(ResultMessage.class, 13 | ResultMessageEncoder.class); 14 | } else // Client 15 | { 16 | super.addMessageEncoder(AddMessage.class, AddMessageEncoder.class); 17 | super.addMessageDecoder(ResultMessageDecoder.class); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/sumup/message/ResultMessage.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.sumup.message; 2 | 3 | public class ResultMessage extends AbstractMessage { 4 | private static final long serialVersionUID = 7371210248110219946L; 5 | 6 | private boolean ok; 7 | 8 | private int value; 9 | 10 | public ResultMessage() { 11 | } 12 | 13 | public boolean isOk() { 14 | return ok; 15 | } 16 | 17 | public void setOk(boolean ok) { 18 | this.ok = ok; 19 | } 20 | 21 | public int getValue() { 22 | return value; 23 | } 24 | 25 | public void setValue(int value) { 26 | this.value = value; 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | if (ok) { 32 | return getSequence() + ":RESULT(" + value + ')'; 33 | } else { 34 | return getSequence() + ":RESULT(ERROR)"; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/sumup/codec/ResultMessageEncoder.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.sumup.codec; 2 | 3 | import org.apache.mina.core.buffer.IoBuffer; 4 | import org.apache.mina.core.session.IoSession; 5 | 6 | import com.waylau.mina.demo.sumup.message.ResultMessage; 7 | 8 | public class ResultMessageEncoder extends 9 | AbstractMessageEncoder { 10 | public ResultMessageEncoder() { 11 | super(Constants.RESULT); 12 | } 13 | 14 | @Override 15 | protected void encodeBody(IoSession session, T message, IoBuffer out) { 16 | if (message.isOk()) { 17 | out.putShort((short) Constants.RESULT_OK); 18 | out.putInt(message.getValue()); 19 | } else { 20 | out.putShort((short) Constants.RESULT_ERROR); 21 | } 22 | } 23 | 24 | public void dispose() throws Exception { 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/imagine/ImageRequest.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.imagine; 2 | 3 | /** 4 | * represents a client's request for an image 5 | * 6 | * @author waylau.com 7 | * @date 2015-2-26 8 | */ 9 | 10 | public class ImageRequest { 11 | 12 | private int width; 13 | private int height; 14 | private int numberOfCharacters; 15 | 16 | public ImageRequest(int width, int height, int numberOfCharacters) { 17 | this.width = width; 18 | this.height = height; 19 | this.numberOfCharacters = numberOfCharacters; 20 | } 21 | 22 | public int getWidth() { 23 | return width; 24 | } 25 | 26 | public int getHeight() { 27 | return height; 28 | } 29 | 30 | public int getNumberOfCharacters() { 31 | return numberOfCharacters; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/TcpClient.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina; 2 | 3 | import java.io.IOException; 4 | import java.io.OutputStream; 5 | import java.net.Socket; 6 | 7 | /** 8 | * 测试用的 TCP 客户端 9 | * 10 | * @author waylau.com 11 | * @date 2015-2-26 12 | */ 13 | public class TcpClient { 14 | 15 | public static void main(String[] args) throws IOException { 16 | Socket socket = null; 17 | OutputStream out = null; 18 | 19 | try { 20 | 21 | socket = new Socket("localhost", 8080); 22 | out = socket.getOutputStream(); 23 | 24 | // 请求服务器 25 | String lines = "床前明月光\r\n疑是地上霜\r\n举头望明月\r\n低头思故乡\r\n"; 26 | byte[] outputBytes = lines.getBytes("UTF-8"); 27 | out.write(outputBytes); 28 | out.flush(); 29 | 30 | } finally { 31 | // 关闭连接 32 | out.close(); 33 | socket.close(); 34 | } 35 | 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /mina2-demos/src/test/java/com/waylau/netty/AppTest.java: -------------------------------------------------------------------------------- 1 | package com.waylau.netty; 2 | 3 | import junit.framework.Test; 4 | import junit.framework.TestCase; 5 | import junit.framework.TestSuite; 6 | 7 | /** 8 | * Unit test for simple App. 9 | */ 10 | public class AppTest 11 | extends TestCase 12 | { 13 | /** 14 | * Create the test case 15 | * 16 | * @param testName name of the test case 17 | */ 18 | public AppTest( String testName ) 19 | { 20 | super( testName ); 21 | } 22 | 23 | /** 24 | * @return the suite of tests being tested 25 | */ 26 | public static Test suite() 27 | { 28 | return new TestSuite( AppTest.class ); 29 | } 30 | 31 | /** 32 | * Rigourous Test :-) 33 | */ 34 | public void testApp() 35 | { 36 | assertTrue( true ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/sumup/codec/AddMessageDecoder.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.sumup.codec; 2 | 3 | import org.apache.mina.core.buffer.IoBuffer; 4 | import org.apache.mina.core.session.IoSession; 5 | import org.apache.mina.filter.codec.ProtocolDecoderOutput; 6 | 7 | import com.waylau.mina.demo.sumup.message.AbstractMessage; 8 | import com.waylau.mina.demo.sumup.message.AddMessage; 9 | 10 | public class AddMessageDecoder extends AbstractMessageDecoder { 11 | 12 | public AddMessageDecoder() { 13 | super(Constants.ADD); 14 | } 15 | 16 | @Override 17 | protected AbstractMessage decodeBody(IoSession session, IoBuffer in) { 18 | if (in.remaining() < Constants.ADD_BODY_LEN) { 19 | return null; 20 | } 21 | 22 | AddMessage m = new AddMessage(); 23 | m.setValue(in.getInt()); 24 | return m; 25 | } 26 | 27 | public void finishDecode(IoSession session, ProtocolDecoderOutput out) 28 | throws Exception { 29 | } 30 | } -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/imagine/client/ImagePanel.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.imagine.client; 2 | 3 | import java.awt.Graphics; 4 | import java.awt.image.BufferedImage; 5 | 6 | import javax.swing.JPanel; 7 | 8 | /** 9 | * JPanel capable of drawing two {@link BufferedImage}'s 10 | * 11 | * @author waylau.com 12 | * @date 2015-2-26 13 | */ 14 | public class ImagePanel extends JPanel { 15 | 16 | private static final long serialVersionUID = 1L; 17 | 18 | private BufferedImage image1; 19 | private BufferedImage image2; 20 | 21 | @Override 22 | public void paintComponent(Graphics g) { 23 | super.paintComponent(g); 24 | if (image1 != null) { 25 | g.drawImage(image1, 20, 20, null); 26 | if (image2 != null) { 27 | g.drawImage(image2, 20, image1.getHeight() + 80, null); 28 | } 29 | } 30 | } 31 | 32 | public void setImages(BufferedImage image1, BufferedImage image2) { 33 | this.image1 = image1; 34 | this.image2 = image2; 35 | repaint(); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/chat/ChatCommand.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.chat; 2 | 3 | /** 4 | * Encapsulates a chat command. Use {@link #valueOf(String)} to create an 5 | * instance given a command string. 6 | * 7 | * @author waylau.com 8 | * @date 2015-4-6 9 | */ 10 | public class ChatCommand { 11 | public static final int LOGIN = 0; 12 | 13 | public static final int QUIT = 1; 14 | 15 | public static final int BROADCAST = 2; 16 | 17 | private final int num; 18 | 19 | private ChatCommand(int num) { 20 | this.num = num; 21 | } 22 | 23 | public int toInt() { 24 | return num; 25 | } 26 | 27 | public static ChatCommand valueOf(String s) { 28 | s = s.toUpperCase(); 29 | if ("LOGIN".equals(s)) { 30 | return new ChatCommand(LOGIN); 31 | } 32 | if ("QUIT".equals(s)) { 33 | return new ChatCommand(QUIT); 34 | } 35 | if ("BROADCAST".equals(s)) { 36 | return new ChatCommand(BROADCAST); 37 | } 38 | 39 | throw new IllegalArgumentException("Unrecognized command: " + s); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/imagine/codec/ImageRequestDecoder.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.imagine.codec; 2 | 3 | import org.apache.mina.core.buffer.IoBuffer; 4 | import org.apache.mina.core.session.IoSession; 5 | import org.apache.mina.filter.codec.CumulativeProtocolDecoder; 6 | import org.apache.mina.filter.codec.ProtocolDecoderOutput; 7 | 8 | import com.waylau.mina.demo.imagine.ImageRequest; 9 | 10 | /** 11 | * a decoder for {@link ImageRequest} objects 12 | * 13 | * @author waylau.com 14 | * @date 2015-2-26 15 | */ 16 | 17 | public class ImageRequestDecoder extends CumulativeProtocolDecoder { 18 | 19 | protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception { 20 | if (in.remaining() >= 12) { 21 | int width = in.getInt(); 22 | int height = in.getInt(); 23 | int numberOfCharachters = in.getInt(); 24 | ImageRequest request = new ImageRequest(width, height, numberOfCharachters); 25 | out.write(request); 26 | return true; 27 | } else { 28 | return false; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/time/TimeServerHandler.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.time; 2 | 3 | import java.util.Date; 4 | import org.apache.mina.core.service.IoHandlerAdapter; 5 | import org.apache.mina.core.session.IdleStatus; 6 | import org.apache.mina.core.session.IoSession; 7 | 8 | /** 9 | * 时间服务器 Handler 10 | * 11 | * @author waylau.com 12 | * @date 2015-4-5 13 | */ 14 | public class TimeServerHandler extends IoHandlerAdapter { 15 | @Override 16 | public void exceptionCaught(IoSession session, Throwable cause) 17 | throws Exception { 18 | cause.printStackTrace(); 19 | } 20 | 21 | @Override 22 | public void messageReceived(IoSession session, Object message) 23 | throws Exception { 24 | String str = message.toString(); 25 | if (str.trim().equalsIgnoreCase("quit")) { 26 | session.close(true); 27 | return; 28 | } 29 | Date date = new Date(); 30 | session.write(date.toString()); 31 | System.out.println("Message written..."); 32 | } 33 | 34 | @Override 35 | public void sessionIdle(IoSession session, IdleStatus status) 36 | throws Exception { 37 | System.out.println("IDLE " + session.getIdleCount(status)); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/imagine/codec/ImageRequestEncoder.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.imagine.codec; 2 | 3 | import org.apache.mina.core.buffer.IoBuffer; 4 | import org.apache.mina.core.session.IoSession; 5 | import org.apache.mina.filter.codec.ProtocolEncoder; 6 | import org.apache.mina.filter.codec.ProtocolEncoderOutput; 7 | 8 | import com.waylau.mina.demo.imagine.ImageRequest; 9 | 10 | /** 11 | * an encoder for {@link ImageRequest} objects 12 | * 13 | * @author waylau.com 14 | * @date 2015-2-26 15 | */ 16 | 17 | public class ImageRequestEncoder implements ProtocolEncoder { 18 | 19 | public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception { 20 | ImageRequest request = (ImageRequest) message; 21 | IoBuffer buffer = IoBuffer.allocate(12, false); 22 | buffer.putInt(request.getWidth()); 23 | buffer.putInt(request.getHeight()); 24 | buffer.putInt(request.getNumberOfCharacters()); 25 | buffer.flip(); 26 | out.write(buffer); 27 | } 28 | 29 | public void dispose(IoSession session) throws Exception { 30 | // nothing to dispose 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/sumup/codec/AbstractMessageEncoder.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.sumup.codec; 2 | 3 | import org.apache.mina.core.buffer.IoBuffer; 4 | import org.apache.mina.core.session.IoSession; 5 | import org.apache.mina.filter.codec.ProtocolEncoderOutput; 6 | import org.apache.mina.filter.codec.demux.MessageEncoder; 7 | 8 | import com.waylau.mina.demo.sumup.message.AbstractMessage; 9 | 10 | public abstract class AbstractMessageEncoder 11 | implements MessageEncoder { 12 | private final int type; 13 | 14 | protected AbstractMessageEncoder(int type) { 15 | this.type = type; 16 | } 17 | 18 | public void encode(IoSession session, T message, ProtocolEncoderOutput out) 19 | throws Exception { 20 | IoBuffer buf = IoBuffer.allocate(16); 21 | buf.setAutoExpand(true); // Enable auto-expand for easier encoding 22 | 23 | // Encode a header 24 | buf.putShort((short) type); 25 | buf.putInt(message.getSequence()); 26 | 27 | // Encode a body 28 | encodeBody(session, message, buf); 29 | buf.flip(); 30 | out.write(buf); 31 | } 32 | 33 | protected abstract void encodeBody(IoSession session, T message, 34 | IoBuffer out); 35 | } 36 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/chat/SpringMain.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.chat; 2 | 3 | import org.springframework.context.support.ClassPathXmlApplicationContext; 4 | import org.springframework.context.ConfigurableApplicationContext; 5 | 6 | /** 7 | * (Entry point) Chat server which uses Spring and the serverContext.xml 8 | * file to set up MINA and the server handler. 9 | * 10 | * @author waylau.com 11 | * @date 2015-4-6 12 | */ 13 | public class SpringMain { 14 | 15 | public static void main(String[] args) throws Exception { 16 | if (System.getProperty("com.sun.management.jmxremote") != null) { 17 | System.out.println("JMX enabled."); 18 | } else { 19 | System.out 20 | .println("JMX disabled. Please set the " 21 | + "'com.sun.management.jmxremote' system property to enable JMX."); 22 | } 23 | getApplicationContext(); 24 | System.out.println("Listening ..."); 25 | } 26 | 27 | public static ConfigurableApplicationContext getApplicationContext() { 28 | return new ClassPathXmlApplicationContext("com/waylau/mina/demo/chat/serverContext.xml"); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/imagine/codec/ImageCodecFactory.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.imagine.codec; 2 | 3 | import org.apache.mina.filter.codec.ProtocolCodecFactory; 4 | import org.apache.mina.filter.codec.ProtocolEncoder; 5 | import org.apache.mina.filter.codec.ProtocolDecoder; 6 | import org.apache.mina.core.session.IoSession; 7 | 8 | /** 9 | * a {@link ProtocolCodecFactory} for the tutorial on how to write a protocol codec 10 | * 11 | * @author waylau.com 12 | * @date 2015-2-26 13 | */ 14 | 15 | public class ImageCodecFactory implements ProtocolCodecFactory { 16 | private ProtocolEncoder encoder; 17 | private ProtocolDecoder decoder; 18 | 19 | public ImageCodecFactory(boolean client) { 20 | if (client) { 21 | encoder = new ImageRequestEncoder(); 22 | decoder = new ImageResponseDecoder(); 23 | } else { 24 | encoder = new ImageResponseEncoder(); 25 | decoder = new ImageRequestDecoder(); 26 | } 27 | } 28 | 29 | public ProtocolEncoder getEncoder(IoSession ioSession) throws Exception { 30 | return encoder; 31 | } 32 | 33 | public ProtocolDecoder getDecoder(IoSession ioSession) throws Exception { 34 | return decoder; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/udp/ClientPanel.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.udp; 2 | 3 | import java.awt.GridBagConstraints; 4 | import java.awt.GridBagLayout; 5 | import java.awt.Insets; 6 | 7 | import javax.swing.JLabel; 8 | import javax.swing.JPanel; 9 | import javax.swing.JTextField; 10 | import javax.swing.SwingUtilities; 11 | 12 | public class ClientPanel extends JPanel { 13 | private static final long serialVersionUID = 1L; 14 | 15 | private JTextField textField; 16 | 17 | public ClientPanel(String label) { 18 | super(); 19 | 20 | setPreferredSize(MemoryMonitor.PANEL_SIZE); 21 | 22 | setLayout(new GridBagLayout()); 23 | GridBagConstraints c = new GridBagConstraints(); 24 | 25 | c.insets = new Insets(5, 5, 5, 5); 26 | c.anchor = GridBagConstraints.CENTER; 27 | 28 | c.gridwidth = GridBagConstraints.REMAINDER; 29 | add(new JLabel(label), c); 30 | 31 | c.gridwidth = 1; 32 | add(new JLabel("Memory Used : ")); 33 | textField = new JTextField(10); 34 | textField.setEditable(false); 35 | add(textField, c); 36 | } 37 | 38 | public void updateTextField(final long val) { 39 | System.out.println("New value for textfield - " + val); 40 | SwingUtilities.invokeLater(new Runnable() { 41 | public void run() { 42 | textField.setText(String.valueOf(val)); 43 | } 44 | }); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/time/MinaTimeServer.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.time; 2 | 3 | import java.net.InetSocketAddress; 4 | import java.nio.charset.Charset; 5 | 6 | import org.apache.mina.core.service.IoAcceptor; 7 | import org.apache.mina.core.session.IdleStatus; 8 | import org.apache.mina.filter.codec.ProtocolCodecFilter; 9 | import org.apache.mina.filter.codec.textline.TextLineCodecFactory; 10 | import org.apache.mina.filter.logging.LoggingFilter; 11 | import org.apache.mina.transport.socket.nio.NioSocketAcceptor; 12 | 13 | /** 14 | * 时间服务器 15 | * 16 | * @author waylau.com 17 | * @date 2015-4-5 18 | */ 19 | public class MinaTimeServer { 20 | 21 | public static void main(String[] args) throws Exception { 22 | int port; 23 | if (args.length > 0) { 24 | port = Integer.parseInt(args[0]); 25 | } else { 26 | port = 8080; 27 | } 28 | 29 | IoAcceptor acceptor = new NioSocketAcceptor(); 30 | acceptor.getFilterChain().addLast("logger", new LoggingFilter()); 31 | acceptor.getFilterChain().addLast( 32 | "codec", 33 | new ProtocolCodecFilter(new TextLineCodecFactory(Charset 34 | .forName("UTF-8")))); 35 | acceptor.setHandler(new TimeServerHandler()); 36 | acceptor.getSessionConfig().setReadBufferSize(2048); 37 | acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10); 38 | acceptor.bind(new InetSocketAddress(port)); 39 | 40 | } 41 | } -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/sumup/codec/ResultMessageDecoder.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.sumup.codec; 2 | 3 | import org.apache.mina.core.buffer.IoBuffer; 4 | import org.apache.mina.core.session.IoSession; 5 | import org.apache.mina.filter.codec.ProtocolDecoderOutput; 6 | 7 | import com.waylau.mina.demo.sumup.message.AbstractMessage; 8 | import com.waylau.mina.demo.sumup.message.ResultMessage; 9 | 10 | public class ResultMessageDecoder extends AbstractMessageDecoder { 11 | private int code; 12 | 13 | private boolean readCode; 14 | 15 | public ResultMessageDecoder() { 16 | super(Constants.RESULT); 17 | } 18 | 19 | @Override 20 | protected AbstractMessage decodeBody(IoSession session, IoBuffer in) { 21 | if (!readCode) { 22 | if (in.remaining() < Constants.RESULT_CODE_LEN) { 23 | return null; // Need more data. 24 | } 25 | 26 | code = in.getShort(); 27 | readCode = true; 28 | } 29 | 30 | if (code == Constants.RESULT_OK) { 31 | if (in.remaining() < Constants.RESULT_VALUE_LEN) { 32 | return null; 33 | } 34 | 35 | ResultMessage m = new ResultMessage(); 36 | m.setOk(true); 37 | m.setValue(in.getInt()); 38 | readCode = false; 39 | return m; 40 | } else { 41 | ResultMessage m = new ResultMessage(); 42 | m.setOk(false); 43 | readCode = false; 44 | return m; 45 | } 46 | } 47 | 48 | public void finishDecode(IoSession session, ProtocolDecoderOutput out) 49 | throws Exception { 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/simplechat/SimpleChatServer.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.simplechat; 2 | 3 | import java.io.IOException; 4 | import java.net.InetSocketAddress; 5 | import java.nio.charset.Charset; 6 | 7 | import org.apache.mina.core.session.IdleStatus; 8 | import org.apache.mina.filter.codec.ProtocolCodecFilter; 9 | import org.apache.mina.filter.codec.textline.TextLineCodecFactory; 10 | import org.apache.mina.transport.socket.SocketAcceptor; 11 | import org.apache.mina.transport.socket.nio.NioSocketAcceptor; 12 | 13 | 14 | /** 15 | * 说明:简单聊天室 服务器 16 | * 17 | * @author waylau.com 2015年4月10日 18 | */ 19 | public class SimpleChatServer { 20 | 21 | public static void main(String[] args) { 22 | int port; 23 | if (args.length > 0) { 24 | port = Integer.parseInt(args[0]); 25 | } else { 26 | port = 8080; 27 | } 28 | 29 | SocketAcceptor acceptor = new NioSocketAcceptor(); // (1) 30 | 31 | acceptor.getFilterChain().addLast( "codec", 32 | new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" )))); // (2) 33 | acceptor.setHandler(new SimpleChatServerHandler()); // (3) 34 | 35 | acceptor.getSessionConfig().setReadBufferSize(2048); // (4) 36 | acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 100);// (5) 37 | 38 | try { 39 | acceptor.bind(new InetSocketAddress(port)); // (6) 40 | } catch (IOException e) { 41 | e.printStackTrace(); 42 | } 43 | System.out.println("[Server]Listening on port " + port); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /mina2-demos/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | ############################################################################# 2 | # Licensed to the Apache Software Foundation (ASF) under one or more 3 | # contributor license agreements. See the NOTICE file distributed with 4 | # this work for additional information regarding copyright ownership. 5 | # The ASF licenses this file to You under the Apache License, Version 2.0 6 | # (the "License"); you may not use this file except in compliance with 7 | # the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | ############################################################################# 17 | # Please don't modify the log level until we reach to acceptable test coverage. 18 | # It's very useful when I test examples manually. 19 | log4j.rootCategory=INFO, stdout 20 | 21 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 22 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 23 | log4j.appender.stdout.layout.ConversionPattern=[%d{HH:mm:ss}] %p [%c] - %m%n 24 | 25 | # you could use this pattern to test the MDC with the Chat server 26 | #log4j.appender.stdout.layout.ConversionPattern=[%d{HH:mm:ss}] %t %p %X{name} [%X{user}] [%X{remoteIp}:%X{remotePort}] [%c] - %m%n 27 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/imagine/codec/ImageResponseEncoder.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.imagine.codec; 2 | 3 | import org.apache.mina.filter.codec.ProtocolEncoderOutput; 4 | import org.apache.mina.filter.codec.ProtocolEncoderAdapter; 5 | import org.apache.mina.core.buffer.IoBuffer; 6 | import org.apache.mina.core.session.IoSession; 7 | 8 | import com.waylau.mina.demo.imagine.ImageResponse; 9 | 10 | import javax.imageio.ImageIO; 11 | 12 | import java.awt.image.BufferedImage; 13 | import java.io.ByteArrayOutputStream; 14 | import java.io.IOException; 15 | 16 | /** 17 | * an encoder for {@link ImageResponse} objects 18 | * 19 | * @author waylau.com 20 | * @date 2015-2-26 21 | */ 22 | public class ImageResponseEncoder extends ProtocolEncoderAdapter { 23 | 24 | public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception { 25 | ImageResponse imageResponse = (ImageResponse) message; 26 | byte[] bytes1 = getBytes(imageResponse.getImage1()); 27 | byte[] bytes2 = getBytes(imageResponse.getImage2()); 28 | int capacity = bytes1.length + bytes2.length + 8; 29 | IoBuffer buffer = IoBuffer.allocate(capacity, false); 30 | buffer.putInt(bytes1.length); 31 | buffer.put(bytes1); 32 | buffer.putInt(bytes2.length); 33 | buffer.put(bytes2); 34 | buffer.flip(); 35 | out.write(buffer); 36 | } 37 | 38 | private byte[] getBytes(BufferedImage image) throws IOException { 39 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); 40 | ImageIO.write(image, "PNG", baos); 41 | return baos.toByteArray(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/simplechat/SimpleChatClient.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.simplechat; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.InputStreamReader; 6 | import java.net.InetSocketAddress; 7 | import java.nio.charset.Charset; 8 | 9 | import org.apache.mina.core.future.ConnectFuture; 10 | import org.apache.mina.core.session.IoSession; 11 | import org.apache.mina.filter.codec.ProtocolCodecFilter; 12 | import org.apache.mina.filter.codec.textline.TextLineCodecFactory; 13 | import org.apache.mina.transport.socket.nio.NioSocketConnector; 14 | 15 | 16 | /** 17 | * 说明:简单聊天室 客户端 18 | * 19 | * @author waylau.com 2015年4月10日 20 | */ 21 | public class SimpleChatClient { 22 | private static final long CONNECT_TIMEOUT = 30 * 1000L; // 30 秒; 23 | private static final String HOSTNAME = "127.0.0.1"; 24 | private static final int PORT = 8080; 25 | /** 26 | * @param args 27 | */ 28 | public static void main(String[] args) { 29 | 30 | NioSocketConnector connector = new NioSocketConnector(); // (1) 31 | connector.setConnectTimeoutMillis(CONNECT_TIMEOUT); 32 | connector.getFilterChain().addLast( "codec", 33 | new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" )))); 34 | connector.setHandler(new SimpleChatClientHandler()); 35 | IoSession session; 36 | ConnectFuture future = connector.connect(new InetSocketAddress( 37 | HOSTNAME, PORT)); // (2) 38 | future.awaitUninterruptibly(); 39 | session = future.getSession(); 40 | 41 | while(true){ 42 | try { 43 | BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); 44 | session.write(in.readLine()); 45 | } catch (IOException e) { 46 | e.printStackTrace(); 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/sumup/Server.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.sumup; 2 | 3 | import java.net.InetSocketAddress; 4 | 5 | import org.apache.mina.filter.codec.ProtocolCodecFilter; 6 | import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory; 7 | import org.apache.mina.filter.logging.LoggingFilter; 8 | import org.apache.mina.transport.socket.nio.NioSocketAcceptor; 9 | 10 | import com.waylau.mina.demo.sumup.codec.SumUpProtocolCodecFactory; 11 | 12 | /** 13 | * (Entry Point) Starts SumUp server. 14 | * 15 | * @author waylau.com 16 | * @date 2015-4-6 17 | */ 18 | public class Server { 19 | private static final int SERVER_PORT = 8080; 20 | 21 | // Set this to false to use object serialization instead of custom codec. 22 | private static final boolean USE_CUSTOM_CODEC = true; 23 | 24 | public static void main(String[] args) throws Throwable { 25 | NioSocketAcceptor acceptor = new NioSocketAcceptor(); 26 | 27 | // Prepare the service configuration. 28 | if (USE_CUSTOM_CODEC) { 29 | acceptor.getFilterChain() 30 | .addLast( 31 | "codec", 32 | new ProtocolCodecFilter( 33 | new SumUpProtocolCodecFactory(true))); 34 | } else { 35 | acceptor.getFilterChain().addLast( 36 | "codec", 37 | new ProtocolCodecFilter( 38 | new ObjectSerializationCodecFactory())); 39 | } 40 | acceptor.getFilterChain().addLast("logger", new LoggingFilter()); 41 | 42 | acceptor.setHandler(new ServerSessionHandler()); 43 | acceptor.bind(new InetSocketAddress(SERVER_PORT)); 44 | 45 | System.out.println("Listening on port " + SERVER_PORT); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/echoserver/ssl/BogusTrustManagerFactory.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.echoserver.ssl; 2 | 3 | import java.security.InvalidAlgorithmParameterException; 4 | import java.security.KeyStore; 5 | import java.security.KeyStoreException; 6 | import java.security.cert.CertificateException; 7 | import java.security.cert.X509Certificate; 8 | 9 | import javax.net.ssl.ManagerFactoryParameters; 10 | import javax.net.ssl.TrustManager; 11 | import javax.net.ssl.TrustManagerFactorySpi; 12 | import javax.net.ssl.X509TrustManager; 13 | 14 | /** 15 | * Bogus trust manager factory. Creates BogusX509TrustManager 16 | * 17 | * @author waylau.com 18 | * @date 2015-4-6 19 | */ 20 | class BogusTrustManagerFactory extends TrustManagerFactorySpi { 21 | 22 | static final X509TrustManager X509 = new X509TrustManager() { 23 | public void checkClientTrusted(X509Certificate[] x509Certificates, 24 | String s) throws CertificateException { 25 | } 26 | 27 | public void checkServerTrusted(X509Certificate[] x509Certificates, 28 | String s) throws CertificateException { 29 | } 30 | 31 | public X509Certificate[] getAcceptedIssuers() { 32 | return new X509Certificate[0]; 33 | } 34 | }; 35 | 36 | static final TrustManager[] X509_MANAGERS = new TrustManager[] { X509 }; 37 | 38 | public BogusTrustManagerFactory() { 39 | } 40 | 41 | @Override 42 | protected TrustManager[] engineGetTrustManagers() { 43 | return X509_MANAGERS; 44 | } 45 | 46 | @Override 47 | protected void engineInit(KeyStore keystore) throws KeyStoreException { 48 | // noop 49 | } 50 | 51 | @Override 52 | protected void engineInit(ManagerFactoryParameters managerFactoryParameters) 53 | throws InvalidAlgorithmParameterException { 54 | // noop 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/udp/MemoryMonitorHandler.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.udp; 2 | 3 | import java.net.SocketAddress; 4 | 5 | import org.apache.mina.core.buffer.IoBuffer; 6 | import org.apache.mina.core.service.IoHandlerAdapter; 7 | import org.apache.mina.core.session.IdleStatus; 8 | import org.apache.mina.core.session.IoSession; 9 | 10 | public class MemoryMonitorHandler extends IoHandlerAdapter { 11 | private MemoryMonitor server; 12 | 13 | public MemoryMonitorHandler(MemoryMonitor server) { 14 | this.server = server; 15 | } 16 | 17 | @Override 18 | public void exceptionCaught(IoSession session, Throwable cause) 19 | throws Exception { 20 | cause.printStackTrace(); 21 | session.close(true); 22 | } 23 | 24 | @Override 25 | public void messageReceived(IoSession session, Object message) 26 | throws Exception { 27 | 28 | if (message instanceof IoBuffer) { 29 | IoBuffer buffer = (IoBuffer) message; 30 | SocketAddress remoteAddress = session.getRemoteAddress(); 31 | server.recvUpdate(remoteAddress, buffer.getLong()); 32 | } 33 | } 34 | 35 | @Override 36 | public void sessionClosed(IoSession session) throws Exception { 37 | System.out.println("Session closed..."); 38 | SocketAddress remoteAddress = session.getRemoteAddress(); 39 | server.removeClient(remoteAddress); 40 | } 41 | 42 | @Override 43 | public void sessionCreated(IoSession session) throws Exception { 44 | 45 | System.out.println("Session created..."); 46 | 47 | SocketAddress remoteAddress = session.getRemoteAddress(); 48 | server.addClient(remoteAddress); 49 | } 50 | 51 | @Override 52 | public void sessionIdle(IoSession session, IdleStatus status) 53 | throws Exception { 54 | System.out.println("Session idle..."); 55 | } 56 | 57 | @Override 58 | public void sessionOpened(IoSession session) throws Exception { 59 | System.out.println("Session Opened..."); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/echoserver/EchoProtocolHandler.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.echoserver; 2 | 3 | import org.apache.mina.core.buffer.IoBuffer; 4 | import org.apache.mina.core.service.IoHandler; 5 | import org.apache.mina.core.service.IoHandlerAdapter; 6 | import org.apache.mina.core.session.IdleStatus; 7 | import org.apache.mina.core.session.IoSession; 8 | import org.apache.mina.filter.ssl.SslFilter; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | 12 | /** 13 | * {@link IoHandler} implementation for echo server. 14 | * 15 | * @author waylau.com 16 | * @date 2015-4-6 17 | */ 18 | public class EchoProtocolHandler extends IoHandlerAdapter { 19 | private final static Logger LOGGER = LoggerFactory.getLogger(EchoProtocolHandler.class); 20 | 21 | @Override 22 | public void sessionCreated(IoSession session) { 23 | session.getConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10); 24 | 25 | // We're going to use SSL negotiation notification. 26 | session.setAttribute(SslFilter.USE_NOTIFICATION); 27 | } 28 | 29 | @Override 30 | public void sessionClosed(IoSession session) throws Exception { 31 | LOGGER.info("CLOSED"); 32 | } 33 | 34 | @Override 35 | public void sessionOpened(IoSession session) throws Exception { 36 | LOGGER.info("OPENED"); 37 | } 38 | 39 | @Override 40 | public void sessionIdle(IoSession session, IdleStatus status) { 41 | LOGGER.info("*** IDLE #" + session.getIdleCount(IdleStatus.BOTH_IDLE) + " ***"); 42 | } 43 | 44 | @Override 45 | public void exceptionCaught(IoSession session, Throwable cause) { 46 | session.close(true); 47 | } 48 | 49 | @Override 50 | public void messageReceived(IoSession session, Object message) 51 | throws Exception { 52 | LOGGER.info( "Received : " + message ); 53 | // Write the received data back to remote peer 54 | session.write(((IoBuffer) message).duplicate()); 55 | } 56 | } -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/echoserver/Main.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.echoserver; 2 | 3 | import java.net.InetSocketAddress; 4 | 5 | import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder; 6 | import org.apache.mina.filter.ssl.SslFilter; 7 | import org.apache.mina.transport.socket.SocketAcceptor; 8 | import org.apache.mina.transport.socket.nio.NioSocketAcceptor; 9 | 10 | import com.waylau.mina.demo.echoserver.ssl.BogusSslContextFactory; 11 | 12 | /** 13 | * (Entry point) Echo server 14 | * 15 | * @author waylau.com 16 | * @date 2015-4-6 17 | */ 18 | public class Main { 19 | /** Choose your favorite port number. */ 20 | private static final int PORT = 8080; 21 | 22 | /** Set this to true if you want to make the server SSL */ 23 | private static final boolean USE_SSL = false; 24 | 25 | public static void main(String[] args) throws Exception { 26 | SocketAcceptor acceptor = new NioSocketAcceptor(); 27 | acceptor.setReuseAddress( true ); 28 | DefaultIoFilterChainBuilder chain = acceptor.getFilterChain(); 29 | 30 | // Add SSL filter if SSL is enabled. 31 | if (USE_SSL) { 32 | addSSLSupport(chain); 33 | } 34 | 35 | // Bind 36 | acceptor.setHandler(new EchoProtocolHandler()); 37 | acceptor.bind(new InetSocketAddress(PORT)); 38 | 39 | System.out.println("Listening on port " + PORT); 40 | 41 | for (;;) { 42 | System.out.println("R: " + acceptor.getStatistics().getReadBytesThroughput() + 43 | ", W: " + acceptor.getStatistics().getWrittenBytesThroughput()); 44 | Thread.sleep(3000); 45 | } 46 | } 47 | 48 | private static void addSSLSupport(DefaultIoFilterChainBuilder chain) 49 | throws Exception { 50 | SslFilter sslFilter = new SslFilter(BogusSslContextFactory 51 | .getInstance(true)); 52 | chain.addLast("sslFilter", sslFilter); 53 | System.out.println("SSL ON"); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/sumup/codec/AbstractMessageDecoder.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.sumup.codec; 2 | 3 | import org.apache.mina.core.buffer.IoBuffer; 4 | import org.apache.mina.core.session.IoSession; 5 | import org.apache.mina.filter.codec.ProtocolDecoderOutput; 6 | import org.apache.mina.filter.codec.demux.MessageDecoder; 7 | import org.apache.mina.filter.codec.demux.MessageDecoderResult; 8 | 9 | import com.waylau.mina.demo.sumup.message.AbstractMessage; 10 | 11 | public abstract class AbstractMessageDecoder implements MessageDecoder { 12 | private final int type; 13 | 14 | private int sequence; 15 | 16 | private boolean readHeader; 17 | 18 | protected AbstractMessageDecoder(int type) { 19 | this.type = type; 20 | } 21 | 22 | public MessageDecoderResult decodable(IoSession session, IoBuffer in) { 23 | // Return NEED_DATA if the whole header is not read yet. 24 | if (in.remaining() < Constants.HEADER_LEN) { 25 | return MessageDecoderResult.NEED_DATA; 26 | } 27 | 28 | // Return OK if type and bodyLength matches. 29 | if (type == in.getShort()) { 30 | return MessageDecoderResult.OK; 31 | } 32 | 33 | // Return NOT_OK if not matches. 34 | return MessageDecoderResult.NOT_OK; 35 | } 36 | 37 | public MessageDecoderResult decode(IoSession session, IoBuffer in, 38 | ProtocolDecoderOutput out) throws Exception { 39 | // Try to skip header if not read. 40 | if (!readHeader) { 41 | in.getShort(); // Skip 'type'. 42 | sequence = in.getInt(); // Get 'sequence'. 43 | readHeader = true; 44 | } 45 | 46 | // Try to decode body 47 | AbstractMessage m = decodeBody(session, in); 48 | // Return NEED_DATA if the body is not fully read. 49 | if (m == null) { 50 | return MessageDecoderResult.NEED_DATA; 51 | } else { 52 | readHeader = false; // reset readHeader for the next decode 53 | } 54 | m.setSequence(sequence); 55 | out.write(m); 56 | 57 | return MessageDecoderResult.OK; 58 | } 59 | 60 | /** 61 | * @return null if the whole body is not read yet 62 | */ 63 | protected abstract AbstractMessage decodeBody(IoSession session, IoBuffer in); 64 | } -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/sumup/ClientSessionHandler.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.sumup; 2 | 3 | import org.apache.mina.core.service.IoHandler; 4 | import org.apache.mina.core.service.IoHandlerAdapter; 5 | import org.apache.mina.core.session.IoSession; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import com.waylau.mina.demo.sumup.message.AddMessage; 10 | import com.waylau.mina.demo.sumup.message.ResultMessage; 11 | 12 | /** 13 | * {@link IoHandler} for SumUp client. 14 | * 15 | * @author waylau.com 16 | * @date 2015-4-6 17 | */ 18 | public class ClientSessionHandler extends IoHandlerAdapter { 19 | 20 | private final static Logger LOGGER = LoggerFactory 21 | .getLogger(ClientSessionHandler.class); 22 | 23 | private final int[] values; 24 | 25 | private boolean finished; 26 | 27 | public ClientSessionHandler(int[] values) { 28 | this.values = values; 29 | } 30 | 31 | public boolean isFinished() { 32 | return finished; 33 | } 34 | 35 | @Override 36 | public void sessionOpened(IoSession session) { 37 | // send summation requests 38 | for (int i = 0; i < values.length; i++) { 39 | AddMessage m = new AddMessage(); 40 | m.setSequence(i); 41 | m.setValue(values[i]); 42 | session.write(m); 43 | } 44 | } 45 | 46 | @Override 47 | public void messageReceived(IoSession session, Object message) { 48 | // server only sends ResultMessage. otherwise, we will have to identify 49 | // its type using instanceof operator. 50 | ResultMessage rm = (ResultMessage) message; 51 | if (rm.isOk()) { 52 | // server returned OK code. 53 | // if received the result message which has the last sequence 54 | // number, 55 | // it is time to disconnect. 56 | if (rm.getSequence() == values.length - 1) { 57 | // print the sum and disconnect. 58 | LOGGER.info("The sum: " + rm.getValue()); 59 | session.close(true); 60 | finished = true; 61 | } 62 | } else { 63 | // seever returned error code because of overflow, etc. 64 | LOGGER.warn("Server error, disconnecting..."); 65 | session.close(true); 66 | finished = true; 67 | } 68 | } 69 | 70 | @Override 71 | public void exceptionCaught(IoSession session, Throwable cause) { 72 | session.close(true); 73 | } 74 | } -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/simplechat/SimpleChatServerHandler.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.simplechat; 2 | 3 | import java.util.Collections; 4 | import java.util.HashSet; 5 | import java.util.Set; 6 | 7 | import org.apache.mina.core.service.IoHandlerAdapter; 8 | import org.apache.mina.core.session.IdleStatus; 9 | import org.apache.mina.core.session.IoSession; 10 | 11 | /** 12 | * 说明:简单聊天室 服务器 处理器 13 | * 14 | * @author waylau.com 2015年4月10日 15 | */ 16 | public class SimpleChatServerHandler extends IoHandlerAdapter { // (1) 17 | 18 | private final Set sessions = Collections 19 | .synchronizedSet(new HashSet()); // (2) 20 | 21 | @Override 22 | public void sessionCreated(IoSession session) throws Exception {// (3) 23 | sessions.add(session); 24 | broadcast(" has join the chat", session); 25 | } 26 | 27 | @Override 28 | public void sessionClosed(IoSession session) throws Exception {// (4) 29 | sessions.remove(session); 30 | broadcast(" has left the chat", session); 31 | } 32 | 33 | @Override 34 | public void messageReceived(IoSession session, Object message) 35 | throws Exception {// (5) 36 | String str = message.toString(); 37 | broadcast(str, session); 38 | } 39 | 40 | @Override 41 | public void sessionIdle(IoSession session, IdleStatus status) 42 | throws Exception {// (6) 43 | System.out.println("[Server] IDLE " + session.getRemoteAddress() 44 | + session.getIdleCount(status)); 45 | } 46 | 47 | @Override 48 | public void exceptionCaught(IoSession session, Throwable cause) { 49 | cause.printStackTrace();// (7) 50 | System.out.println("[Server] Client:" + session.getRemoteAddress() 51 | + "异常"); 52 | // 遇到未捕获的异常,则关闭连接 53 | session.close(true); 54 | } 55 | 56 | /** 57 | * 广播消息 58 | * 59 | * @param message 60 | */ 61 | private void broadcast(String message, IoSession exceptSession) {// (8) 62 | synchronized (sessions) { 63 | for (IoSession session : sessions) { 64 | if (session.isConnected()) { 65 | if (session.equals(exceptSession)) { 66 | session.write("[You]" + message); 67 | } else { 68 | session.write("[Client" + session.getRemoteAddress() 69 | + "] " + message); 70 | } 71 | 72 | } 73 | } 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/chat/client/SwingChatClientHandler.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.chat.client; 2 | 3 | import org.apache.mina.core.service.IoHandler; 4 | import org.apache.mina.core.service.IoHandlerAdapter; 5 | import org.apache.mina.core.session.IoSession; 6 | 7 | import com.waylau.mina.demo.chat.ChatCommand; 8 | 9 | /** 10 | * {@link IoHandler} implementation of the client side of the simple chat protocol. 11 | * 12 | * @author waylau.com 13 | * @date 2015-4-6 14 | */ 15 | public class SwingChatClientHandler extends IoHandlerAdapter { 16 | 17 | public interface Callback { 18 | void connected(); 19 | 20 | void loggedIn(); 21 | 22 | void loggedOut(); 23 | 24 | void disconnected(); 25 | 26 | void messageReceived(String message); 27 | 28 | void error(String message); 29 | } 30 | 31 | private final Callback callback; 32 | 33 | public SwingChatClientHandler(Callback callback) { 34 | this.callback = callback; 35 | } 36 | 37 | @Override 38 | public void sessionOpened(IoSession session) throws Exception { 39 | callback.connected(); 40 | } 41 | 42 | @Override 43 | public void messageReceived(IoSession session, Object message) 44 | throws Exception { 45 | String theMessage = (String) message; 46 | String[] result = theMessage.split(" ", 3); 47 | String status = result[1]; 48 | String theCommand = result[0]; 49 | ChatCommand command = ChatCommand.valueOf(theCommand); 50 | 51 | if ("OK".equals(status)) { 52 | 53 | switch (command.toInt()) { 54 | 55 | case ChatCommand.BROADCAST: 56 | if (result.length == 3) { 57 | callback.messageReceived(result[2]); 58 | } 59 | break; 60 | case ChatCommand.LOGIN: 61 | callback.loggedIn(); 62 | break; 63 | 64 | case ChatCommand.QUIT: 65 | callback.loggedOut(); 66 | break; 67 | } 68 | 69 | } else { 70 | if (result.length == 3) { 71 | callback.error(result[2]); 72 | } 73 | } 74 | } 75 | 76 | @Override 77 | public void sessionClosed(IoSession session) throws Exception { 78 | callback.disconnected(); 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/chat/Main.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.chat; 2 | 3 | import java.net.InetSocketAddress; 4 | 5 | import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder; 6 | import org.apache.mina.filter.codec.ProtocolCodecFilter; 7 | import org.apache.mina.filter.codec.textline.TextLineCodecFactory; 8 | import org.apache.mina.filter.logging.LoggingFilter; 9 | import org.apache.mina.filter.logging.MdcInjectionFilter; 10 | import org.apache.mina.filter.ssl.SslFilter; 11 | import org.apache.mina.transport.socket.nio.NioSocketAcceptor; 12 | 13 | import com.waylau.mina.demo.echoserver.ssl.BogusSslContextFactory; 14 | 15 | /** 16 | * (Entry point) Chat server 17 | * 18 | * @author waylau.com 19 | * @date 2015-4-6 20 | */ 21 | public class Main { 22 | /** Choose your favorite port number. */ 23 | private static final int PORT = 1234; 24 | 25 | /** Set this to true if you want to make the server SSL */ 26 | private static final boolean USE_SSL = false; 27 | 28 | public static void main(String[] args) throws Exception { 29 | NioSocketAcceptor acceptor = new NioSocketAcceptor(); 30 | DefaultIoFilterChainBuilder chain = acceptor.getFilterChain(); 31 | 32 | MdcInjectionFilter mdcInjectionFilter = new MdcInjectionFilter(); 33 | chain.addLast("mdc", mdcInjectionFilter); 34 | 35 | // Add SSL filter if SSL is enabled. 36 | if (USE_SSL) { 37 | addSSLSupport(chain); 38 | } 39 | 40 | chain.addLast("codec", new ProtocolCodecFilter( 41 | new TextLineCodecFactory())); 42 | 43 | addLogger(chain); 44 | 45 | // Bind 46 | acceptor.setHandler(new ChatProtocolHandler()); 47 | acceptor.bind(new InetSocketAddress(PORT)); 48 | 49 | System.out.println("Listening on port " + PORT); 50 | } 51 | 52 | private static void addSSLSupport(DefaultIoFilterChainBuilder chain) 53 | throws Exception { 54 | SslFilter sslFilter = new SslFilter(BogusSslContextFactory 55 | .getInstance(true)); 56 | chain.addLast("sslFilter", sslFilter); 57 | System.out.println("SSL ON"); 58 | } 59 | 60 | private static void addLogger(DefaultIoFilterChainBuilder chain) 61 | throws Exception { 62 | chain.addLast("logger", new LoggingFilter()); 63 | System.out.println("Logging ON"); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/echoserver/ssl/SslServerSocketFactory.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.echoserver.ssl; 2 | 3 | import java.io.IOException; 4 | import java.net.InetAddress; 5 | import java.net.ServerSocket; 6 | import java.security.GeneralSecurityException; 7 | 8 | import javax.net.ServerSocketFactory; 9 | 10 | /** 11 | * Simple Server Socket factory to create sockets with or without SSL enabled. 12 | * If SSL enabled a "bougus" SSL Context is used (suitable for test purposes) 13 | * 14 | * @author waylau.com 15 | * @date 2015-4-6 16 | */ 17 | public class SslServerSocketFactory extends javax.net.ServerSocketFactory { 18 | private static boolean sslEnabled = false; 19 | 20 | private static javax.net.ServerSocketFactory sslFactory = null; 21 | 22 | private static ServerSocketFactory factory = null; 23 | 24 | public SslServerSocketFactory() { 25 | super(); 26 | } 27 | 28 | @Override 29 | public ServerSocket createServerSocket(int port) throws IOException { 30 | return new ServerSocket(port); 31 | } 32 | 33 | @Override 34 | public ServerSocket createServerSocket(int port, int backlog) 35 | throws IOException { 36 | return new ServerSocket(port, backlog); 37 | } 38 | 39 | @Override 40 | public ServerSocket createServerSocket(int port, int backlog, 41 | InetAddress ifAddress) throws IOException { 42 | return new ServerSocket(port, backlog, ifAddress); 43 | } 44 | 45 | public static javax.net.ServerSocketFactory getServerSocketFactory() 46 | throws IOException { 47 | if (isSslEnabled()) { 48 | if (sslFactory == null) { 49 | try { 50 | sslFactory = BogusSslContextFactory.getInstance(true) 51 | .getServerSocketFactory(); 52 | } catch (GeneralSecurityException e) { 53 | IOException ioe = new IOException( 54 | "could not create SSL socket"); 55 | ioe.initCause(e); 56 | throw ioe; 57 | } 58 | } 59 | return sslFactory; 60 | } else { 61 | if (factory == null) { 62 | factory = new SslServerSocketFactory(); 63 | } 64 | return factory; 65 | } 66 | 67 | } 68 | 69 | public static boolean isSslEnabled() { 70 | return sslEnabled; 71 | } 72 | 73 | public static void setSslEnabled(boolean newSslEnabled) { 74 | sslEnabled = newSslEnabled; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/sumup/Client.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.sumup; 2 | 3 | import java.net.InetSocketAddress; 4 | 5 | import org.apache.mina.core.RuntimeIoException; 6 | import org.apache.mina.core.future.ConnectFuture; 7 | import org.apache.mina.core.session.IoSession; 8 | import org.apache.mina.filter.codec.ProtocolCodecFilter; 9 | import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory; 10 | import org.apache.mina.filter.logging.LoggingFilter; 11 | import org.apache.mina.transport.socket.nio.NioSocketConnector; 12 | 13 | import com.waylau.mina.demo.sumup.codec.SumUpProtocolCodecFactory; 14 | 15 | /** 16 | * (Entry Point) Starts SumUp client. 17 | * 18 | * @author waylau.com 19 | * @date 2015-4-6 20 | */ 21 | public class Client { 22 | 23 | private static final long CONNECT_TIMEOUT = 30 * 1000L; // 30 秒; 24 | 25 | // 当是 false 时,来使用对象序列化来代替自定义编解码器 26 | private static final boolean USE_CUSTOM_CODEC = true; 27 | 28 | private static final String HOSTNAME = "localhost"; 29 | 30 | private static final int PORT = 8080; 31 | 32 | public static void main(String[] args) throws Throwable { 33 | if (args.length == 0) { 34 | System.out.println("Please specify the list of any integers"); 35 | return; 36 | } 37 | 38 | // prepare values to sum up 39 | int[] values = new int[args.length]; 40 | for (int i = 0; i < args.length; i++) { 41 | values[i] = Integer.parseInt(args[i]); 42 | } 43 | 44 | NioSocketConnector connector = new NioSocketConnector(); 45 | connector.setConnectTimeoutMillis(CONNECT_TIMEOUT); 46 | 47 | if (USE_CUSTOM_CODEC) { 48 | connector.getFilterChain().addLast( 49 | "codec", 50 | new ProtocolCodecFilter( 51 | new SumUpProtocolCodecFactory(false))); 52 | } else { 53 | connector.getFilterChain().addLast( 54 | "codec", 55 | new ProtocolCodecFilter( 56 | new ObjectSerializationCodecFactory())); 57 | } 58 | 59 | connector.getFilterChain().addLast("logger", new LoggingFilter()); 60 | connector.setHandler(new ClientSessionHandler(values)); 61 | IoSession session; 62 | 63 | for (;;) { 64 | try { 65 | ConnectFuture future = connector.connect(new InetSocketAddress( 66 | HOSTNAME, PORT)); 67 | future.awaitUninterruptibly(); 68 | session = future.getSession(); 69 | break; 70 | } catch (RuntimeIoException e) { 71 | System.err.println("Failed to connect."); 72 | e.printStackTrace(); 73 | Thread.sleep(5000); 74 | } 75 | } 76 | 77 | // wait until the summation is done 78 | session.getCloseFuture().awaitUninterruptibly(); 79 | connector.dispose(); 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/imagine/codec/ImageResponseDecoder.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.imagine.codec; 2 | 3 | import org.apache.mina.filter.codec.ProtocolDecoderOutput; 4 | import org.apache.mina.filter.codec.CumulativeProtocolDecoder; 5 | import org.apache.mina.core.buffer.IoBuffer; 6 | import org.apache.mina.core.session.IoSession; 7 | 8 | import com.waylau.mina.demo.imagine.ImageResponse; 9 | 10 | import javax.imageio.ImageIO; 11 | 12 | import java.awt.image.BufferedImage; 13 | import java.io.ByteArrayInputStream; 14 | import java.io.IOException; 15 | 16 | /** 17 | * a decoder for {@link ImageResponse} objects 18 | * 19 | * @author waylau.com 20 | * @date 2015-2-26 21 | */ 22 | 23 | public class ImageResponseDecoder extends CumulativeProtocolDecoder { 24 | 25 | private static final String DECODER_STATE_KEY = ImageResponseDecoder.class.getName() + ".STATE"; 26 | 27 | public static final int MAX_IMAGE_SIZE = 5 * 1024 * 1024; 28 | 29 | private static class DecoderState { 30 | private BufferedImage image1; 31 | } 32 | 33 | protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception { 34 | DecoderState decoderState = (DecoderState) session.getAttribute(DECODER_STATE_KEY); 35 | if (decoderState == null) { 36 | decoderState = new DecoderState(); 37 | session.setAttribute(DECODER_STATE_KEY, decoderState); 38 | } 39 | if (decoderState.image1 == null) { 40 | // try to read first image 41 | if (in.prefixedDataAvailable(4, MAX_IMAGE_SIZE)) { 42 | decoderState.image1 = readImage(in); 43 | } else { 44 | // not enough data available to read first image 45 | return false; 46 | } 47 | } 48 | if (decoderState.image1 != null) { 49 | // try to read second image 50 | if (in.prefixedDataAvailable(4, MAX_IMAGE_SIZE)) { 51 | BufferedImage image2 = readImage(in); 52 | ImageResponse imageResponse = new ImageResponse(decoderState.image1, image2); 53 | out.write(imageResponse); 54 | decoderState.image1 = null; 55 | return true; 56 | } else { 57 | // not enough data available to read second image 58 | return false; 59 | } 60 | } 61 | return false; 62 | } 63 | 64 | private BufferedImage readImage(IoBuffer in) throws IOException { 65 | int length = in.getInt(); 66 | byte[] bytes = new byte[length]; 67 | in.get(bytes); 68 | ByteArrayInputStream bais = new ByteArrayInputStream(bytes); 69 | return ImageIO.read(bais); 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/sumup/ServerSessionHandler.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.sumup; 2 | 3 | import org.apache.mina.core.service.IoHandler; 4 | import org.apache.mina.core.service.IoHandlerAdapter; 5 | import org.apache.mina.core.session.IdleStatus; 6 | import org.apache.mina.core.session.IoSession; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | import com.waylau.mina.demo.sumup.message.AddMessage; 11 | import com.waylau.mina.demo.sumup.message.ResultMessage; 12 | 13 | /** 14 | * {@link IoHandler} for SumUp server. 15 | * 16 | * @author waylau.com 17 | * @date 2015-2-26 18 | */ 19 | public class ServerSessionHandler extends IoHandlerAdapter { 20 | 21 | private static final String SUM_KEY = "sum"; 22 | 23 | private final static Logger LOGGER = LoggerFactory.getLogger(ServerSessionHandler.class); 24 | 25 | @Override 26 | public void sessionOpened(IoSession session) { 27 | // set idle time to 60 seconds 28 | session.getConfig().setIdleTime(IdleStatus.BOTH_IDLE, 60); 29 | 30 | // initial sum is zero 31 | session.setAttribute(SUM_KEY, Integer.valueOf(0)); 32 | } 33 | 34 | @Override 35 | public void messageReceived(IoSession session, Object message) { 36 | // client only sends AddMessage. otherwise, we will have to identify 37 | // its type using instanceof operator. 38 | AddMessage am = (AddMessage) message; 39 | 40 | // add the value to the current sum. 41 | int sum = ((Integer) session.getAttribute(SUM_KEY)).intValue(); 42 | int value = am.getValue(); 43 | long expectedSum = (long) sum + value; 44 | if (expectedSum > Integer.MAX_VALUE || expectedSum < Integer.MIN_VALUE) { 45 | // if the sum overflows or underflows, return error message 46 | ResultMessage rm = new ResultMessage(); 47 | rm.setSequence(am.getSequence()); // copy sequence 48 | rm.setOk(false); 49 | session.write(rm); 50 | } else { 51 | // sum up 52 | sum = (int) expectedSum; 53 | session.setAttribute(SUM_KEY, Integer.valueOf(sum)); 54 | 55 | // return the result message 56 | ResultMessage rm = new ResultMessage(); 57 | rm.setSequence(am.getSequence()); // copy sequence 58 | rm.setOk(true); 59 | rm.setValue(sum); 60 | session.write(rm); 61 | } 62 | } 63 | 64 | @Override 65 | public void sessionIdle(IoSession session, IdleStatus status) { 66 | LOGGER.info("Disconnecting the idle."); 67 | // disconnect an idle client 68 | session.close(true); 69 | } 70 | 71 | @Override 72 | public void exceptionCaught(IoSession session, Throwable cause) { 73 | // close the connection on exceptional situation 74 | session.close(true); 75 | } 76 | } -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/udp/MemoryMonitor.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.udp; 2 | 3 | import java.awt.BorderLayout; 4 | import java.awt.Dimension; 5 | import java.io.IOException; 6 | import java.net.InetSocketAddress; 7 | import java.net.SocketAddress; 8 | import java.util.concurrent.ConcurrentHashMap; 9 | 10 | import javax.swing.JFrame; 11 | import javax.swing.JLabel; 12 | import javax.swing.JPanel; 13 | import javax.swing.JTabbedPane; 14 | 15 | import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder; 16 | import org.apache.mina.filter.logging.LoggingFilter; 17 | import org.apache.mina.transport.socket.DatagramSessionConfig; 18 | import org.apache.mina.transport.socket.nio.NioDatagramAcceptor; 19 | 20 | public class MemoryMonitor { 21 | private static final long serialVersionUID = 1L; 22 | 23 | public static final int PORT = 18567; 24 | 25 | protected static final Dimension PANEL_SIZE = new Dimension(300, 200); 26 | 27 | private JFrame frame; 28 | 29 | private JTabbedPane tabbedPane; 30 | 31 | private ConcurrentHashMap clients; 32 | 33 | public MemoryMonitor() throws IOException { 34 | 35 | NioDatagramAcceptor acceptor = new NioDatagramAcceptor(); 36 | acceptor.setHandler(new MemoryMonitorHandler(this)); 37 | 38 | DefaultIoFilterChainBuilder chain = acceptor.getFilterChain(); 39 | chain.addLast("logger", new LoggingFilter()); 40 | 41 | DatagramSessionConfig dcfg = acceptor.getSessionConfig(); 42 | dcfg.setReuseAddress(true); 43 | 44 | frame = new JFrame("Memory monitor"); 45 | tabbedPane = new JTabbedPane(); 46 | tabbedPane.add("Welcome", createWelcomePanel()); 47 | frame.add(tabbedPane, BorderLayout.CENTER); 48 | clients = new ConcurrentHashMap(); 49 | frame.pack(); 50 | frame.setLocation(300, 300); 51 | frame.setVisible(true); 52 | 53 | acceptor.bind(new InetSocketAddress(PORT)); 54 | System.out.println("UDPServer listening on port " + PORT); 55 | } 56 | 57 | private JPanel createWelcomePanel() { 58 | JPanel panel = new JPanel(); 59 | panel.setPreferredSize(PANEL_SIZE); 60 | panel.add(new JLabel("Welcome to the Memory Monitor")); 61 | return panel; 62 | } 63 | 64 | protected void recvUpdate(SocketAddress clientAddr, long update) { 65 | ClientPanel clientPanel = clients.get(clientAddr); 66 | if (clientPanel != null) { 67 | clientPanel.updateTextField(update); 68 | } else { 69 | System.err.println("Received update from unknown client"); 70 | } 71 | } 72 | 73 | protected void addClient(SocketAddress clientAddr) { 74 | if (!containsClient(clientAddr)) { 75 | ClientPanel clientPanel = new ClientPanel(clientAddr.toString()); 76 | tabbedPane.add(clientAddr.toString(), clientPanel); 77 | clients.put(clientAddr, clientPanel); 78 | } 79 | } 80 | 81 | protected boolean containsClient(SocketAddress clientAddr) { 82 | return clients.contains(clientAddr); 83 | } 84 | 85 | protected void removeClient(SocketAddress clientAddr) { 86 | clients.remove(clientAddr); 87 | } 88 | 89 | public static void main(String[] args) throws IOException { 90 | new MemoryMonitor(); 91 | } 92 | } -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/echoserver/ssl/SslSocketFactory.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.echoserver.ssl; 2 | 3 | import java.io.IOException; 4 | import java.net.InetAddress; 5 | import java.net.Socket; 6 | import java.net.UnknownHostException; 7 | import java.security.GeneralSecurityException; 8 | 9 | import javax.net.SocketFactory; 10 | 11 | /** 12 | * Simple Socket factory to create sockets with or without SSL enabled. 13 | * If SSL enabled a "bougus" SSL Context is used (suitable for test purposes) 14 | * 15 | * @author waylau.com 16 | * @date 2015-4-6 17 | */ 18 | public class SslSocketFactory extends SocketFactory { 19 | private static boolean sslEnabled = false; 20 | 21 | private static javax.net.ssl.SSLSocketFactory sslFactory = null; 22 | 23 | private static javax.net.SocketFactory factory = null; 24 | 25 | public SslSocketFactory() { 26 | super(); 27 | } 28 | 29 | @Override 30 | public Socket createSocket(String arg1, int arg2) throws IOException, 31 | UnknownHostException { 32 | if (isSslEnabled()) { 33 | return getSSLFactory().createSocket(arg1, arg2); 34 | } else { 35 | return new Socket(arg1, arg2); 36 | } 37 | } 38 | 39 | @Override 40 | public Socket createSocket(String arg1, int arg2, InetAddress arg3, int arg4) 41 | throws IOException, UnknownHostException { 42 | if (isSslEnabled()) { 43 | return getSSLFactory().createSocket(arg1, arg2, arg3, arg4); 44 | } else { 45 | return new Socket(arg1, arg2, arg3, arg4); 46 | } 47 | } 48 | 49 | @Override 50 | public Socket createSocket(InetAddress arg1, int arg2) throws IOException { 51 | if (isSslEnabled()) { 52 | return getSSLFactory().createSocket(arg1, arg2); 53 | } else { 54 | return new Socket(arg1, arg2); 55 | } 56 | } 57 | 58 | @Override 59 | public Socket createSocket(InetAddress arg1, int arg2, InetAddress arg3, 60 | int arg4) throws IOException { 61 | if (isSslEnabled()) { 62 | return getSSLFactory().createSocket(arg1, arg2, arg3, arg4); 63 | } else { 64 | return new Socket(arg1, arg2, arg3, arg4); 65 | } 66 | } 67 | 68 | public static javax.net.SocketFactory getSocketFactory() { 69 | if (factory == null) { 70 | factory = new SslSocketFactory(); 71 | } 72 | return factory; 73 | } 74 | 75 | private javax.net.ssl.SSLSocketFactory getSSLFactory() { 76 | if (sslFactory == null) { 77 | try { 78 | sslFactory = BogusSslContextFactory.getInstance(false) 79 | .getSocketFactory(); 80 | } catch (GeneralSecurityException e) { 81 | throw new RuntimeException("could not create SSL socket", e); 82 | } 83 | } 84 | return sslFactory; 85 | } 86 | 87 | public static boolean isSslEnabled() { 88 | return sslEnabled; 89 | } 90 | 91 | public static void setSslEnabled(boolean newSslEnabled) { 92 | sslEnabled = newSslEnabled; 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/chat/client/ConnectDialog.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.chat.client; 2 | 3 | import java.awt.BorderLayout; 4 | import java.awt.Frame; 5 | import java.awt.HeadlessException; 6 | import java.awt.event.ActionEvent; 7 | 8 | import javax.swing.AbstractAction; 9 | import javax.swing.BoxLayout; 10 | import javax.swing.JButton; 11 | import javax.swing.JCheckBox; 12 | import javax.swing.JDialog; 13 | import javax.swing.JLabel; 14 | import javax.swing.JPanel; 15 | import javax.swing.JTextField; 16 | 17 | /** 18 | * TODO Add documentation 19 | * 20 | * @author waylau.com 21 | * @date 2015-4-6 22 | */ 23 | public class ConnectDialog extends JDialog { 24 | private static final long serialVersionUID = 2009384520250666216L; 25 | 26 | private String serverAddress; 27 | 28 | private String username; 29 | 30 | private boolean useSsl; 31 | 32 | private boolean cancelled = false; 33 | 34 | public ConnectDialog(Frame owner) throws HeadlessException { 35 | super(owner, "Connect", true); 36 | 37 | serverAddress = "localhost:1234"; 38 | username = "user" + Math.round(Math.random() * 10); 39 | 40 | final JTextField serverAddressField = new JTextField(serverAddress); 41 | final JTextField usernameField = new JTextField(username); 42 | final JCheckBox useSslCheckBox = new JCheckBox("Use SSL", false); 43 | 44 | JPanel content = new JPanel(); 45 | content.setLayout(new BoxLayout(content, BoxLayout.PAGE_AXIS)); 46 | content.add(new JLabel("Server address")); 47 | content.add(serverAddressField); 48 | content.add(new JLabel("Username")); 49 | content.add(usernameField); 50 | content.add(useSslCheckBox); 51 | 52 | JButton okButton = new JButton(); 53 | okButton.setAction(new AbstractAction("OK") { 54 | private static final long serialVersionUID = -2292183622613960604L; 55 | 56 | public void actionPerformed(ActionEvent e) { 57 | serverAddress = serverAddressField.getText(); 58 | username = usernameField.getText(); 59 | useSsl = useSslCheckBox.isSelected(); 60 | ConnectDialog.this.dispose(); 61 | } 62 | }); 63 | 64 | JButton cancelButton = new JButton(); 65 | cancelButton.setAction(new AbstractAction("Cancel") { 66 | private static final long serialVersionUID = 6122393546173723305L; 67 | 68 | public void actionPerformed(ActionEvent e) { 69 | cancelled = true; 70 | ConnectDialog.this.dispose(); 71 | } 72 | }); 73 | 74 | JPanel buttons = new JPanel(); 75 | buttons.add(okButton); 76 | buttons.add(cancelButton); 77 | 78 | getContentPane().add(content, BorderLayout.CENTER); 79 | getContentPane().add(buttons, BorderLayout.SOUTH); 80 | } 81 | 82 | public boolean isCancelled() { 83 | return cancelled; 84 | } 85 | 86 | public String getServerAddress() { 87 | return serverAddress; 88 | } 89 | 90 | public String getUsername() { 91 | return username; 92 | } 93 | 94 | public boolean isUseSsl() { 95 | return useSsl; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/imagine/client/ImageClient.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.imagine.client; 2 | 3 | import org.apache.mina.core.RuntimeIoException; 4 | import org.apache.mina.core.future.ConnectFuture; 5 | import org.apache.mina.core.service.IoHandlerAdapter; 6 | import org.apache.mina.core.session.IoSession; 7 | import org.apache.mina.filter.codec.ProtocolCodecFilter; 8 | import org.apache.mina.transport.socket.SocketConnector; 9 | import org.apache.mina.transport.socket.nio.NioSocketConnector; 10 | 11 | import com.waylau.mina.demo.imagine.ImageRequest; 12 | import com.waylau.mina.demo.imagine.ImageResponse; 13 | import com.waylau.mina.demo.imagine.codec.ImageCodecFactory; 14 | 15 | import java.net.InetSocketAddress; 16 | 17 | /** 18 | * client for the {@link ImageServer} 19 | * 20 | * @author waylau.com 21 | * @date 2015-2-26 22 | */ 23 | public class ImageClient extends IoHandlerAdapter { 24 | public static final int CONNECT_TIMEOUT = 3000; 25 | 26 | private String host; 27 | private int port; 28 | private SocketConnector connector; 29 | private IoSession session; 30 | private ImageListener imageListener; 31 | 32 | public ImageClient(String host, int port, ImageListener imageListener) { 33 | this.host = host; 34 | this.port = port; 35 | this.imageListener = imageListener; 36 | connector = new NioSocketConnector(); 37 | connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new ImageCodecFactory(true))); 38 | connector.setHandler(this); 39 | } 40 | 41 | public boolean isConnected() { 42 | return (session != null && session.isConnected()); 43 | } 44 | 45 | public void connect() { 46 | ConnectFuture connectFuture = connector.connect(new InetSocketAddress(host, port)); 47 | connectFuture.awaitUninterruptibly(CONNECT_TIMEOUT); 48 | try { 49 | session = connectFuture.getSession(); 50 | } 51 | catch (RuntimeIoException e) { 52 | imageListener.onException(e); 53 | } 54 | } 55 | 56 | public void disconnect() { 57 | if (session != null) { 58 | session.close(true).awaitUninterruptibly(CONNECT_TIMEOUT); 59 | session = null; 60 | } 61 | } 62 | 63 | public void sessionOpened(IoSession session) throws Exception { 64 | imageListener.sessionOpened(); 65 | } 66 | 67 | public void sessionClosed(IoSession session) throws Exception { 68 | imageListener.sessionClosed(); 69 | } 70 | 71 | public void sendRequest(ImageRequest imageRequest) { 72 | if (session == null) { 73 | //noinspection ThrowableInstanceNeverThrown 74 | imageListener.onException(new Throwable("not connected")); 75 | } else { 76 | session.write(imageRequest); 77 | } 78 | } 79 | 80 | public void messageReceived(IoSession session, Object message) throws Exception { 81 | ImageResponse response = (ImageResponse) message; 82 | imageListener.onImages(response.getImage1(), response.getImage2()); 83 | } 84 | 85 | public void exceptionCaught(IoSession session, Throwable cause) throws Exception { 86 | imageListener.onException(cause); 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/chat/client/ChatClientSupport.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.chat.client; 2 | 3 | import java.net.SocketAddress; 4 | 5 | import javax.net.ssl.SSLContext; 6 | 7 | import org.apache.mina.core.filterchain.IoFilter; 8 | import org.apache.mina.core.future.ConnectFuture; 9 | import org.apache.mina.core.service.IoHandler; 10 | import org.apache.mina.core.session.IoSession; 11 | import org.apache.mina.filter.ssl.SslFilter; 12 | import org.apache.mina.filter.codec.ProtocolCodecFilter; 13 | import org.apache.mina.filter.codec.textline.TextLineCodecFactory; 14 | import org.apache.mina.filter.logging.LoggingFilter; 15 | import org.apache.mina.filter.logging.MdcInjectionFilter; 16 | import org.apache.mina.transport.socket.nio.NioSocketConnector; 17 | 18 | import com.waylau.mina.demo.echoserver.ssl.BogusSslContextFactory; 19 | 20 | /** 21 | * A simple chat client for a given user. 22 | * 23 | * @author waylau.com 24 | * @date 2015-4-6 25 | */ 26 | public class ChatClientSupport { 27 | private final IoHandler handler; 28 | 29 | private final String name; 30 | 31 | private IoSession session; 32 | 33 | public ChatClientSupport(String name, IoHandler handler) { 34 | if (name == null) { 35 | throw new IllegalArgumentException("Name can not be null"); 36 | } 37 | this.name = name; 38 | this.handler = handler; 39 | } 40 | 41 | public boolean connect(NioSocketConnector connector, SocketAddress address, 42 | boolean useSsl) { 43 | if (session != null && session.isConnected()) { 44 | throw new IllegalStateException( 45 | "Already connected. Disconnect first."); 46 | } 47 | 48 | try { 49 | IoFilter LOGGING_FILTER = new LoggingFilter(); 50 | 51 | IoFilter CODEC_FILTER = new ProtocolCodecFilter( 52 | new TextLineCodecFactory()); 53 | 54 | connector.getFilterChain().addLast("mdc", new MdcInjectionFilter()); 55 | connector.getFilterChain().addLast("codec", CODEC_FILTER); 56 | connector.getFilterChain().addLast("logger", LOGGING_FILTER); 57 | 58 | if (useSsl) { 59 | SSLContext sslContext = BogusSslContextFactory 60 | .getInstance(false); 61 | SslFilter sslFilter = new SslFilter(sslContext); 62 | sslFilter.setUseClientMode(true); 63 | connector.getFilterChain().addFirst("sslFilter", sslFilter); 64 | } 65 | 66 | connector.setHandler(handler); 67 | ConnectFuture future1 = connector.connect(address); 68 | future1.awaitUninterruptibly(); 69 | if (!future1.isConnected()) { 70 | return false; 71 | } 72 | session = future1.getSession(); 73 | login(); 74 | 75 | return true; 76 | } catch (Exception e) { 77 | return false; 78 | } 79 | } 80 | 81 | public void login() { 82 | session.write("LOGIN " + name); 83 | } 84 | 85 | public void broadcast(String message) { 86 | session.write("BROADCAST " + message); 87 | } 88 | 89 | public void quit() { 90 | if (session != null) { 91 | if (session.isConnected()) { 92 | session.write("QUIT"); 93 | // Wait until the chat ends. 94 | session.getCloseFuture().awaitUninterruptibly(); 95 | } 96 | session.close(true); 97 | } 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /mina2-demos/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.waylau 6 | mina2-demos 7 | 0.0.1-SNAPSHOT 8 | jar 9 | 10 | mina2-demos 11 | http://www.waylau.com 12 | 13 | 14 | UTF-8 15 | 2.0.9 16 | 1.2.17 17 | 1.7.12 18 | 2.5.6.SEC03 19 | 4.0 20 | 21 | 22 | 23 | 24 | org.apache.maven.plugins 25 | maven-compiler-plugin 26 | 3.2 27 | 28 | true 29 | 1.7 30 | 1.7 31 | 32 | 33 | 34 | org.apache.felix 35 | maven-bundle-plugin 36 | true 37 | 38 | 39 | 40 | 41 | 42 | junit 43 | junit 44 | 4.12 45 | test 46 | 47 | 48 | org.apache.mina 49 | mina-core 50 | ${version.mina} 51 | 52 | 53 | org.apache.mina 54 | mina-integration-jmx 55 | ${version.mina} 56 | 57 | 58 | org.apache.mina 59 | mina-integration-beans 60 | ${version.mina} 61 | 62 | 63 | org.apache.mina 64 | mina-integration-ognl 65 | ${version.mina} 66 | 67 | 68 | 69 | org.slf4j 70 | slf4j-api 71 | ${version.slf4j.api} 72 | 73 | 74 | 75 | org.slf4j 76 | slf4j-log4j12 77 | 1.7.12 78 | 79 | 80 | log4j 81 | log4j 82 | 1.2.17 83 | 84 | 85 | 86 | 87 | org.apache.xbean 88 | xbean-spring 89 | ${version.xbean.spring} 90 | 91 | 92 | 93 | org.springframework 94 | spring 95 | ${version.springframework} 96 | 97 | 98 | commons-logging 99 | commons-logging 100 | 101 | 102 | commons-logging 103 | commons-logging-api 104 | 105 | 106 | javax.servlet 107 | servlet-api 108 | 109 | 110 | 111 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/udp/client/MemMonClient.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.udp.client; 2 | 3 | import java.net.InetSocketAddress; 4 | 5 | import org.apache.mina.core.buffer.IoBuffer; 6 | import org.apache.mina.core.future.ConnectFuture; 7 | import org.apache.mina.core.future.IoFutureListener; 8 | import org.apache.mina.core.service.IoConnector; 9 | import org.apache.mina.core.service.IoHandlerAdapter; 10 | import org.apache.mina.core.session.IdleStatus; 11 | import org.apache.mina.core.session.IoSession; 12 | import org.apache.mina.transport.socket.nio.NioDatagramConnector; 13 | import org.slf4j.Logger; 14 | import org.slf4j.LoggerFactory; 15 | 16 | import com.waylau.mina.demo.udp.MemoryMonitor; 17 | 18 | public class MemMonClient extends IoHandlerAdapter { 19 | private final static Logger LOGGER = LoggerFactory 20 | .getLogger(MemMonClient.class); 21 | 22 | private IoSession session; 23 | 24 | private IoConnector connector; 25 | 26 | /** 27 | * Default constructor. 28 | */ 29 | public MemMonClient() { 30 | 31 | LOGGER.debug("UDPClient::UDPClient"); 32 | LOGGER.debug("Created a datagram connector"); 33 | connector = new NioDatagramConnector(); 34 | 35 | LOGGER.debug("Setting the handler"); 36 | connector.setHandler(this); 37 | 38 | LOGGER.debug("About to connect to the server..."); 39 | ConnectFuture connFuture = connector.connect(new InetSocketAddress( 40 | "localhost", MemoryMonitor.PORT)); 41 | 42 | LOGGER.debug("About to wait."); 43 | connFuture.awaitUninterruptibly(); 44 | 45 | LOGGER.debug("Adding a future listener."); 46 | connFuture.addListener(new IoFutureListener() { 47 | public void operationComplete(ConnectFuture future) { 48 | if (future.isConnected()) { 49 | LOGGER.debug("...connected"); 50 | session = future.getSession(); 51 | try { 52 | sendData(); 53 | } catch (InterruptedException e) { 54 | e.printStackTrace(); 55 | } 56 | } else { 57 | LOGGER.error("Not connected...exiting"); 58 | } 59 | } 60 | }); 61 | } 62 | 63 | private void sendData() throws InterruptedException { 64 | for (int i = 0; i < 30; i++) { 65 | long free = Runtime.getRuntime().freeMemory(); 66 | IoBuffer buffer = IoBuffer.allocate(8); 67 | buffer.putLong(free); 68 | buffer.flip(); 69 | session.write(buffer); 70 | 71 | try { 72 | Thread.sleep(1000); 73 | } catch (InterruptedException e) { 74 | e.printStackTrace(); 75 | throw new InterruptedException(e.getMessage()); 76 | } 77 | } 78 | } 79 | 80 | @Override 81 | public void exceptionCaught(IoSession session, Throwable cause) 82 | throws Exception { 83 | cause.printStackTrace(); 84 | } 85 | 86 | @Override 87 | public void messageReceived(IoSession session, Object message) 88 | throws Exception { 89 | LOGGER.debug("Session recv..."); 90 | } 91 | 92 | @Override 93 | public void messageSent(IoSession session, Object message) throws Exception { 94 | LOGGER.debug("Message sent..."); 95 | } 96 | 97 | @Override 98 | public void sessionClosed(IoSession session) throws Exception { 99 | LOGGER.debug("Session closed..."); 100 | } 101 | 102 | @Override 103 | public void sessionCreated(IoSession session) throws Exception { 104 | LOGGER.debug("Session created..."); 105 | } 106 | 107 | @Override 108 | public void sessionIdle(IoSession session, IdleStatus status) 109 | throws Exception { 110 | LOGGER.debug("Session idle..."); 111 | } 112 | 113 | @Override 114 | public void sessionOpened(IoSession session) throws Exception { 115 | LOGGER.debug("Session opened..."); 116 | } 117 | 118 | public static void main(String[] args) { 119 | new MemMonClient(); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/udp/perf/UdpClient.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.udp.perf; 2 | 3 | import java.net.InetSocketAddress; 4 | 5 | import org.apache.mina.core.buffer.IoBuffer; 6 | import org.apache.mina.core.future.ConnectFuture; 7 | import org.apache.mina.core.service.IoConnector; 8 | import org.apache.mina.core.service.IoHandlerAdapter; 9 | import org.apache.mina.core.session.IdleStatus; 10 | import org.apache.mina.core.session.IoSession; 11 | import org.apache.mina.transport.socket.nio.NioDatagramConnector; 12 | 13 | /** 14 | * An UDP client taht just send thousands of small messages to a UdpServer. 15 | * 16 | * This class is used for performance test purposes. It does nothing at all, but send a message 17 | * repetitly to a server. 18 | * 19 | * @author waylau.com 20 | * @date 2015-4-6 21 | */ 22 | public class UdpClient extends IoHandlerAdapter { 23 | /** The connector */ 24 | private IoConnector connector; 25 | 26 | /** The session */ 27 | private static IoSession session; 28 | 29 | /** 30 | * Create the UdpClient's instance 31 | */ 32 | public UdpClient() { 33 | connector = new NioDatagramConnector(); 34 | 35 | connector.setHandler(this); 36 | 37 | ConnectFuture connFuture = connector.connect(new InetSocketAddress("localhost", UdpServer.PORT)); 38 | 39 | connFuture.awaitUninterruptibly(); 40 | 41 | session = connFuture.getSession(); 42 | } 43 | 44 | /** 45 | * {@inheritDoc} 46 | */ 47 | @Override 48 | public void exceptionCaught(IoSession session, Throwable cause) throws Exception { 49 | cause.printStackTrace(); 50 | } 51 | 52 | /** 53 | * {@inheritDoc} 54 | */ 55 | @Override 56 | public void messageReceived(IoSession session, Object message) throws Exception { 57 | } 58 | 59 | /** 60 | * {@inheritDoc} 61 | */ 62 | @Override 63 | public void messageSent(IoSession session, Object message) throws Exception { 64 | } 65 | 66 | /** 67 | * {@inheritDoc} 68 | */ 69 | @Override 70 | public void sessionClosed(IoSession session) throws Exception { 71 | } 72 | 73 | /** 74 | * {@inheritDoc} 75 | */ 76 | @Override 77 | public void sessionCreated(IoSession session) throws Exception { 78 | } 79 | 80 | /** 81 | * {@inheritDoc} 82 | */ 83 | @Override 84 | public void sessionIdle(IoSession session, IdleStatus status) throws Exception { 85 | } 86 | 87 | /** 88 | * {@inheritDoc} 89 | */ 90 | @Override 91 | public void sessionOpened(IoSession session) throws Exception { 92 | } 93 | 94 | /** 95 | * The main method : instanciates a client, and send N messages. We sleep 96 | * between each K messages sent, to avoid the server saturation. 97 | * @param args 98 | * @throws Exception 99 | */ 100 | public static void main(String[] args) throws Exception { 101 | UdpClient client = new UdpClient(); 102 | 103 | long t0 = System.currentTimeMillis(); 104 | 105 | for (int i = 0; i <= UdpServer.MAX_RECEIVED; i++) { 106 | Thread.sleep(1); 107 | 108 | String str = Integer.toString(i); 109 | byte[] data = str.getBytes(); 110 | IoBuffer buffer = IoBuffer.allocate(data.length); 111 | buffer.put(data); 112 | buffer.flip(); 113 | session.write(buffer); 114 | 115 | if (i % 10000 == 0) { 116 | System.out.println("Sent " + i + " messages"); 117 | } 118 | } 119 | 120 | long t1 = System.currentTimeMillis(); 121 | 122 | System.out.println("Sent messages delay : " + (t1 - t0)); 123 | 124 | Thread.sleep(100000); 125 | 126 | client.connector.dispose(true); 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/udp/perf/UdpServer.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.udp.perf; 2 | 3 | import java.io.IOException; 4 | import java.net.InetSocketAddress; 5 | import java.util.concurrent.atomic.AtomicInteger; 6 | 7 | import org.apache.mina.core.service.IoHandlerAdapter; 8 | import org.apache.mina.core.session.IdleStatus; 9 | import org.apache.mina.core.session.IoSession; 10 | import org.apache.mina.transport.socket.nio.NioDatagramAcceptor; 11 | 12 | /** 13 | * An UDP server used for performance tests. 14 | * 15 | * It does nothing fancy, except receiving the messages, and counting the number of 16 | * received messages. 17 | * 18 | * @author waylau.com 19 | * @date 2015-4-6 20 | */ 21 | public class UdpServer extends IoHandlerAdapter { 22 | /** The listening port (check that it's not already in use) */ 23 | public static final int PORT = 18567; 24 | 25 | /** The number of message to receive */ 26 | public static final int MAX_RECEIVED = 100000; 27 | 28 | /** The starting point, set when we receive the first message */ 29 | private static long t0; 30 | 31 | /** A counter incremented for every recieved message */ 32 | private AtomicInteger nbReceived = new AtomicInteger(0); 33 | 34 | /** 35 | * {@inheritDoc} 36 | */ 37 | @Override 38 | public void exceptionCaught(IoSession session, Throwable cause) throws Exception { 39 | cause.printStackTrace(); 40 | session.close(true); 41 | } 42 | 43 | /** 44 | * {@inheritDoc} 45 | */ 46 | @Override 47 | public void messageReceived(IoSession session, Object message) throws Exception { 48 | 49 | int nb = nbReceived.incrementAndGet(); 50 | 51 | if (nb == 1) { 52 | t0 = System.currentTimeMillis(); 53 | } 54 | 55 | if (nb == MAX_RECEIVED) { 56 | long t1 = System.currentTimeMillis(); 57 | System.out.println("-------------> end " + (t1 - t0)); 58 | } 59 | 60 | if (nb % 10000 == 0) { 61 | System.out.println("Received " + nb + " messages"); 62 | } 63 | 64 | // If we want to test the write operation, uncomment this line 65 | session.write(message); 66 | } 67 | 68 | /** 69 | * {@inheritDoc} 70 | */ 71 | @Override 72 | public void sessionClosed(IoSession session) throws Exception { 73 | System.out.println("Session closed..."); 74 | 75 | // Reinitialize the counter and expose the number of received messages 76 | System.out.println("Nb message received : " + nbReceived.get()); 77 | nbReceived.set(0); 78 | } 79 | 80 | /** 81 | * {@inheritDoc} 82 | */ 83 | @Override 84 | public void sessionCreated(IoSession session) throws Exception { 85 | System.out.println("Session created..."); 86 | } 87 | 88 | /** 89 | * {@inheritDoc} 90 | */ 91 | @Override 92 | public void sessionIdle(IoSession session, IdleStatus status) throws Exception { 93 | System.out.println("Session idle..."); 94 | } 95 | 96 | /** 97 | * {@inheritDoc} 98 | */ 99 | @Override 100 | public void sessionOpened(IoSession session) throws Exception { 101 | System.out.println("Session Opened..."); 102 | } 103 | 104 | /** 105 | * Create the UDP server 106 | */ 107 | public UdpServer() throws IOException { 108 | NioDatagramAcceptor acceptor = new NioDatagramAcceptor(); 109 | acceptor.setHandler(this); 110 | 111 | // The logger, if needed. Commented atm 112 | //DefaultIoFilterChainBuilder chain = acceptor.getFilterChain(); 113 | //chain.addLast("logger", new LoggingFilter()); 114 | 115 | acceptor.bind(new InetSocketAddress(PORT)); 116 | 117 | System.out.println("Server started..."); 118 | } 119 | 120 | /** 121 | * The entry point. 122 | */ 123 | public static void main(String[] args) throws IOException { 124 | new UdpServer(); 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/imagine/server/ImageServer.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.imagine.server; 2 | 3 | import java.lang.management.ManagementFactory; 4 | import java.net.InetSocketAddress; 5 | import java.util.concurrent.Executors; 6 | 7 | import javax.management.MBeanServer; 8 | import javax.management.ObjectName; 9 | 10 | import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder; 11 | import org.apache.mina.filter.codec.ProtocolCodecFilter; 12 | import org.apache.mina.filter.executor.ExecutorFilter; 13 | import org.apache.mina.integration.jmx.IoFilterMBean; 14 | import org.apache.mina.integration.jmx.IoServiceMBean; 15 | import org.apache.mina.transport.socket.nio.NioSocketAcceptor; 16 | 17 | import com.waylau.mina.demo.imagine.codec.ImageCodecFactory; 18 | 19 | /** 20 | * entry point for the server used in the tutorial on protocol codecs 21 | * 22 | * @author waylau.com 23 | * @date 2015-2-26 24 | */ 25 | 26 | public class ImageServer { 27 | public static final int PORT = 33789; 28 | 29 | public static void main(String[] args) throws Exception { 30 | 31 | // create a JMX MBean Server server instance 32 | MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer(); 33 | 34 | // Create a class that handles sessions, incoming and outgoing data. For 35 | // this step, we will pass in the MBeanServer so that sessions can be 36 | // registered on the MBeanServer. 37 | ImageServerIoHandler handler = new ImageServerIoHandler( mBeanServer ); 38 | 39 | // This socket acceptor will handle incoming connections 40 | NioSocketAcceptor acceptor = new NioSocketAcceptor(); 41 | 42 | // create a JMX-aware bean that wraps a MINA IoService object. In this 43 | // case, a NioSocketAcceptor. 44 | IoServiceMBean acceptorMBean = new IoServiceMBean( acceptor ); 45 | 46 | // create a JMX ObjectName. This has to be in a specific format. 47 | ObjectName acceptorName = new ObjectName( acceptor.getClass().getPackage().getName() + 48 | ":type=acceptor,name=" + acceptor.getClass().getSimpleName()); 49 | 50 | // register the bean on the MBeanServer. Without this line, no JMX will happen for 51 | // this acceptor. 52 | mBeanServer.registerMBean( acceptorMBean, acceptorName ); 53 | 54 | // add an IoFilter . This class is responsible for converting the incoming and 55 | // outgoing raw data to ImageRequest and ImageResponse objects 56 | ProtocolCodecFilter protocolFilter = new ProtocolCodecFilter(new ImageCodecFactory(false)); 57 | 58 | // create a JMX-aware bean that wraps a MINA IoFilter object. In this 59 | // case, a ProtocolCodecFilter 60 | IoFilterMBean protocolFilterMBean = new IoFilterMBean( protocolFilter ); 61 | 62 | // create a JMX ObjectName. 63 | ObjectName protocolFilterName = new ObjectName( protocolFilter.getClass().getPackage().getName() + 64 | ":type=protocolfilter,name=" + protocolFilter.getClass().getSimpleName() ); 65 | 66 | // register the bean on the MBeanServer. Without this line, no JMX will happen for 67 | // this filter. 68 | mBeanServer.registerMBean( protocolFilterMBean, protocolFilterName ); 69 | 70 | // add the protocolFilter to the acceptor, otherwise no filtering of data will happen 71 | acceptor.getFilterChain().addLast("protocol", protocolFilter); 72 | 73 | // get a reference to the filter chain from the acceptor 74 | DefaultIoFilterChainBuilder filterChainBuilder = acceptor.getFilterChain(); 75 | 76 | // add an ExecutorFilter to the filter chain. The preferred order is to put the executor filter 77 | // after any protocol filters due to the fact that protocol codecs are generally CPU-bound 78 | // which is the same as I/O filters. 79 | filterChainBuilder.addLast("threadPool", new ExecutorFilter(Executors.newCachedThreadPool())); 80 | 81 | // set this NioSocketAcceptor's handler to the ImageServerHandler 82 | acceptor.setHandler(handler); 83 | 84 | // Bind to the specified address. This kicks off the listening for 85 | // incoming connections 86 | acceptor.bind(new InetSocketAddress(PORT)); 87 | System.out.println("Step 3 server is listenig at port " + PORT); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/echoserver/ssl/BogusSslContextFactory.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.echoserver.ssl; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.security.GeneralSecurityException; 6 | import java.security.KeyStore; 7 | import java.security.Security; 8 | 9 | import javax.net.ssl.KeyManagerFactory; 10 | import javax.net.ssl.SSLContext; 11 | 12 | /** 13 | * Factory to create a bogus SSLContext. 14 | * 15 | * @author waylau.com 16 | * @date 2015-4-6 17 | */ 18 | public class BogusSslContextFactory { 19 | 20 | /** 21 | * Protocol to use. 22 | */ 23 | private static final String PROTOCOL = "TLS"; 24 | 25 | private static final String KEY_MANAGER_FACTORY_ALGORITHM; 26 | 27 | static { 28 | String algorithm = Security 29 | .getProperty("ssl.KeyManagerFactory.algorithm"); 30 | if (algorithm == null) { 31 | algorithm = KeyManagerFactory.getDefaultAlgorithm(); 32 | } 33 | 34 | KEY_MANAGER_FACTORY_ALGORITHM = algorithm; 35 | } 36 | 37 | /** 38 | * Bougus Server certificate keystore file name. 39 | */ 40 | private static final String BOGUS_KEYSTORE = "bogus.cert"; 41 | 42 | // NOTE: The keystore was generated using keytool: 43 | // keytool -genkey -alias bogus -keysize 512 -validity 3650 44 | // -keyalg RSA -dname "CN=bogus.com, OU=XXX CA, 45 | // O=Bogus Inc, L=Stockholm, S=Stockholm, C=SE" 46 | // -keypass boguspw -storepass boguspw -keystore bogus.cert 47 | 48 | /** 49 | * Bougus keystore password. 50 | */ 51 | private static final char[] BOGUS_PW = { 'b', 'o', 'g', 'u', 's', 'p', 'w' }; 52 | 53 | private static SSLContext serverInstance = null; 54 | 55 | private static SSLContext clientInstance = null; 56 | 57 | /** 58 | * Get SSLContext singleton. 59 | * 60 | * @return SSLContext 61 | * @throws java.security.GeneralSecurityException 62 | * 63 | */ 64 | public static SSLContext getInstance(boolean server) 65 | throws GeneralSecurityException { 66 | SSLContext retInstance = null; 67 | if (server) { 68 | synchronized(BogusSslContextFactory.class) { 69 | if (serverInstance == null) { 70 | try { 71 | serverInstance = createBougusServerSslContext(); 72 | } catch (Exception ioe) { 73 | throw new GeneralSecurityException( 74 | "Can't create Server SSLContext:" + ioe); 75 | } 76 | } 77 | } 78 | retInstance = serverInstance; 79 | } else { 80 | synchronized (BogusSslContextFactory.class) { 81 | if (clientInstance == null) { 82 | clientInstance = createBougusClientSslContext(); 83 | } 84 | } 85 | retInstance = clientInstance; 86 | } 87 | return retInstance; 88 | } 89 | 90 | private static SSLContext createBougusServerSslContext() 91 | throws GeneralSecurityException, IOException { 92 | // Create keystore 93 | KeyStore ks = KeyStore.getInstance("JKS"); 94 | InputStream in = null; 95 | try { 96 | in = BogusSslContextFactory.class 97 | .getResourceAsStream(BOGUS_KEYSTORE); 98 | ks.load(in, BOGUS_PW); 99 | } finally { 100 | if (in != null) { 101 | try { 102 | in.close(); 103 | } catch (IOException ignored) { 104 | } 105 | } 106 | } 107 | 108 | // Set up key manager factory to use our key store 109 | KeyManagerFactory kmf = KeyManagerFactory 110 | .getInstance(KEY_MANAGER_FACTORY_ALGORITHM); 111 | kmf.init(ks, BOGUS_PW); 112 | 113 | // Initialize the SSLContext to work with our key managers. 114 | SSLContext sslContext = SSLContext.getInstance(PROTOCOL); 115 | sslContext.init(kmf.getKeyManagers(), 116 | BogusTrustManagerFactory.X509_MANAGERS, null); 117 | 118 | return sslContext; 119 | } 120 | 121 | private static SSLContext createBougusClientSslContext() 122 | throws GeneralSecurityException { 123 | SSLContext context = SSLContext.getInstance(PROTOCOL); 124 | context.init(null, BogusTrustManagerFactory.X509_MANAGERS, null); 125 | return context; 126 | } 127 | 128 | } 129 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/chat/ChatProtocolHandler.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.chat; 2 | 3 | import java.util.Collections; 4 | import java.util.HashSet; 5 | import java.util.Set; 6 | 7 | import org.apache.mina.core.service.IoHandler; 8 | import org.apache.mina.core.service.IoHandlerAdapter; 9 | import org.apache.mina.core.session.IoSession; 10 | import org.apache.mina.filter.logging.MdcInjectionFilter; 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | 14 | /** 15 | * {@link IoHandler} implementation of a simple chat server protocol. 16 | * 17 | * @author waylau.com 18 | * @date 2015-4-6 19 | */ 20 | public class ChatProtocolHandler extends IoHandlerAdapter { 21 | private final static Logger LOGGER = LoggerFactory.getLogger(ChatProtocolHandler.class); 22 | 23 | private final Set sessions = Collections 24 | .synchronizedSet(new HashSet()); 25 | 26 | private final Set users = Collections 27 | .synchronizedSet(new HashSet()); 28 | 29 | @Override 30 | public void exceptionCaught(IoSession session, Throwable cause) { 31 | LOGGER.warn("Unexpected exception.", cause); 32 | // Close connection when unexpected exception is caught. 33 | session.close(true); 34 | } 35 | 36 | @Override 37 | public void messageReceived(IoSession session, Object message) { 38 | Logger log = LoggerFactory.getLogger(ChatProtocolHandler.class); 39 | log.info("received: " + message); 40 | String theMessage = (String) message; 41 | String[] result = theMessage.split(" ", 2); 42 | String theCommand = result[0]; 43 | 44 | try { 45 | 46 | ChatCommand command = ChatCommand.valueOf(theCommand); 47 | String user = (String) session.getAttribute("user"); 48 | 49 | switch (command.toInt()) { 50 | 51 | case ChatCommand.QUIT: 52 | session.write("QUIT OK"); 53 | session.close(true); 54 | break; 55 | case ChatCommand.LOGIN: 56 | 57 | if (user != null) { 58 | session.write("LOGIN ERROR user " + user 59 | + " already logged in."); 60 | return; 61 | } 62 | 63 | if (result.length == 2) { 64 | user = result[1]; 65 | } else { 66 | session.write("LOGIN ERROR invalid login command."); 67 | return; 68 | } 69 | 70 | // check if the username is already used 71 | if (users.contains(user)) { 72 | session.write("LOGIN ERROR the name " + user 73 | + " is already used."); 74 | return; 75 | } 76 | 77 | sessions.add(session); 78 | session.setAttribute("user", user); 79 | MdcInjectionFilter.setProperty(session, "user", user); 80 | 81 | // Allow all users 82 | users.add(user); 83 | session.write("LOGIN OK"); 84 | broadcast("The user " + user + " has joined the chat session."); 85 | break; 86 | 87 | case ChatCommand.BROADCAST: 88 | 89 | if (result.length == 2) { 90 | broadcast(user + ": " + result[1]); 91 | } 92 | break; 93 | default: 94 | LOGGER.info("Unhandled command: " + command); 95 | break; 96 | } 97 | 98 | } catch (IllegalArgumentException e) { 99 | LOGGER.debug("Illegal argument", e); 100 | } 101 | } 102 | 103 | public void broadcast(String message) { 104 | synchronized (sessions) { 105 | for (IoSession session : sessions) { 106 | if (session.isConnected()) { 107 | session.write("BROADCAST OK " + message); 108 | } 109 | } 110 | } 111 | } 112 | 113 | @Override 114 | public void sessionClosed(IoSession session) throws Exception { 115 | String user = (String) session.getAttribute("user"); 116 | users.remove(user); 117 | sessions.remove(session); 118 | broadcast("The user " + user + " has left the chat session."); 119 | } 120 | 121 | public boolean isChatUser(String name) { 122 | return users.contains(name); 123 | } 124 | 125 | public int getNumberOfUsers() { 126 | return users.size(); 127 | } 128 | 129 | public void kick(String name) { 130 | synchronized (sessions) { 131 | for (IoSession session : sessions) { 132 | if (name.equals(session.getAttribute("user"))) { 133 | session.close(true); 134 | break; 135 | } 136 | } 137 | } 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/imagine/server/ImageServerIoHandler.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.imagine.server; 2 | 3 | import java.awt.Color; 4 | import java.awt.Font; 5 | import java.awt.Graphics; 6 | import java.awt.image.BufferedImage; 7 | 8 | import javax.management.MBeanServer; 9 | import javax.management.ObjectName; 10 | 11 | import org.apache.mina.core.service.IoHandlerAdapter; 12 | import org.apache.mina.core.session.IoSession; 13 | import org.apache.mina.integration.jmx.IoSessionMBean; 14 | import org.slf4j.Logger; 15 | import org.slf4j.LoggerFactory; 16 | 17 | import com.waylau.mina.demo.imagine.ImageRequest; 18 | import com.waylau.mina.demo.imagine.ImageResponse; 19 | 20 | /** 21 | * server-side {@link org.apache.mina.core.service.IoHandler} 22 | * 23 | * @author waylau.com 24 | * @date 2015-2-26 25 | */ 26 | 27 | public class ImageServerIoHandler extends IoHandlerAdapter { 28 | 29 | private final static String characters = "mina rocks abcdefghijklmnopqrstuvwxyz0123456789"; 30 | 31 | public static final String INDEX_KEY = ImageServerIoHandler.class.getName() + ".INDEX"; 32 | 33 | private static Logger LOGGER = LoggerFactory.getLogger(ImageServerIoHandler.class); 34 | 35 | private MBeanServer mBeanServer; 36 | 37 | /** 38 | * Creates a new instance of ImageServerIoHandler. For this step, we pass in a reference 39 | * to the MBeanServer. This instance will be used to register new IoSession objects 40 | * so that the JMX subsystem can report statistics on the sessions. 41 | * 42 | * @param mBeanServer 43 | * The JMX MBeanServer that will register the sessions 44 | */ 45 | public ImageServerIoHandler( MBeanServer mBeanServer ) { 46 | this.mBeanServer = mBeanServer; 47 | } 48 | 49 | /** 50 | * This method is called first when a new connection to the server is made. In here we will set 51 | * up the JMX session MBean. 52 | * 53 | * @see org.apache.mina.core.service.IoHandlerAdapter#sessionCreated(org.apache.mina.core.session.IoSession) 54 | */ 55 | public void sessionCreated( IoSession session ) throws Exception 56 | { 57 | // create a session MBean in order to load into the MBeanServer and allow 58 | // this session to be managed by the JMX subsystem. 59 | IoSessionMBean sessionMBean = new IoSessionMBean( session ); 60 | 61 | // create a JMX ObjectName. This has to be in a specific format. 62 | ObjectName sessionName = new ObjectName( session.getClass().getPackage().getName() + 63 | ":type=session,name=" + session.getClass().getSimpleName() + "-" + session.getId()); 64 | 65 | // register the bean on the MBeanServer. Without this line, no JMX will happen for 66 | // this session 67 | mBeanServer.registerMBean( sessionMBean, sessionName ); 68 | } 69 | 70 | /** 71 | * Called when the session is opened, which will come after the session created. 72 | * 73 | * @see org.apache.mina.core.service.IoHandlerAdapter#sessionOpened(org.apache.mina.core.session.IoSession) 74 | */ 75 | public void sessionOpened(IoSession session) throws Exception { 76 | 77 | // set the index to zero. This is used to determine how the build the 78 | // string that is sent to the client. 79 | session.setAttribute(INDEX_KEY, 0); 80 | } 81 | 82 | /** 83 | * This method will be called whenever an exception occurs. For this handler, 84 | * the logger will generate a warning message. 85 | * 86 | * @see org.apache.mina.core.service.IoHandlerAdapter#exceptionCaught(org.apache.mina.core.session.IoSession, java.lang.Throwable) 87 | */ 88 | public void exceptionCaught(IoSession session, Throwable cause) throws Exception { 89 | LOGGER.warn(cause.getMessage(), cause); 90 | } 91 | 92 | /** 93 | * Handle incoming messages. 94 | * 95 | * @see org.apache.mina.core.service.IoHandlerAdapter#messageReceived(org.apache.mina.core.session.IoSession, java.lang.Object) 96 | */ 97 | public void messageReceived(IoSession session, Object message) throws Exception { 98 | ImageRequest request = (ImageRequest) message; 99 | String text1 = generateString(session, request.getNumberOfCharacters()); 100 | String text2 = generateString(session, request.getNumberOfCharacters()); 101 | BufferedImage image1 = createImage(request, text1); 102 | BufferedImage image2 = createImage(request, text2); 103 | ImageResponse response = new ImageResponse(image1, image2); 104 | session.write(response); 105 | } 106 | 107 | /** 108 | * Create an image using the specified request and the text. 109 | * 110 | * @param request 111 | * Determines the height and width of the image 112 | * @param text 113 | * The text that is placed in the image 114 | * @return 115 | * a BufferedImage representing the text. 116 | */ 117 | private BufferedImage createImage(ImageRequest request, String text) { 118 | BufferedImage image = new BufferedImage(request.getWidth(), request.getHeight(), BufferedImage.TYPE_BYTE_INDEXED); 119 | Graphics graphics = image.createGraphics(); 120 | graphics.setColor(Color.YELLOW); 121 | graphics.fillRect(0, 0, image.getWidth(), image.getHeight()); 122 | Font serif = new Font("serif", Font.PLAIN, 30); 123 | graphics.setFont(serif); 124 | graphics.setColor(Color.BLUE); 125 | graphics.drawString(text, 10, 50); 126 | return image; 127 | } 128 | 129 | /** 130 | * Generate a string based on the 'characters' field in this class. The 131 | * characters that make up the string are based on the session 132 | * attribute "INDEX_KEY" 133 | * 134 | * @param session 135 | * The {@link IoSession} object that will provide the INDEX_KEY attribute 136 | * @param length 137 | * The length that the String will be 138 | * @return 139 | * The generated String 140 | */ 141 | private String generateString(IoSession session, int length) { 142 | Integer index = (Integer) session.getAttribute(INDEX_KEY); 143 | StringBuilder buffer = new StringBuilder(length); 144 | while (buffer.length() < length) { 145 | buffer.append(characters.charAt(index)); 146 | index++; 147 | if (index >= characters.length()) { 148 | index = 0; 149 | } 150 | } 151 | session.setAttribute(INDEX_KEY, index); 152 | return buffer.toString(); 153 | } 154 | 155 | } 156 | -------------------------------------------------------------------------------- /mina2-demos/src/main/resources/com/waylau/mina/demo/chat/serverContext.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 23 | 24 | 25 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/chat/client/SwingChatClient.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.chat.client; 2 | 3 | import java.awt.BorderLayout; 4 | import java.awt.Dimension; 5 | import java.awt.event.ActionEvent; 6 | import java.awt.event.ActionListener; 7 | import java.net.InetSocketAddress; 8 | import java.net.SocketAddress; 9 | 10 | import javax.swing.AbstractAction; 11 | import javax.swing.BorderFactory; 12 | import javax.swing.Box; 13 | import javax.swing.BoxLayout; 14 | import javax.swing.JButton; 15 | import javax.swing.JFrame; 16 | import javax.swing.JLabel; 17 | import javax.swing.JOptionPane; 18 | import javax.swing.JPanel; 19 | import javax.swing.JScrollBar; 20 | import javax.swing.JTextArea; 21 | import javax.swing.JTextField; 22 | import javax.swing.border.EmptyBorder; 23 | 24 | import org.apache.mina.transport.socket.nio.NioSocketConnector; 25 | 26 | import com.waylau.mina.demo.chat.client.SwingChatClientHandler.Callback; 27 | 28 | /** 29 | * Simple chat client based on Swing & MINA that implements the chat protocol. 30 | * 31 | * @author waylau.com 32 | * @date 2015-4-6 33 | */ 34 | public class SwingChatClient extends JFrame implements Callback { 35 | private static final long serialVersionUID = 1538675161745436968L; 36 | 37 | private JTextField inputText; 38 | 39 | private JButton loginButton; 40 | 41 | private JButton quitButton; 42 | 43 | private JButton closeButton; 44 | 45 | private JTextField serverField; 46 | 47 | private JTextField nameField; 48 | 49 | private JTextArea area; 50 | 51 | private JScrollBar scroll; 52 | 53 | private ChatClientSupport client; 54 | 55 | private SwingChatClientHandler handler; 56 | 57 | private NioSocketConnector connector; 58 | 59 | public SwingChatClient() { 60 | super("Chat Client based on Apache MINA"); 61 | 62 | connector = new NioSocketConnector(); 63 | 64 | loginButton = new JButton(new LoginAction()); 65 | loginButton.setText("Connect"); 66 | quitButton = new JButton(new LogoutAction()); 67 | quitButton.setText("Disconnect"); 68 | closeButton = new JButton(new QuitAction()); 69 | closeButton.setText("Quit"); 70 | inputText = new JTextField(30); 71 | inputText.setAction(new BroadcastAction()); 72 | area = new JTextArea(10, 50); 73 | area.setLineWrap(true); 74 | area.setEditable(false); 75 | scroll = new JScrollBar(); 76 | scroll.add(area); 77 | nameField = new JTextField(10); 78 | nameField.setEditable(false); 79 | serverField = new JTextField(10); 80 | serverField.setEditable(false); 81 | 82 | JPanel h = new JPanel(); 83 | h.setLayout(new BoxLayout(h, BoxLayout.LINE_AXIS)); 84 | h.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); 85 | JLabel nameLabel = new JLabel("Name: "); 86 | JLabel serverLabel = new JLabel("Server: "); 87 | h.add(nameLabel); 88 | h.add(Box.createRigidArea(new Dimension(10, 0))); 89 | h.add(nameField); 90 | h.add(Box.createRigidArea(new Dimension(10, 0))); 91 | h.add(Box.createHorizontalGlue()); 92 | h.add(Box.createRigidArea(new Dimension(10, 0))); 93 | h.add(serverLabel); 94 | h.add(Box.createRigidArea(new Dimension(10, 0))); 95 | h.add(serverField); 96 | 97 | JPanel p = new JPanel(); 98 | p.setLayout(new BoxLayout(p, BoxLayout.LINE_AXIS)); 99 | p.setBorder(new EmptyBorder(10, 10, 10, 10)); 100 | 101 | JPanel left = new JPanel(); 102 | left.setLayout(new BoxLayout(left, BoxLayout.PAGE_AXIS)); 103 | left.add(area); 104 | left.add(Box.createRigidArea(new Dimension(0, 5))); 105 | left.add(Box.createHorizontalGlue()); 106 | left.add(inputText); 107 | 108 | JPanel right = new JPanel(); 109 | right.setLayout(new BoxLayout(right, BoxLayout.PAGE_AXIS)); 110 | right.add(loginButton); 111 | right.add(Box.createRigidArea(new Dimension(0, 5))); 112 | right.add(quitButton); 113 | right.add(Box.createHorizontalGlue()); 114 | right.add(Box.createRigidArea(new Dimension(0, 25))); 115 | right.add(closeButton); 116 | 117 | p.add(left); 118 | p.add(Box.createRigidArea(new Dimension(10, 0))); 119 | p.add(right); 120 | 121 | getContentPane().add(h, BorderLayout.NORTH); 122 | getContentPane().add(p); 123 | 124 | closeButton.addActionListener(new ActionListener() { 125 | public void actionPerformed(ActionEvent e) { 126 | client.quit(); 127 | connector.dispose(); 128 | dispose(); 129 | } 130 | }); 131 | setLoggedOut(); 132 | setDefaultCloseOperation(EXIT_ON_CLOSE); 133 | } 134 | 135 | public class LoginAction extends AbstractAction { 136 | private static final long serialVersionUID = 3596719854773863244L; 137 | 138 | public void actionPerformed(ActionEvent e) { 139 | 140 | ConnectDialog dialog = new ConnectDialog(SwingChatClient.this); 141 | dialog.pack(); 142 | dialog.setVisible(true); 143 | 144 | if (dialog.isCancelled()) { 145 | return; 146 | } 147 | 148 | SocketAddress address = parseSocketAddress(dialog 149 | .getServerAddress()); 150 | String name = dialog.getUsername(); 151 | 152 | handler = new SwingChatClientHandler(SwingChatClient.this); 153 | client = new ChatClientSupport(name, handler); 154 | nameField.setText(name); 155 | serverField.setText(dialog.getServerAddress()); 156 | 157 | if (!client.connect(connector, address, dialog.isUseSsl())) { 158 | JOptionPane.showMessageDialog(SwingChatClient.this, 159 | "Could not connect to " + dialog.getServerAddress() 160 | + ". "); 161 | } 162 | } 163 | } 164 | 165 | private class LogoutAction extends AbstractAction { 166 | private static final long serialVersionUID = 1655297424639924560L; 167 | 168 | public void actionPerformed(ActionEvent e) { 169 | try { 170 | client.quit(); 171 | setLoggedOut(); 172 | } catch (Exception e1) { 173 | JOptionPane.showMessageDialog(SwingChatClient.this, 174 | "Session could not be closed."); 175 | } 176 | } 177 | } 178 | 179 | private class BroadcastAction extends AbstractAction { 180 | /** 181 | * 182 | */ 183 | private static final long serialVersionUID = -6276019615521905411L; 184 | 185 | public void actionPerformed(ActionEvent e) { 186 | client.broadcast(inputText.getText()); 187 | inputText.setText(""); 188 | } 189 | } 190 | 191 | private class QuitAction extends AbstractAction { 192 | private static final long serialVersionUID = -6389802816912005370L; 193 | 194 | public void actionPerformed(ActionEvent e) { 195 | if (client != null) { 196 | client.quit(); 197 | } 198 | SwingChatClient.this.dispose(); 199 | } 200 | } 201 | 202 | private void setLoggedOut() { 203 | inputText.setEnabled(false); 204 | quitButton.setEnabled(false); 205 | loginButton.setEnabled(true); 206 | } 207 | 208 | private void setLoggedIn() { 209 | area.setText(""); 210 | inputText.setEnabled(true); 211 | quitButton.setEnabled(true); 212 | loginButton.setEnabled(false); 213 | } 214 | 215 | private void append(String text) { 216 | area.append(text); 217 | } 218 | 219 | private void notifyError(String message) { 220 | JOptionPane.showMessageDialog(this, message); 221 | } 222 | 223 | private SocketAddress parseSocketAddress(String s) { 224 | s = s.trim(); 225 | int colonIndex = s.indexOf(":"); 226 | if (colonIndex > 0) { 227 | String host = s.substring(0, colonIndex); 228 | int port = parsePort(s.substring(colonIndex + 1)); 229 | return new InetSocketAddress(host, port); 230 | } else { 231 | int port = parsePort(s.substring(colonIndex + 1)); 232 | return new InetSocketAddress(port); 233 | } 234 | } 235 | 236 | private int parsePort(String s) { 237 | try { 238 | return Integer.parseInt(s); 239 | } catch (NumberFormatException nfe) { 240 | throw new IllegalArgumentException("Illegal port number: " + s); 241 | } 242 | } 243 | 244 | public void connected() { 245 | } 246 | 247 | public void disconnected() { 248 | append("Connection closed.\n"); 249 | setLoggedOut(); 250 | } 251 | 252 | public void error(String message) { 253 | notifyError(message + "\n"); 254 | } 255 | 256 | public void loggedIn() { 257 | setLoggedIn(); 258 | append("You have joined the chat session.\n"); 259 | } 260 | 261 | public void loggedOut() { 262 | append("You have left the chat session.\n"); 263 | setLoggedOut(); 264 | } 265 | 266 | public void messageReceived(String message) { 267 | append(message + "\n"); 268 | } 269 | 270 | public static void main(String[] args) { 271 | SwingChatClient client = new SwingChatClient(); 272 | client.pack(); 273 | client.setVisible(true); 274 | } 275 | } 276 | -------------------------------------------------------------------------------- /mina2-demos/src/main/java/com/waylau/mina/demo/imagine/client/GraphicalCharGenClient.java: -------------------------------------------------------------------------------- 1 | package com.waylau.mina.demo.imagine.client; 2 | 3 | import java.awt.Color; 4 | import java.awt.Container; 5 | import java.awt.Dimension; 6 | import java.awt.GridBagConstraints; 7 | import java.awt.GridBagLayout; 8 | import java.awt.Insets; 9 | import java.awt.Rectangle; 10 | import java.awt.event.ActionEvent; 11 | import java.awt.event.ActionListener; 12 | import java.awt.image.BufferedImage; 13 | 14 | import javax.swing.JButton; 15 | import javax.swing.JCheckBox; 16 | import javax.swing.JFrame; 17 | import javax.swing.JLabel; 18 | import javax.swing.JOptionPane; 19 | import javax.swing.JSpinner; 20 | import javax.swing.JTextField; 21 | import javax.swing.SpinnerNumberModel; 22 | import javax.swing.UIManager; 23 | import javax.swing.WindowConstants; 24 | 25 | import com.waylau.mina.demo.imagine.ImageRequest; 26 | 27 | /** 28 | * Swing application that acts as a client of the {@link ImageServer} 29 | * 30 | * @author waylau.com 31 | * @date 2015-2-26 32 | */ 33 | public class GraphicalCharGenClient extends JFrame implements ImageListener { 34 | 35 | private static final long serialVersionUID = 1L; 36 | 37 | public static final int PORT = 33789; 38 | public static final String HOST = "localhost"; 39 | 40 | public GraphicalCharGenClient() { 41 | initComponents(); 42 | jSpinnerHeight.setModel(spinnerHeightModel); 43 | jSpinnerWidth.setModel(spinnerWidthModel); 44 | jSpinnerChars.setModel(spinnerCharsModel); 45 | jTextFieldHost.setText(HOST); 46 | jTextFieldPort.setText(String.valueOf(PORT)); 47 | setTitle(""); 48 | } 49 | 50 | private void jButtonConnectActionPerformed() { 51 | try { 52 | setTitle("connecting..."); 53 | String host = jTextFieldHost.getText(); 54 | int port = Integer.valueOf(jTextFieldPort.getText()); 55 | if (imageClient != null) { 56 | imageClient.disconnect(); 57 | } 58 | imageClient = new ImageClient(host, port, this); 59 | imageClient.connect(); 60 | jButtonConnect.setEnabled(!imageClient.isConnected()); 61 | } catch (NumberFormatException e) { 62 | onException(e); 63 | } catch (IllegalArgumentException e) { 64 | onException(e); 65 | } 66 | } 67 | 68 | private void jButtonDisconnectActionPerformed() { 69 | setTitle("disconnecting"); 70 | imageClient.disconnect(); 71 | } 72 | 73 | private void jButtonSendRequestActionPerformed() { 74 | sendRequest(); 75 | } 76 | 77 | private void sendRequest() { 78 | int chars = spinnerCharsModel.getNumber().intValue(); 79 | int height = spinnerHeightModel.getNumber().intValue(); 80 | int width = spinnerWidthModel.getNumber().intValue(); 81 | imageClient.sendRequest(new ImageRequest(width, height, chars)); 82 | } 83 | 84 | public void onImages(BufferedImage image1, BufferedImage image2) { 85 | if (checkBoxContinuous.isSelected()) { 86 | // already request next image 87 | sendRequest(); 88 | } 89 | imagePanel1.setImages(image1, image2); 90 | } 91 | 92 | public void onException(Throwable throwable) { 93 | Throwable cause = throwable; 94 | while (cause.getCause() != null) { 95 | cause = cause.getCause(); 96 | } 97 | JOptionPane.showMessageDialog( 98 | this, 99 | cause.getMessage(), 100 | throwable.getMessage(), 101 | JOptionPane.ERROR_MESSAGE); 102 | setTitle(""); 103 | jButtonConnect.setEnabled(!imageClient.isConnected()); 104 | jButtonDisconnect.setEnabled(imageClient.isConnected()); 105 | } 106 | 107 | public void sessionOpened() { 108 | jButtonDisconnect.setEnabled(true); 109 | jButtonSendRequest.setEnabled(true); 110 | jButtonConnect.setEnabled(false); 111 | setTitle("connected"); 112 | } 113 | 114 | public void sessionClosed() { 115 | jButtonDisconnect.setEnabled(false); 116 | jButtonSendRequest.setEnabled(false); 117 | jButtonConnect.setEnabled(true); 118 | setTitle("not connected"); 119 | } 120 | 121 | @Override 122 | public void setTitle(String title) { 123 | super.setTitle("MINA - Chargen client - " + title); 124 | } 125 | 126 | 127 | private void initComponents() { 128 | JLabel jLabel1 = new JLabel(); 129 | jTextFieldHost = new JTextField(); 130 | jButtonConnect = new JButton(); 131 | JLabel jLabel3 = new JLabel(); 132 | jSpinnerWidth = new JSpinner(); 133 | JLabel label5 = new JLabel(); 134 | jSpinnerChars = new JSpinner(); 135 | checkBoxContinuous = new JCheckBox(); 136 | JLabel jLabel2 = new JLabel(); 137 | jTextFieldPort = new JTextField(); 138 | jButtonDisconnect = new JButton(); 139 | JLabel jLabel4 = new JLabel(); 140 | jSpinnerHeight = new JSpinner(); 141 | jButtonSendRequest = new JButton(); 142 | imagePanel1 = new ImagePanel(); 143 | 144 | //======== this ======== 145 | setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 146 | setMinimumSize(new Dimension(700, 300)); 147 | setPreferredSize(new Dimension(740, 600)); 148 | Container contentPane = getContentPane(); 149 | contentPane.setLayout(new GridBagLayout()); 150 | ((GridBagLayout) contentPane.getLayout()).columnWidths = new int[]{36, 167, 99, 41, 66, 75, 57, 96, 0, 0}; 151 | ((GridBagLayout) contentPane.getLayout()).rowHeights = new int[]{10, 31, 31, 256, 0}; 152 | ((GridBagLayout) contentPane.getLayout()).columnWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0E-4}; 153 | ((GridBagLayout) contentPane.getLayout()).rowWeights = new double[]{0.0, 0.0, 0.0, 1.0, 1.0E-4}; 154 | 155 | //---- jLabel1 ---- 156 | jLabel1.setText("Host"); 157 | contentPane.add(jLabel1, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, 158 | GridBagConstraints.CENTER, GridBagConstraints.BOTH, 159 | new Insets(0, 5, 5, 5), 0, 0)); 160 | contentPane.add(jTextFieldHost, new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0, 161 | GridBagConstraints.CENTER, GridBagConstraints.BOTH, 162 | new Insets(0, 5, 5, 10), 0, 0)); 163 | 164 | //---- jButtonConnect ---- 165 | jButtonConnect.setText("Connect"); 166 | jButtonConnect.addActionListener(new ActionListener() { 167 | public void actionPerformed(ActionEvent e) { 168 | jButtonConnectActionPerformed(); 169 | } 170 | }); 171 | contentPane.add(jButtonConnect, new GridBagConstraints(2, 1, 1, 1, 0.0, 0.0, 172 | GridBagConstraints.CENTER, GridBagConstraints.BOTH, 173 | new Insets(0, 5, 5, 10), 0, 0)); 174 | 175 | //---- jLabel3 ---- 176 | jLabel3.setText("Width"); 177 | contentPane.add(jLabel3, new GridBagConstraints(3, 1, 1, 1, 0.0, 0.0, 178 | GridBagConstraints.CENTER, GridBagConstraints.BOTH, 179 | new Insets(0, 0, 5, 5), 0, 0)); 180 | contentPane.add(jSpinnerWidth, new GridBagConstraints(4, 1, 1, 1, 0.0, 0.0, 181 | GridBagConstraints.CENTER, GridBagConstraints.BOTH, 182 | new Insets(0, 5, 5, 10), 0, 0)); 183 | 184 | //---- label5 ---- 185 | label5.setText("characters"); 186 | contentPane.add(label5, new GridBagConstraints(5, 1, 1, 1, 0.0, 0.0, 187 | GridBagConstraints.EAST, GridBagConstraints.VERTICAL, 188 | new Insets(0, 0, 5, 5), 0, 0)); 189 | contentPane.add(jSpinnerChars, new GridBagConstraints(6, 1, 1, 1, 0.0, 0.0, 190 | GridBagConstraints.CENTER, GridBagConstraints.BOTH, 191 | new Insets(0, 0, 5, 10), 0, 0)); 192 | 193 | //---- checkBoxContinuous ---- 194 | checkBoxContinuous.setText("continuous"); 195 | contentPane.add(checkBoxContinuous, new GridBagConstraints(7, 1, 1, 1, 0.0, 0.0, 196 | GridBagConstraints.CENTER, GridBagConstraints.BOTH, 197 | new Insets(0, 5, 5, 10), 0, 0)); 198 | 199 | //---- jLabel2 ---- 200 | jLabel2.setText("Port"); 201 | contentPane.add(jLabel2, new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0, 202 | GridBagConstraints.CENTER, GridBagConstraints.BOTH, 203 | new Insets(0, 5, 5, 5), 0, 0)); 204 | contentPane.add(jTextFieldPort, new GridBagConstraints(1, 2, 1, 1, 0.0, 0.0, 205 | GridBagConstraints.CENTER, GridBagConstraints.BOTH, 206 | new Insets(0, 5, 5, 10), 0, 0)); 207 | 208 | //---- jButtonDisconnect ---- 209 | jButtonDisconnect.setText("Disconnect"); 210 | jButtonDisconnect.setEnabled(false); 211 | jButtonDisconnect.addActionListener(new ActionListener() { 212 | public void actionPerformed(ActionEvent e) { 213 | jButtonDisconnectActionPerformed(); 214 | } 215 | }); 216 | contentPane.add(jButtonDisconnect, new GridBagConstraints(2, 2, 1, 1, 0.0, 0.0, 217 | GridBagConstraints.CENTER, GridBagConstraints.BOTH, 218 | new Insets(0, 5, 5, 10), 0, 0)); 219 | 220 | //---- jLabel4 ---- 221 | jLabel4.setText("Height"); 222 | contentPane.add(jLabel4, new GridBagConstraints(3, 2, 1, 1, 0.0, 0.0, 223 | GridBagConstraints.CENTER, GridBagConstraints.BOTH, 224 | new Insets(0, 0, 5, 5), 0, 0)); 225 | contentPane.add(jSpinnerHeight, new GridBagConstraints(4, 2, 1, 1, 0.0, 0.0, 226 | GridBagConstraints.CENTER, GridBagConstraints.BOTH, 227 | new Insets(0, 5, 5, 10), 0, 0)); 228 | 229 | //---- jButtonSendRequest ---- 230 | jButtonSendRequest.setText("Send Request"); 231 | jButtonSendRequest.setEnabled(false); 232 | jButtonSendRequest.addActionListener(new ActionListener() { 233 | public void actionPerformed(ActionEvent e) { 234 | jButtonSendRequestActionPerformed(); 235 | } 236 | }); 237 | contentPane.add(jButtonSendRequest, new GridBagConstraints(5, 2, 2, 1, 0.0, 0.0, 238 | GridBagConstraints.CENTER, GridBagConstraints.BOTH, 239 | new Insets(0, 5, 5, 10), 0, 0)); 240 | 241 | //======== imagePanel1 ======== 242 | { 243 | imagePanel1.setBackground(new Color(51, 153, 255)); 244 | imagePanel1.setPreferredSize(new Dimension(500, 500)); 245 | 246 | { // compute preferred size 247 | Dimension preferredSize = new Dimension(); 248 | for (int i = 0; i < imagePanel1.getComponentCount(); i++) { 249 | Rectangle bounds = imagePanel1.getComponent(i).getBounds(); 250 | preferredSize.width = Math.max(bounds.x + bounds.width, preferredSize.width); 251 | preferredSize.height = Math.max(bounds.y + bounds.height, preferredSize.height); 252 | } 253 | Insets insets = imagePanel1.getInsets(); 254 | preferredSize.width += insets.right; 255 | preferredSize.height += insets.bottom; 256 | imagePanel1.setMinimumSize(preferredSize); 257 | imagePanel1.setPreferredSize(preferredSize); 258 | } 259 | } 260 | contentPane.add(imagePanel1, new GridBagConstraints(0, 3, 9, 1, 0.0, 0.0, 261 | GridBagConstraints.CENTER, GridBagConstraints.BOTH, 262 | new Insets(8, 5, 8, 5), 0, 0)); 263 | pack(); 264 | setLocationRelativeTo(getOwner()); 265 | } 266 | 267 | /** 268 | * @param args the command line arguments 269 | */ 270 | public static void main(String args[]) { 271 | try { 272 | UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 273 | } catch (Exception e) { 274 | // ignore 275 | } 276 | java.awt.EventQueue.invokeLater(new Runnable() { 277 | public void run() { 278 | new GraphicalCharGenClient().setVisible(true); 279 | } 280 | }); 281 | } 282 | 283 | private JTextField jTextFieldHost; 284 | private JButton jButtonConnect; 285 | private JSpinner jSpinnerWidth; 286 | private JSpinner jSpinnerChars; 287 | private JCheckBox checkBoxContinuous; 288 | private JTextField jTextFieldPort; 289 | private JButton jButtonDisconnect; 290 | private JSpinner jSpinnerHeight; 291 | private JButton jButtonSendRequest; 292 | private ImagePanel imagePanel1; 293 | 294 | private SpinnerNumberModel spinnerHeightModel = new SpinnerNumberModel(100, 50, 600, 25); 295 | private SpinnerNumberModel spinnerWidthModel = new SpinnerNumberModel(200, 50, 1000, 25); 296 | private SpinnerNumberModel spinnerCharsModel = new SpinnerNumberModel(10, 1, 60, 1); 297 | 298 | private ImageClient imageClient = new ImageClient(HOST, PORT, this); 299 | } 300 | --------------------------------------------------------------------------------