Mina入门实例(一)

mina现在用的很多了,之前也有用到,但是毕竟不熟悉,于是查了一些资料,做了一些总结。看代码是最直观的,比什么长篇大论都要好。不过其中重要的理论,也要理解下。

首先是环境,程序运行需要几个包,这里用maven比较方便。

pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>MyMinaServer</groupId>
  <artifactId>mina</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>mina</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
      <dependency>
            <groupId>org.apache.mina</groupId>
            <artifactId>mina-core</artifactId>
            <version>2.0.4</version>
        </dependency>  

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>1.6.1</version>
        </dependency>  

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-nop</artifactId>
            <version>1.6.1</version>
        </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

然后就可以写代码了。

---------------------------------------------------------- 分割线 -----------------------------------------------------------------------------------------

一,简单的客户端和服务端程序

服务端程序:

package MyMinaServer.mina;

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

import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;

public class MainServer {
    private static final int Port=8888;
    public static void main(String[] args) {
        IoAcceptor ioAcceptor=new NioSocketAcceptor();
        System.out.println("begin server....");
        ioAcceptor.getFilterChain().addLast("logger", new LoggingFilter());
        ioAcceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));
        ioAcceptor.setHandler(new HelloWorldHandler());
        ioAcceptor.getSessionConfig().setReadBufferSize(2048);
        ioAcceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
        try {
            ioAcceptor.bind(new InetSocketAddress(Port));
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

服务端,创建连接,然后这里注册了几个过滤链,这里简单写了需要的两个,到后面的内容中还可以加入一个加密的ssl链。

其中重要的是setHandler这个,在这个里面,我们可以定义自己的handler,然后做自己的业务。下面有这个handler的简单代码。

最后设置session的缓冲,和idle(空闲处理)的设定,再为此连接绑定一个端口。

其中需要注意的是,在服务端和客户端的代码里面,如果要传递string信息,codec编码过滤器中,要这么写:new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8")))。否则报错。

业务处理的handler:

package MyMinaServer.mina;

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

public class HelloWorldHandler extends IoHandlerAdapter{

    @Override
    public void exceptionCaught(IoSession session, Throwable cause)
            throws Exception {
        // TODO Auto-generated method stub
        super.exceptionCaught(session, cause);
    }

    @Override
    public void messageReceived(IoSession session, Object message)
            throws Exception {
        // TODO Auto-generated method stub
        String string=message.toString();
        if (string.trim().equalsIgnoreCase("quit")) {
            session.close(true);
            return;
        }
        System.out.println("recevied message:"+string);
        String reply=" hi, i am server";
        session.write(reply);
        System.out.println("message have been written");
    }

    @Override
    public void messageSent(IoSession session, Object message) throws Exception {
        // TODO Auto-generated method stub
        System.out.println("message have been sent");
    }

    @Override
    public void sessionClosed(IoSession session) throws Exception {
        // TODO Auto-generated method stub
        System.out.println("closed session");
    }

    @Override
    public void sessionCreated(IoSession session) throws Exception {
        // TODO Auto-generated method stub
        System.out.println("session created");
    }

    @Override
    public void sessionIdle(IoSession session, IdleStatus status)
            throws Exception {
        // TODO Auto-generated method stub
        System.out.println("IDLE "+session.getIdleCount(status));
    }

    @Override
    public void sessionOpened(IoSession session) throws Exception {
        // TODO Auto-generated method stub
        System.out.println("session opened");
    }

}

这里的每个方法,算是事件。在每个事件中,我们可以定义自己的处理。在前面的《AndroidPn源码分析(一)》这篇文章中,笔者曾写过他们的每个事件代表的含义,不过从字面意思也很好理解。

这里主要是对接受到信息的处理,如果不是收到quit字符,则返回给客户端一句 hi,i am server。

服务端暂时到此,以下是客户端。

package com.example.mina.server;

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

import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.core.future.CloseFuture;
import org.apache.mina.core.future.ConnectFuture;
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.filter.logging.LoggingFilter;import org.apache.mina.transport.socket.SocketConnector;
import org.apache.mina.transport.socket.nio.NioSocketConnector;

import com.example.mina.charset.CharsetFactory;
import com.example.mina.hanlder.MsgHanler;public class MinaClient {

    private SocketConnector connector;
    private ConnectFuture future;
    private IoSession session;

    public boolean connect() {
        /*
         * 1.创建一个socket连接,连接到服务器
         */
        connector = new NioSocketConnector();

        /*
         * 获取过滤器链,用于添加过滤器
         */
        DefaultIoFilterChainBuilder chain = connector.getFilterChain();

        // b.添加日志过滤器
        chain.addLast("logger", new LoggingFilter());

        // c.添加字符的编码过滤器
        chain.addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));

        /*
         * 3.设置消息处理器,用于处理接收到的消息
         */
        connector.setHandler(new MsgHanler());

        /*
         * 4.根据IP和端口号连接到服务器
         */
        future = connector.connect(new InetSocketAddress("127.0.0.1", 8888));
        // 等待连接创建完成
        future.awaitUninterruptibly();

        /*
         * 5.获取session对象,通过session可以向服务器发送消息;
         */
        session = future.getSession();
        session.getConfig().setUseReadOperation(true);
        return future.isConnected();
    }

    /**
     * 往服务器发送消息
     *
     * @param message
     */
    public void sendMsg2Server(String message) {
        session.write(message);
    }

    /**
     * 关闭与服务器的连接
     *
     * @return
     */
    public boolean close() {
        CloseFuture future = session.getCloseFuture();
        future.awaitUninterruptibly(1000);
        connector.dispose();
        return true;
    }
}

然后同样是一个客户端的handler,和server的很像:

package com.example.mina.hanlder;

import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MsgHanler extends IoHandlerAdapter {
    private static final Logger log = LoggerFactory.getLogger(MsgHanler.class);

    @Override
    public void exceptionCaught(IoSession session, Throwable cause)
            throws Exception {
        // 出现异常
        log.error("--------exception--------");
        super.exceptionCaught(session, cause);
    }

    @Override
    public void messageReceived(IoSession session, Object message)
            throws Exception {
        // 从服务器中接收到消息后的处理
        log.info("--------msg receive--------");
        log.info("Message:{}" + message.toString());
        super.messageReceived(session, message);
    }

    @Override
    public void messageSent(IoSession session, Object message) throws Exception {
        // 往服务器中发送消息
        log.info("--------msg sent--------");
        super.messageSent(session, message);
    }

    @Override
    public void sessionCreated(IoSession session) throws Exception {
        // 当session被创建的时候调用
        log.info("--------session create--------");
        super.sessionCreated(session);
    }
}

写一个入口方法:

package com.example.mina.server;

public class Main {

    public static void main(String[] args) {
        MinaClient client=new MinaClient();
        client.connect();
        client.sendMsg2Server("message from cilent");
    }
}

这样,客户端就可以工作了。

先启动服务端,然后启动客户端,就可以看到在两个控制台中,分别有交互信息。

服务端:

begin server....
session created
session opened
recevied message:message from cilent
message have been written
message have been sent

客户端:

[QC] INFO [NioProcessor-2] org.apache.mina.filter.logging.LoggingFilter.log(186) | CREATED
[QC] INFO [NioProcessor-2] com.example.mina.hanlder.MsgHanler.sessionCreated(54) | --------session create--------
[QC] INFO [NioProcessor-2] org.apache.mina.filter.logging.LoggingFilter.log(186) | OPENED
[QC] INFO [NioProcessor-2] org.apache.mina.filter.logging.LoggingFilter.log(157) | SENT: HeapBuffer[pos=0 lim=0 cap=0: empty]
[QC] INFO [NioProcessor-2] com.example.mina.hanlder.MsgHanler.messageSent(47) | --------msg sent--------
[QC] INFO [NioProcessor-2] org.apache.mina.filter.logging.LoggingFilter.log(157) | RECEIVED: HeapBuffer[pos=0 lim=17 cap=2048: 20 68 69 2C 20 69 20 61 6D 20 73 65 72 76 65 72...]
[QC] INFO [NioProcessor-2] com.example.mina.hanlder.MsgHanler.messageReceived(39) | --------msg receive--------
[QC] INFO [NioProcessor-2] com.example.mina.hanlder.MsgHanler.messageReceived(40) | Message:{} hi, i am server

客户端因为用了log4j,打印比较多信息。

到此,这个例子就完成了。

时间: 2024-10-16 15:52:09

Mina入门实例(一)的相关文章

Apache Mina 入门实例

这个教程是介绍使用Mina搭建基础示例.这个教程内容是以创建一个时间服务器. 以下是这个教程需要准备的东西: MINA 2.0.7 Core JDK 1.5 或更高 SLF4J 1.3.0 或更高 Log4J 1.2 用户: slf4j-api.jar, slf4j-log4j12.jar, 和Log4J 1.2.x Log4J 1.3 用户: slf4j-api.jar, slf4j-log4j13.jar, 和Log4J 1.3.x java.util.logging 用户: slf4j-a

Mina入门实例

继续上一篇,这篇主要讲通过mina往B端发送消息,并接受消息,mina是一个网络通信框架,封装了javaNIO,简单易用,网上有非常多关于他的介绍.在此不赘述了. 如上篇所介绍.完毕功能,须要五个类: PoolListener:监听.用来在系统启动的时候创建连接: SessionPool:连接池: SendHandler:处理类. CharsetEncoder:编码: CharsetDecoder:解码: B为我们提供了6个port,每一个port可建立3个长连接,因此.在系统时.就要创建长连接

JAVA通信系列二:mina入门总结

一.学习资料 Mina入门实例(一) http://www.cnblogs.com/juepei/p/3939119.html Mina入门教程(二)----Spring4 集成Mina http://www.cnblogs.com/juepei/p/3940396.html Apache Mina 入门实例--创建一个MINA时间服务http://loftor.com/archives/apache-mina-quick-start-guide.html MINA2.0用户手册中文版--系列文

DWR之入门实例(一)

DWR(Direct Web Remoting)是一个WEB远程调用框架.利用这个框架可以让AJAX开发变得很简单.利用DWR可以在客户端利用JavaScript直接调用服务端的Java方法并返回值给JavaScript就好像直接本地客户端调用一样(DWR根据Java类来动态生成JavaScrip代码).它的最新版本DWR0.6添加许多特性如:支持Dom Trees的自动配置,支持Spring(JavaScript远程调用spring bean),更好浏览器支持,还支持一个可选的commons-

React 入门实例教程

React 入门实例教程 作者: 阮一峰 日期: 2015年3月31日 现在最热门的前端框架,毫无疑问是 React . 上周,基于 React 的 React Native 发布,结果一天之内,就获得了 5000 颗星,受瞩目程度可见一斑. React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设 Instagram 的网站.做出来以后,发现这套东西很好用,就在2013年5月开源了. 由于 React 的

Java AIO 入门实例(转)

Java7 AIO入门实例,首先是服务端实现: 服务端代码 SimpleServer: Java代码   public class SimpleServer { public SimpleServer(int port) throws IOException { final AsynchronousServerSocketChannel listener = AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(por

FPGA入门实例一:LFSR

一:任务: 要求使用Verilog语言在Xilinx Virtex-6开发板上实现线性反馈移位寄存器(LFSR)的硬件逻辑设计. 二:前期准备: 基本上完成一个简单的设计需要用到以下几个软件 逻辑:Uedit32(硬件狗吐血推荐) 综合:ISE14.1 仿真:Modelsim SE 10.1b 分析:Chipscope Pro 三:设计流程 逻辑: 首先当然是RTL级设计,俗称硬件逻辑设计.使用的是Uedit32,这个软件相当于一个记事本,但编辑功能十分强大,简直是写Verilog代码的神器,具

php页面get方法实现ajax,入门实例教程

ajax,入门实例教程 本例针对php页面,做了一个小的demo加深对ajax的理解 1.文档结构: 共有ajax.php 和action.php 2个页面. 2.源码如下: /*ajax.php页面*/<!DOCTYPE html> <html lang="en"> <head> <title> ajax</title> <script type="text/javascript"> func

Omnet++ 4.0 入门实例教程

http://blog.sina.com.cn/s/blog_8a2bb17d01018npf.html 在网上找到的一个讲解omnet++的实例, 是4.0下面实现的. 我在4.2上试了试,可以用.照着做就能完成,有些小地方不同而已 Omnet++ 4.0 入门实例教程根据http://omnest.com/webdemo/ide 上的实例,自己动手做了做.新版本的4.0 跟它视频上的版本有些差别,配图说明一下我的操作过程,供大家一起学习.现在开始.首先,开发环境选择simulation 的视