├── .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 |
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 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
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 |
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 |
--------------------------------------------------------------------------------