最近用到了前台推送技术,一开始用了comet4j 但是发现偶尔会断开,所以探寻了另一条出路。mina+applet实现推送技术。
分为三步:一.编写mina服务端,客户端代码。(先调试好)
二.将客户端类变成applet类, 进行签章等设置
三.实现applet 和 jsp 通信
上代码,边看代码边将:
1.服务端类MinaServer
import java.io.IOException; import java.net.InetSocketAddress; import java.util.Collection; import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder; import org.apache.mina.core.session.IdleStatus; import org.apache.mina.core.session.IoSession; import org.apache.mina.filter.codec.ProtocolCodecFilter; import org.apache.mina.transport.socket.SocketAcceptor; import org.apache.mina.transport.socket.nio.NioSocketAcceptor; /** * 服务器启动类 * * @author JiangBo */ public class MinaServer { /** * 单例 */ private static MinaServer instance = new MinaServer(); public static MinaServer getInstance() { return instance; } private MinaServer() { } // 端口设置 private static int PORT = 30001; private SocketAcceptor acceptor; /** * 初始化方法 * * @return */ public boolean start() { // 创建非阻塞的server端的Socket连接 acceptor = new NioSocketAcceptor(); DefaultIoFilterChainBuilder filterChain = acceptor.getFilterChain(); // 添加编码过滤器 处理乱码、编码问题 // filterChain.addLast("codec", new ProtocolCodecFilter(new CharsetCodecFactory())); // 设置核心消息业务处理器 acceptor.setHandler(new ServerMessageHandler()); // 设置session配置,30秒内无操作进入空闲状态 acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 30); try { // 绑定端口 acceptor.bind(new InetSocketAddress(PORT)); } catch (IOException e) { e.printStackTrace(); return false; } return true; } /** * 向客户端发送(推送)消息 */ public void sendMessage(String host, String port, String value) { // 实例化一个向客户端发送的socket对象 Collection<IoSession> sessions = acceptor.getManagedSessions().values(); for (IoSession sess : sessions) { sess.write(value); } } /** * main方法 * * @param args */ public static void main(String[] args) { // MinaServer server = MinaServer.getInstance(); server.start(); System.out.println("服务器启动成功================="); } }
2.ServerMessageHandler类
import org.apache.mina.core.future.CloseFuture; import org.apache.mina.core.future.IoFuture; import org.apache.mina.core.future.IoFutureListener; import org.apache.mina.core.service.IoHandler; import org.apache.mina.core.session.IdleStatus; import org.apache.mina.core.session.IoSession; /** * 处理服务器端消息 * * @author JiangBo */ public class ServerMessageHandler implements IoHandler { /** * 服务器发生异常 */ @Override public void exceptionCaught(IoSession session, Throwable cause) throws Exception { System.out.println("服务器发生异常: " + cause.getMessage()); } /** * 接收数据 */ @Override public void messageReceived(IoSession session, Object message) throws Exception { System.out.println("服务器接收到数据:" + message); } /** * 发送消息 */ @Override public void messageSent(IoSession session, Object message) throws Exception { System.out.println("服务器发送消息: " + message); } /** * 关闭链接 */ @Override public void sessionClosed(IoSession session) throws Exception { System.out.println("关闭当前session:" + session.getId() + session.getRemoteAddress()); CloseFuture closeFuture = session.close(true); closeFuture.addListener(new IoFutureListener<IoFuture>() { public void operationComplete(IoFuture future) { if (future instanceof CloseFuture) { ((CloseFuture) future).setClosed(); System.out.println("sessionClosed CloseFuture setClosed-->" + future.getSession().getId() + ","); } } }); } /** * 创建连接 */ @Override public void sessionCreated(IoSession session) throws Exception { System.out.println("创建一个新连接:" + session.getRemoteAddress()); session.write("session created:" + session.getRemoteAddress()); } /** * 空闲 */ @Override public void sessionIdle(IoSession session, IdleStatus status) throws Exception { System.out.println("当前连接" + session.getRemoteAddress() + "处于空闲状态:" + status); } /** * 打开一个session链接 */ @Override public void sessionOpened(IoSession session) throws Exception { System.out.println("打开一个session:"+ session.getId() + session.getBothIdleCount()); } }
3.MinaClient客户端类
import java.applet.Applet; import java.net.InetSocketAddress; import netscape.javascript.JSObject; 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.transport.socket.SocketConnector; import org.apache.mina.transport.socket.nio.NioSocketConnector; import com.txsoft.ipcc.common.mina.service.CharsetCodecFactory; /** * mina客户端 * * @author JiangBo */ public class MinaClient extends Applet { /** * serialVersionUID */ private static final long serialVersionUID = 1L; private static String IP = "192.168.1.30"; private static int PORT = 30001; private SocketConnector connector; private ConnectFuture future; private IoSession session; public void init() { JSObject window= null; try { window=JSObject.getWindow(this); window.eval("alert('start begin!')"); } catch (Exception e) { } // 创建一个socket连接 connector = new NioSocketConnector(); // 设置链接超时时间 connector.setConnectTimeoutMillis(3000); // 获取过滤器链 DefaultIoFilterChainBuilder filterChain = connector.getFilterChain(); // 添加编码过滤器 处理乱码、编码问题 filterChain.addLast("codec", new ProtocolCodecFilter(new CharsetCodecFactory())); // 消息核心处理器 connector.setHandler(new ClientMessageHandlerAdapter(this)); // 连接服务器,知道端口、地址 future = connector.connect(new InetSocketAddress(IP, PORT)); // 等待连接创建完成 future.awaitUninterruptibly(); // 获取当前session session = future.getSession(); // try { window.eval("alert('end!')"); } catch (Exception e) { } } public void setAttribute(Object key, Object value) { session.setAttribute(key, value); } /** * 发送 * @param message */ public void send(String message) { session.write(message); } /** * 发送信息到JSP * @param message */ public void sendJsp(String message) { // 获取JavaScript窗口句柄,引用当前文档窗口 JSObject window = JSObject.getWindow(MinaClient.this); // 调用页面上的js方法 show(message) Object obj[] = new Object[1]; obj[0] = message; window.call("show", obj);// 参数用数组的形势表示。 } public boolean close() { CloseFuture future = session.getCloseFuture(); future.awaitUninterruptibly(1000); connector.dispose(); return true; } public SocketConnector getConnector() { return connector; } public IoSession getSession() { return session; } }
4.ClientMessageHandlerAdapter类
import org.apache.mina.core.service.IoHandlerAdapter; import org.apache.mina.core.session.IoSession; /** * 客户端消息处理类 * @author JiangBo */ public class ClientMessageHandlerAdapter extends IoHandlerAdapter { private MinaClient minaClient = null; public ClientMessageHandlerAdapter(MinaClient minaClient) { this.minaClient = minaClient; } /** * 接收到消息 */ public void messageReceived(IoSession session, Object message) throws Exception { // 接到消息无处理 System.out.println("messageSent服务端发送到客户端的消息:" + message); if (null != this.minaClient) { try { this.minaClient.sendJsp(message.toString()); } catch (Exception e) { } } } public void messageSent(IoSession session , Object message) throws Exception{ System.out.println("messageSent 客户端发送消息:" + message); } @Override public void exceptionCaught(IoSession session, Throwable cause) throws Exception { System.out.println("服务器发生异常: {}" + cause.getMessage()); } }
5. jsp文件
<%@ page contentType="text/html; charset=utf-8"%> <html> <head> <title> test mina push </title> </head> <body> <applet name = "testapplet" code = 'com.txsoft.ipcc.common.mina.client.MinaClient.class' archive = 'minaClient.jar' width = 100 height = 50 MAYSCRIPT> </applet> <script type="text/javascript"> function show(message){ alert(message); } </script> </body> </html>
注意:例子中要把代码打包放在跟目录下,例子中jar包名叫:minaClient.jar。jar包还需要密码的支持所以打包时候还要把mima的支持包打进去。把下面3个包放在跟minaClient.jar同级目录下。
1.mina-core-2.0.7.jar
2.slf4j-api-1.7.6.jar
3.slf4j-jdk14-1.7.7.jar
打包时候我是通过MANIFEST.MF文件选择了密码支持的3个包
MANIFEST.MF内容:
Manifest-Version: 1.0 Class-Path: mina-core-2.0.7.jar slf4j-api-1.7.6.jar slf4j-jdk14-1.7.7.jar
由于是Applet所以需要生成证书及签名所以在服务端cmd调出命令框 执行授权:
1、keytool -genkey -keystore pepper.store -alias pepper
这个命令用来产生一个密匙库,执行完毕后应该在c:/admin中产生一个pepper.store的文件,这里的pepper是我自己的名字,你可以对它进行修改。另外在执行命令的时候还有提示你输入密匙库的密码,这里你一定要记住,否则后面要用的时候无法输入。
2、keytool -export -keystore pepper.store -alias pepper -file pepper.cert
这个命令用来产生签名时所要用的证书,同样这里的pepper也可以换成你自己需要的名字。这个命令执行完后在c:/admin中产生一个pepper.cert的文件。
3、 jarsigner -keystore pepper.store E:\workspace_IPCC\IPCC\WebRoot\minaClient.jar pepper
这个命令用上面产生的证书将我们的jar文件进行了签名。(可以写绝对路径)
在客户端设置security
C:\Program Files (x86)\Java\jre6\lib\security\java.policy
在最下面添加这句,是允许所有IP 所有端口的权限,让然你可以可以指定IP 和端口
permission java.net.SocketPermission "*:*","accept,connect,resolve";
好了 小伙伴们 快去试试吧~
需要的jar包:
相关推荐
通过Mina与Socket实现通信,其包含客户端与服务端的实现代码
mina新手案例,mina新手教程源码 mina+springboot最简单的案例。用的IDEA * mina服务端 * 1、添加@Controller注解和 @PostConstruct注解,代表启动springboot项目时也调用该类下的该方法, * 启动springboot项目...
该项目是本人真实项目中使用到的mina + spring+struts2 + mybatis框架,里面有详细的注释说明,以及一个完整的接收消息、入库、返回例子。对需要真实项目开发的人员来说,可以直接使用。 另外,如果需要更加详细的...
该程序集成mina框架与spring框架实现多人聊天程序
Java-Mina长连接方式实现服务端主动推送到客户端。
我自己写的使用mina框架实现cmpp2.0服务端,经过一段使用解决了几个bug现在比较稳定。
java mina 消息推送
mina+spring+hibernate搭建所需jar包
一个对推送 及时的处理结束,长连接保持,以及对客户端 和服务端的实现,
http://knight-black-bob.iteye.com/blog/2370938 推送sdk (类似百度 推送 ) android mina (待优化... ) 本demo 研究的是原理,不要计较太多。。。。 至于token生成,service 保活,定时启动 不做说明。
基于Mina的Android消息推送系统的研究与实现.pdf
NULL 博文链接:https://shiwujie.iteye.com/blog/1045272
mina+spring做的聊天室程序。先跑server,再启动chatpanel即可登录
这是一个简单的基于mina框架的实现增删改查的工程,融合了mongodb mybatis proxool等多个技术。
SSI+Mina2(Struts2+Spring4+Mybatis3+Mina2)集成,都是最新的包, 发布就可运行,配置文件都写了详细的注释。
Mina框架+常用JAR包 Mina框架+常用JAR包 Mina框架+常用JAR包 Mina框架+常用JAR包 Mina框架+常用JAR包 Mina框架+常用JAR包
mina2+spring结合实例
用Apache MiNa 实现多人聊天室,项目直接导进去myeclipse就可以运行了,懒人必备