java mina聊天_MINA 实现聊天功能

在《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 sessions = Collections

.synchronizedSet(new HashSet()); // (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 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();

}

}

}

}

2.连接到指定的服务器

##运行效果

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

s%281%29.jpg

c1.jpg

c2.jpg

##源码

##参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值