MINA 实现聊天功能

原文同步至 http://www.waylau.com/mina-chat/

在《MINA 快速入门》一文中,我们介绍了如何利用 MINA 快速构建一个 Time Server(时间服务器)。在《Netty 实现聊天功能》一文,我们也介绍了如何用 Netty 实现聊天功能。由于 MINA 和 Netty 是同一个作者,架构类似,如果你掌握其中一个,学习另外一个也不是难事。现在我们就用 MINA 来实现聊天功能。

准备

  • JDK 7+
  • Maven 3.2.x
  • MINA 2.x
  • Eclipse 4.x

服务端

让我们从 handler (处理器)的实现开始,handler 是由 MINA 生成用来处理 I/O 事件的, 处理器继承自 IoHandlerAdapter。

SimpleChatServerHandler.java

public class SimpleChatServerHandler extends IoHandlerAdapter { // (1)

    private final Set<IoSession> sessions = Collections
        .synchronizedSet(new HashSet<IoSession>()); //  (2)

    @Override
    public void sessionCreated(IoSession session) throws Exception {// (3)
        sessions.add(session);
        broadcast(" has join the chat", session);
    }

    @Override
    public void sessionClosed(IoSession session) throws Exception {// (4)
        sessions.remove(session);
        broadcast(" has left the chat", session);
    }

    @Override
    public void messageReceived(IoSession session, Object message)
            throws Exception {// (5)
        String str = message.toString();
        broadcast(str, session);
    }

    @Override
    public void sessionIdle(IoSession session, IdleStatus status)
            throws Exception {// (6)
        System.out.println("[Server] IDLE " + session.getRemoteAddress()
                + session.getIdleCount(status));
    }

    @Override
    public void exceptionCaught(IoSession session, Throwable cause) {
        cause.printStackTrace();// (7)
        System.out.println("[Server] Client:" + session.getRemoteAddress()
                + "异常");
        // 遇到未捕获的异常,则关闭连接
        session.close(true);
    }

    /**
     * 广播消息
     *
     * @param message
     */
    private void broadcast(String message, IoSession exceptSession) {// (8)
        synchronized (sessions) {
            for (IoSession session : sessions) {
                if (session.isConnected()) {
                    if (session.equals(exceptSession)) {
                        session.write("[You]" + message);
                    } else {
                        session.write("[Client" + session.getRemoteAddress()
                                + "] " + message);
                    }

                }
            }
        }
    }
}

1.SimpleChatServerHandler 继承自 IoHandlerAdapter,这个类实现了 IoHandler 接口,IoHandlerAdapter 提供了许多事件处理的接口方法,然后你可以覆盖这些方法。现在仅仅只需要继承 IoHandlerAdapter 类而不是你自己去实现接口方法。

2.Set<IoSession> sessions 用来存储所有的 连接上来的 session.

3.覆盖了 sessionCreated() 事件处理方法。每当从服务端收到新的客户端连接时,客户端的 IoSession 就存入存入 sessions 列表中,并通知列表中的其他客户端 IoSession

4.覆盖了 sessionClosed() 事件处理方法。每当从服务端收到客户端断开时,客户端的 IoSession 从 sessions 列表中,并通知列表中的其他客户端 IoSession

5.覆盖了 messageReceived() 事件处理方法。每当从服务端读到客户端写入信息时,将信息广播给其他客户端的 IoSession。

6.覆盖了 sessionIdle() 事件处理方法。服务端监听到客户端闲置情况

7.exceptionCaught() 事件处理方法是当出现 Throwable 对象才会被调用,即当 MINA 由于 IO 错误或者处理器在处理事件时抛出的异常时。在大部分情况下,捕获的异常应该被记录下来并且把关联的 IoSession 给关闭掉。然而这个方法的处理方式会在遇到不同异常的情况下有不同的实现,比如你可能想在关闭连接之前发送一个错误码的响应消息。

8.broadcast() 服务器用于广播的方法

SimpleChatServer.java

编写一个 main() 方法来启动服务端。

public class SimpleChatServer {

    public static void main(String[] args) {
        int port;
        if (args.length > 0) {
            port = Integer.parseInt(args[0]);
        } else {
            port = 8080;
        }

        SocketAcceptor acceptor = new NioSocketAcceptor(); // (1)

        acceptor.getFilterChain().addLast( "codec",
                new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" ))));      // (2)
        acceptor.setHandler(new SimpleChatServerHandler()); // (3)

        acceptor.getSessionConfig().setReadBufferSize(2048); // (4)
        acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 100);// (5)

        try {
            acceptor.bind(new InetSocketAddress(port)); // (6)
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("[Server]Listening on port " + port);
    }
}

1.NioSocketAcceptor 基于 TCP/IP 的 socket 连接。

2.ProtocolCodecFilter 是编码和解码的过滤器链,将一个连入的 ByteBuffer 转化为消息 POJO,反之亦然。而TextLineCodecFactory是 MINA 提供的一个编解码是,可以方便处理基于文本的协议。

3.设置在处理器为之前创建的 SimpleChatServerHandler。

4.会话配置,设置字节缓存大小。

5.会话配置,设置闲置时间。

6.剩下的就是绑定端口然后启动服务。这里我们在机器上默认绑定了机器所有网卡上的 8080 端口。

恭喜!你已经完成了基于 MINA 聊天服务端程序。

客户端

SimpleChatClientHandler.java

客户端的处理类比较简单,只需要将读到的信息打印出来即可

public class SimpleChatClientHandler extends IoHandlerAdapter {
    @Override
    public void messageReceived(IoSession session, Object message) {
        String str = message.toString();
        System.out.println(str);
    }
}

SimpleChatClient.java

编写一个 main() 方法来启动客户端。

public class SimpleChatClient {
    private static final long CONNECT_TIMEOUT = 30 * 1000L; // 30 秒;
    private static final String HOSTNAME = "127.0.0.1";
    private static final int PORT = 8080;
    /**
     * @param args
     */
    public static void main(String[] args) {

        NioSocketConnector connector = new NioSocketConnector(); // (1)
        connector.setConnectTimeoutMillis(CONNECT_TIMEOUT);
        connector.getFilterChain().addLast( "codec",
                new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" ))));
        connector.setHandler(new SimpleChatClientHandler());
        IoSession session;
        ConnectFuture future = connector.connect(new InetSocketAddress(
                HOSTNAME, PORT));  // (2)
        future.awaitUninterruptibly();
        session = future.getSession();

        while(true){
            try {
                BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
                session.write(in.readLine());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

1.NioSocketConnector 用于 TCP/IP 连接

2.连接到指定的服务器

运行效果

先运行 SimpleChatServer,再可以运行多个 SimpleChatClient,控制台输入文本继续测试

源码

https://github.com/waylau/apache-mina-2-user-guide-demossimplechat

参考

时间: 2024-08-06 08:10:44

MINA 实现聊天功能的相关文章

[Asp.net 开发系列之SignalR篇]专题二:使用SignalR实现酷炫端对端聊天功能

一.引言 在前一篇文章已经详细介绍了SignalR了,并且简单介绍它在Asp.net MVC 和WPF中的应用.在上篇博文介绍的都是群发消息的实现,然而,对于SignalR是为了实时聊天而生的,自然少了不像QQ一样的端对端的聊天了.本篇博文将介绍如何使用SignalR来实现类似QQ聊天的功能. 二.使用SignalR实现端对端聊天的思路 在介绍具体实现之前,我先来介绍了使用SignalR实现端对端聊天的思路.相信大家在前篇文章已经看到过Clients.All.sendMessage(name,

我们一起学习WCF 第九篇聊天功能

说到聊天,那么其实就是传输数据,把自己写的东西传给自己想发送的那么人.我总结一下传输有三种方式 1:就是我们常见的数据库传输 2:就是文件(流)传输 3:就是socket传输 今天我们说的wcf实现聊天其实是基于socket的聊天功能(QQ聊天发展到今天肯定是很牛的了,但是最初肯定也是这样的思想) 今天我先说说基于WCF聊天的原理 1:需要一个回调函数(当用户发送的时候会吧信息回调给客户端本身) 2:需要一个委托(把服务器传来的信息显示给前台) 3:需要一个触发点击事件(目的是为了触发把发送信息

安卓平台基于SIP协议实现注册,聊天功能

============问题描述============ 不涉及音频,视频发送,只要实现注册,和聊天功能就行, 网上下了sipdroid的源码,但是XML中配置的<uses-sdk android:minSdkVersion="3" android:targetSdkVersion="4"/> 这段没明白,资料里说安卓最低支持SIP协议的API level是9,但是这版本不匹配呀,有大牛指导下么 ============解决方案1============

Mina airQQ聊天 客户端篇(三)

开发工具 (FlashBuilder4.7) 程序类型(Adobe Air) Flex Air做的桌面程序,效果还挺好看的,最主要是Socket这一块,它也是异步的,并且在Flex中的事件机制比较强大(个人认为) 有改一些样式,重新看看新的效果吧: 大致的实现方式: 在WindowedApplication中包含登陆窗口和主界面,用Flex中的状态来切换,聊天窗口时Window组件,好友列表用树菜单 实现好友分组,好友上线时改成在线图标,收到消息时头像抖动,聊天显示实现图文混排,系统托盘,其它貌

Java UDP实现聊天功能代码

我以前经常写的是基于TCP的网络编程,由于TCP建立连接鼻血要经过三次握手连接,服务器端需要阻塞式等待客户端的连接.而UDP则是可以直接向目的地址的目的端口上发送数据包,由于它只负责发送出去就好,不管对方是否正确接受到与否,所以当网络性能不好时它容易出现丢包的问题.(注意:UDP是基于数据报为单位进行传输的,而TCP是一种基于流进行传输的) 但是UDP很好的模拟了我们呢平时聊天的方式,可以很好的实现连续多次发送和接受,也就是简单的QQ聊天的功能. 现在来简要介绍Java中有关UDP编程相关的类:

软件工程腾讯QQ (1)优点:聊天功能比较强大。同时提供安全登陆通道,保障了用户信息的安全性。应用的人群范围比较广 缺点:要展示的信息量太多,用户个人信息容易泄露。有一些弄虚作假通过其欺骗用户上当。 (2)有使用需要自己下载 (3)版本更新修复bug,定期更新版本

1.软件工程未来的发展方向是什么? 2.编程基础不好,我能学习好软件工程吗? 3.软件工程跟物联网之间的区别与联系是什么? 4.软件工程在现实生活中有哪些应用? 5.在软件工程的分类中,如何选择一个适合自己的? 6.软件工程的学习中最难克服的阶段是什么? 7.怎样学好软件工程? 腾讯QQ (1)优点:聊天功能比较强大.同时提供安全登陆通道,保障了用户信息的安全性.应用的人群范围比较广 缺点:要展示的信息量太多,用户个人信息容易泄露.有一些弄虚作假通过其欺骗用户上当. (2)有使用需要自己下载 (

在线聊天功能 实现中俄双语实时翻译 原创 加精!!

要做一个在线实时聊天系统,而且还要实时双语翻译(中.俄).头疼 先找了一个php在线客服系统 带源码的.看懂源码后在上面加翻译功能,一共耗时4天弄出来的. 代码如下: if(mb_detect_encoding($fdata,"UTF-8, GBK") != "UTF-8"){     //$fdata = mb_detect_encoding($fdata,"UTF-8, GBK")     $fdata = mb_convert_encodi

提高逼格,给自己的网站加入智能聊天功能

提高逼格,给自己的网站加入智能聊天功能 引言 现在突然发现有很多 QQ 群都开启了群机器人的功能,其中有两个角色,他们分别是:Baby Q 和 QQ 小冰.在 Q 群中,你可以对他们进行任意程度的调戏,不过,遗憾的是鱼和熊掌不可得兼,一个群只能进行二选一.据说 Baby Q 来自图灵公司,而小冰却是出生自微软公司. 无论是Baby Q,还是小冰,向我们展现的都是人工智能技术.这些产品都是利用深度神经网络算法模仿人脑的运算方式,让机器可以持续的自我学习. 目录 简介 机器人看板 简单调用 API

最新的chart 聊天功能( webpack2 + react + router + redux + scss + nodejs + express + mysql + es6/7)

请表明转载链接:http://www.cnblogs.com/zhangkunweb/p/6853728.html 我是一个喜欢捣腾的人,没事总喜欢学点新东西,可能现在用不到,但是不保证下一刻用不到. 我一直从事的是依赖angular.js 的web开发,但是我怎么能一直用它呢?看看最近火的一塌糊涂的reactjs ,我的天啊,不学会它,怎么能睡好觉. 今天我分享一个依赖最新版本的webpack + react + router + redux + scss + nodejs + mysql +