最近自己在工作之余做一个金融类的项目(类似股票),采用mina开源框架进行服务端和客户端之间交互。开始学学mina。转入正题...
(1)首先需要引入以下几个包:
mina-core-2.0.x.jar,slf4j-api-1.6.x.jar,slf4j-log4j12-1.6.x.jar
这里需要注意下:slf4j-api-1.6.x.jar,slf4j-log4j12-1.6.x.jar 必须是同样二级版本号,即1.6版本,如果一个是1.5版本、一个是1.6版本,运行时会报错:java.lang.NoSuchMethodError: org.slf4j.helpers.MessageFormatter.format,原因是包冲突。
(2)创建一个主服务类:TradeSocket
public class TradeSocket extends SocketBase implements ISocket { ..... @Override public boolean initSocket(Config config) { logger.info("正在初始化 tradeSocket"); TradeSocketConfig tradeConfig = (TradeSocketConfig) config; this.setSocket_IP(tradeConfig.getIp()); logger.info("正在初始化 tradeSocket的Ip"); this.setSocket_port(tradeConfig.getPost()); logger.info("正在初始化 tradeSocket的端口"); this.setHandlerAdapter(new TradeSocketHandler()); logger.info("正在初始化 tradeSocket的处理器"); this.setAcceptor(new NioSocketAcceptor()); logger.info("正在初始化 tradeSocket的接收器"); logger.info("成功初始化 tradeSocket"); logger.info("tradeSocket服务IP:" + this.getSocket_IP()); logger.info("tradeSocket服务端口号:" + this.getSocket_port()); return true; } @Override public boolean startSocket() { boolean result = false; if (this.isStart() == false) { initSocket(this.tradeSocketConfig); // 设置过滤器,ObjectSerializationCodecFactory可以对象序列化方式在服务端和客户端之间传递数据 this.getAcceptor().getFilterChain().addLast(DGConstants.SERVER_SOCKET_FILTER_CHIN, new ProtocolCodecFilter(new ObjectSerializationCodecFactory())); // 设置读取数据的缓冲区大小 this.getAcceptor().getSessionConfig().setReadBufferSize(2048); // 设置长连接 this.getAcceptor().getSessionConfig().setKeepAlive(true); // 读写通道10秒内无操作进入空闲状态 this.getAcceptor().getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10); this.getAcceptor().setHandler(this.getHandlerAdapter()); try { this.getAcceptor().bind(new InetSocketAddress(this.getSocket_IP(), this.getSocket_port())); this.setStart(true); result = true; logger.info("成功启动 tradeSocket"); } catch (IOException e) { logger.error(e.getMessage(), e); } } return result; } @Override public boolean closeSocket() { this.getAcceptor().dispose(); this.setStart(false); logger.error("关闭了交易Socket"); return false; }
(3)创建一个handler来管理事件,是业务处理关注点
public class TradeSocketHandler extends IoHandlerAdapter { public static Logger logger = Logger.getLogger(TradeSocketHandler.class); @Override public void sessionCreated(IoSession session) throws Exception { super.sessionCreated(session); logger.info("服务端与客户端创建连接..."); } @Override public void sessionOpened(IoSession session) throws Exception { InetSocketAddress remoteAddress = (InetSocketAddress) session.getRemoteAddress(); String clientIp = remoteAddress.getAddress().getHostAddress(); logger.info("服务器打开Session ID=" + session.getId()); logger.info( "服务端与客户端["+session.getRemoteAddress()+"]连接打开..."); // ConnectResponseMessage connectResponseMessage = new ConnectResponseMessage(); // connectResponseMessage.setConnectResponse(ConnectResponseMessage.ConnectSuccess); // session.write(connectResponseMessage); } @Override public void sessionClosed(IoSession session) throws Exception { super.sessionClosed(session); logger.info("服务端与客户端断开连接"); } @Override public void sessionIdle(IoSession session, IdleStatus status) throws Exception { super.sessionIdle(session, status); logger.info("服务端进入空闲状态..."); } @Override public void exceptionCaught(IoSession session, Throwable cause) throws Exception { logger.error(cause.getMessage(), cause); super.exceptionCaught(session, cause); } @Override public void messageReceived(IoSession session, Object message) throws Exception { if (message instanceof BaseMessage) { BaseMessage baseMessage = (BaseMessage) message; logger.info("服务器收到的消息为:" + baseMessage); if (baseMessage.getMsgType() == MessageType.LoginMessage_Type) { LoginMessage loginMessage = (LoginMessage) baseMessage; UserConnect userConnect = new UserConnect(); userConnect.setTradeSession(session); loginMessage.setUserid(loginMessage.getUserid() + session.hashCode()); ServerCache cache = ServerCache.getInstance(); cache.addUserConnect(loginMessage.getUserid(), userConnect); userConnect.getTradeSession().setAttribute("userID", loginMessage.getUserid()); userConnect.getTradeSession().setAttribute("sessionID", session.hashCode()); //这里主要是处理各种业务 ServerReceivedMessageProcess.getInstance().processMessage(loginMessage); } } } @Override public void messageSent(IoSession session, Object message) throws Exception { super.messageSent(session, message); }
ServerReceivedMessageProcess.getInstance().processMessage(.....);方法是根据从客户端传过来不同message,实例化出不同处理类。
(4)创建客户端主类
public class ClientTradeSocket extends ClientSocketBase { private static Logger logger = Logger.getLogger(ClientTradeSocket.class); private static ClientTradeSocket instance; public static ClientTradeSocket getInstance() { if (instance == null) { instance = new ClientTradeSocket(); } return instance; } private ClientTradeSocket() { } @Override public boolean closedSocket() { this.getConnector().dispose(); this.setStart(false); logger.info("客户关闭了与服务器的连接"); return true; } @Override public void initSocket() { this.setHandlerAdapter(new ClientTradeHandler()); this.setConnector(new NioSocketConnector()); logger.info("客户初始化了与服务器的连接"); } @Override public void startSocket() { this.initSocket(); try { if (this.isStart() == false) { /** * 创建接收数据的过滤器 */ DefaultIoFilterChainBuilder chain = this.getConnector().getFilterChain(); chain.addLast(DGConstants.SERVER_SOCKET_FILTER_CHIN, new ProtocolCodecFilter(new ObjectSerializationCodecFactory())); this.getConnector().setHandler(this.getHandlerAdapter()); /** * 设置连接超时的时间 为:一分钟 这个超时不可以过小 */ this.getConnector().setConnectTimeoutMillis(ClientSocketBase.timeOutMillis); logger.info("ip/port:" + this.getServer_IP_Port() + "/" + this.getServer_Socket_Port()); InetSocketAddress socketAddress = new InetSocketAddress(this.getServer_IP_Port(), this.getServer_Socket_Port()); /** * 建立连接 */ this.connectFuture = this.getConnector().connect(socketAddress); //等待连接,这句话比较重要,如果没有,则后面的this.connectFuture.isConnected()为false的。 //原因在于:connect方法是异步的,awaitUninterruptibly方式阻塞主线程,等待服务端返回,从而实现同步 //如果不用awaitUninterruptibly,可以采用this.connectFuture.addListener方法进行回调 this.connectFuture.awaitUninterruptibly(); //连接后,获得session if (this.connectFuture.isConnected()) { logger.info("已经建立用户连接"); this.setStart(true); logger.info("客户开启了与服务器的连接"); ConnectSession session = ConnectSession.getInstance(); //将session保存到缓存中 session.setTradeSession(this.connectFuture.getSession()); } else { logger.info("不能建立用户连接"); this.setStart(false); ConnectSession session = ConnectSession.getInstance(); session.setTradeSession(null); } } } catch (Exception e) { logger.error(e.getMessage(), e); this.setStart(false); } } }
(5)客户端业务处理类handler
public class ClientTradeHandler extends IoHandlerAdapter { private static Logger logger = Logger.getLogger(ClientTradeHandler.class); private String user; public void setUser(String user) { this.user = user; } public String getUser() { return this.user; } /** * * 当接口中其他方法抛出异常未被捕获时触发此方法 */ @Override public void exceptionCaught(IoSession ioSession, Throwable throwable) throws Exception { } /** * 当接收到消息后被触发 * */ @Override public void messageReceived(IoSession ioSession, Object msg) throws Exception { BaseMessage message = (BaseMessage) msg; logger.info("接受到得消息为:" + message); if(message!=null) { if(message instanceof ConnectResponseMessage) { ConnectResponseMessage connectResponseMessage = (ConnectResponseMessage)message; if(connectResponseMessage.getConnectResponse() == ConnectResponseMessage.ConnectSuccess) { ConnectSession clientConnect = ConnectSession.getInstance(); clientConnect.setTradeSession(ioSession); } } else { //根据服务端返回的message,实例化不同处理类 ClientReceivedMessageProcess messageProcess = new ClientReceivedMessageProcess(); messageProcess.processMessage(message); } } } /** * 当发送消息后被触发 * */ @Override public void messageSent(IoSession ioSession, Object msg) throws Exception { } /** * 当会话关闭时被触发 * */ @Override public void sessionClosed(IoSession ioSession) throws Exception { logger.info("与服务器断开连接!!"); // EIMTrayIcon trayIcon = EIMTrayIcon.getInStance(); // trayIcon.showIcon(EIMClientConfig.OffLineTryIcon_Type); } /** * 当会话创建时被触发 * */ @Override public void sessionCreated(IoSession ioSession) throws Exception { } /** * * 当会话空闲时被触发 */ @Override public void sessionIdle(IoSession ioSession, IdleStatus msg) throws Exception { } /** * * 当会话开始时被触发 */ @Override public void sessionOpened(IoSession ioSession) throws Exception { logger.info("会话已经打开"); } }
最后,可以进行运行测试了。。。。
相关推荐
**Mina2.0入门** Apache Mina是一个高度可扩展且功能强大的网络通信框架,它为Java应用程序提供了简单而统一的API来处理TCP/IP、UDP和SSL/TLS协议。Mina2.0作为其最新版本,引入了许多改进和优化,旨在提高性能、...
Mina 的设计目标之一是为了让开发者能够快速构建出高效稳定的网络服务,无论是在客户端还是服务器端。 #### 二、Mina 的核心组件 为了更好地理解和使用 Mina,我们需要深入了解其核心组件及其工作原理: 1. **`...
【mina入门实例】这篇教程主要介绍了如何入门Apache Mina框架,并通过一个简单的实例来演示其基本用法。Apache Mina是一个高性能、轻量级的网络通信框架,常用于开发网络应用,如TCP/IP和UDP协议的服务端和客户端。 ...
Apache Mina是一个开源项目,由Apache软件基金会维护,它是一个网络通信框架,专注于提供高性能、...对于初学者,阅读《Apache Mina入门(完成版)》PDF文档将是一个很好的起点,深入学习Mina的内部机制和实践技巧。
描述提到,这个源码是配合某篇技术文章《NIO框架入门(二):服务端基于MINA2的UDP双向通信Demo演示》的实现部分,文章链接为http://www.52im.net/thread-373-1-1.html。通常,这样的源码示例会包含完整的服务器端代码...
本篇文章将围绕"Mina入门程序"展开,带你逐步了解如何利用Mina进行简单的网络通信。 首先,我们来看一下Mina的核心概念。Mina的核心组件包括Acceptor、Session和Filter。Acceptor负责监听网络端口并接收连接请求;...
**Mina入门程序详解** Apache Mina是一个高度可扩展的网络通信框架,广泛应用于Java开发中,特别是构建高性能、高并发的TCP/IP和UDP服务。本篇将带你深入理解Mina的基本概念,以及如何通过一个简单的入门程序来熟悉...
描述中提到的源码来源于《NIO框架入门(二):服务端基于MINA2的UDP双向通信Demo演示》这篇文章,这表明源码实例是为了解释和展示如何利用MINA2进行基于UDP的网络编程,特别是涉及到了非阻塞I/O(Non-blocking I/O, ...
jaca视频教程 jaca游戏服务器端开发 Netty NIO AIO Mina视频教程 课程目录: 一、Netty快速入门教程 01、第一课NIO 02、第二课netty服务端 03、第三课netty客户端 ...16、Mina学习之自定义协议-客户端实例.flv
在本篇中,我们将探讨Mina的基本概念、架构以及如何开始一个简单的Mina项目。 **Mina的核心概念** 1. **事件驱动模型**:Mina基于I/O多路复用技术,如Java的NIO(Non-blocking I/O),实现了一个事件驱动的模型。...
《Mina 2.0 工作原理以及配置中的注意事项》这篇教程深入讲解了Mina2的工作机制,包括其基于NIO(非阻塞I/O)的设计,以及如何配置和优化这些设置。在实际应用中,正确配置Mina能够显著提升网络应用的效率和稳定性。...
- **基于MINA框架快速开发网络应用程序(转载).html**:这篇文章可能介绍了如何使用MINA快速构建网络应用,包括基本的配置和代码示例,帮助初学者快速入门。 - **Apache_Mina_Server_2.0中文参考手册V1.0.pdf**:这是...
#### Mina入门 为了更好地理解和使用Mina2.0框架,我们将通过一个简单的示例来了解如何搭建一个基于Mina的服务端和客户端程序。 ##### 第一步:下载所需的Jar包 1. **mina-core-2.0.0-M1.jar**:这是Mina的核心库...
本节目标:对于入门篇的总结 目标用户:无编程经验,但对微信小程序感兴趣的同学。 学习目标:对微信小程序的研发,有概要的了解,并对基本知识点有一定的认识,不需要深入追究。仅记80/20定律。 案例分析:hello...
1. 开篇导言 本节目标:通过上一节的讲解,相信大家对微信小程序有了初步的了解。接下来将会对小程序的框架进行简单介绍。 目标用户:无编程经验,但对微信小程序感兴趣的同学。 学习目标:了解MINA框架的基本特征...
1. 开篇导言 本节目标:通过上一节的讲解,相信大家对小程序框架MINA的目录结构和配置有了一定的了解。接下来将会讲解视图层,逻辑层及其之间的交互。 目标用户:无编程经验,但对微信小程序感兴趣的同学。 学习...
1. 开篇导言 本节目标:通过上一节的讲解,相信大家对小程序框架MINA有了初步了解。接下来将会对其进行深入介绍。 目标用户:无编程经验,但对微信小程序感兴趣的同学。 学习目标:了解MINA框架的目录结构和配置。...
这篇总结将深入探讨Dubbo的核心概念、安装过程以及如何通过示例进行快速入门。 一、Dubbo核心概念 1. 服务提供者(Provider):提供服务的模块,它对外暴露服务,并通过Dubbo的注册中心将自己的服务注册出去。 2....
虽然"ApacheMina入门(完成版).pdf"文件与GC直接关联不大,但它可以帮助Java程序员更好地理解网络编程和服务器端开发,这些也是Java应用的重要组成部分。 总的来说,理解Java的GC工作原理对于优化代码性能和解决...