mina的小demo

最近很无聊,找些新玩意玩玩,正好看到了mina的介绍,下了2.0M5的zip,看看example,再查查资料,写了下面的列子,虽然简单,但是问题还真不少,好在快下班的时候搞定了,留个纪念,有空再扩展.

看名字就知道是啥,看人家的命名,真不是盖得.

唯一一点要注意的就是session在关闭时的参数,如果有数据没有flush,可能就是报错.如果有多个地方同时关闭,可能会死锁...

package com.hcycom.lan;

import java.net.InetSocketAddress;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;

public class ServerHandler extends IoHandlerAdapter {

	@Override
	public void exceptionCaught(IoSession session, Throwable cause)
			throws Exception {
		cause.printStackTrace();
		session.close(false);
	}

	@Override
	public void messageReceived(IoSession session, Object message)
			throws Exception {
		String s = message.toString();
		System.out.println("收到请求:" + s);
		if (s != null) {
			int i = getPoint(s);
			if (session.isConnected()) {
				if (i >= 95) {
					session.write("运气不错,你可以出去了.");
					session.close(false);
					return;
				}
				Integer count = (Integer) session.getAttribute(Server.KEY);
				count++;
				session.setAttribute(Server.KEY, count);
				session.write("抱歉,你运气太差了,第" + count + "次请求未被通过,继续在小黑屋里呆着吧.");
			} else {
				session.close(true);
			}
		}
	}

	@Override
	public void messageSent(IoSession session, Object message) throws Exception {
		System.out.println("发给客户端: " + message.toString());
	}

	@Override
	public void sessionClosed(IoSession session) throws Exception {
		long l = session.getCreationTime();
		System.out.println("来自" + getInfo(session) + "的会话已经关闭,它已经存活了 "
				+ (System.currentTimeMillis() - l) + "毫秒.");
	}

	@Override
	public void sessionCreated(IoSession session) throws Exception {
		System.out.println("给" + getInfo(session) + "创建了一个新会话.");
	}

	@Override
	public void sessionIdle(IoSession session, IdleStatus status)
			throws Exception {
		System.out.println("来自" + getInfo(session) + "的会话在闲置,状态为"
				+ status.toString());
	}

	@Override
	public void sessionOpened(IoSession session) throws Exception {
		session.setAttribute(Server.KEY, 0);
		System.out.println("和" + getInfo(session) + "的会话已经打开.");
	}

	public String getInfo(IoSession session) {
		if (session == null) {
			return null;
		}
		InetSocketAddress address = (InetSocketAddress) session
				.getRemoteAddress();
		int port = address.getPort();
		String ip = address.getAddress().getHostAddress();
		return ip + ":" + port;
	}

	public int getPoint(String s) {
		if (s == null) {
			return -1;
		}
		Pattern p = Pattern.compile("^[\u0041-\uFFFF,]*(\\d+).*$");
		Matcher m = p.matcher(s);
		if (m.matches()) {
			return Integer.valueOf(m.group(1));
		}
		return 0;
	}

}

  客户端,直接继承了HandlerAdapter,不需要写啥太复杂的东西

package com.hcycom.lan;

import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.util.Random;

import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.future.IoFutureListener;
import org.apache.mina.core.service.IoConnector;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketConnector;

public class Client extends IoHandlerAdapter {
	private Random random = new Random(System.currentTimeMillis());

	public Client() {
		IoConnector connector = new NioSocketConnector();
		connector.getFilterChain().addLast(
				"text",
				new ProtocolCodecFilter(new TextLineCodecFactory(Charset
						.forName(Server.ENCODE))));
		connector.setHandler(this);
		ConnectFuture future = connector.connect(new InetSocketAddress(
				"127.0.0.1", Server.PORT));
		future.awaitUninterruptibly();
		future.addListener(new IoFutureListener<ConnectFuture>() {

			@Override
			public void operationComplete(ConnectFuture future) {
				IoSession session = future.getSession();
				while (!session.isClosing()) {
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					String message = "你好,我roll了" + random.nextInt(100) + "点.";
					session.write(message);
				}
			}
		});
		connector.dispose();
	}

	@Override
	public void messageReceived(IoSession session, Object message)
			throws Exception {
		System.out.println("批复:" + message.toString());
	}

	@Override
	public void messageSent(IoSession session, Object message) throws Exception {
		System.out.println("报告:" + message.toString());
	}

	@Override
	public void exceptionCaught(IoSession session, Throwable cause)
			throws Exception {
		cause.printStackTrace();
		session.close(true);
	}

	public static void main(String[] args) {
		for (int i = 0; i < 10; i++) {
			new Client();
		}
	}
}

 server端,更简单,就是要注意filter,客户端要和服务器端一致,这里用的是传字符串的,mina实现了很多filter,包括传对象的,有空再玩.

package com.hcycom.lan;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;

import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.transport.socket.SocketAcceptor;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;

public class Server {

	public static final int PORT = 2534;
	public static final String ENCODE = "UTF-8";
	public static final String KEY = "roll";

	public static void main(String[] args) {
		SocketAcceptor acceptor = new NioSocketAcceptor();
		acceptor.getFilterChain().addLast(
				"text",
				new ProtocolCodecFilter(new TextLineCodecFactory(Charset
						.forName(ENCODE))));
		acceptor.setHandler(new ServerHandler());
		try {
			acceptor.bind(new InetSocketAddress(PORT));
			System.out.println("游戏开始,你想出去吗,来,碰碰运气吧!");
		} catch (IOException e) {
			e.printStackTrace();
			acceptor.dispose();
		}
	}
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值