Netty-SocketIO的Web推送实战应用
netty-socketio是一个开源的Socket.io服务器端的一个java的实现, 它基于Netty框架。可应用于服务端主动推送消息到客户端等场景,比如说股票价格变化、k线图的走势,和websocket是一个作用,只不过socketio可支持所有的浏览器。 项目地址为: https://github.com/mrniko/netty-socketio。
Socket.IO除了支持WebSocket通讯协议外,还支持许多种轮询(Polling)机制以及其它实时通信方式,并封装成了通用的接口,并且在服务端实现了这些实时机制的相应代码。Socket.IO实现的Polling通信机制包括Adobe Flash Socket、AJAX长轮询、AJAX multipart streaming、持久Iframe、JSONP轮询等。Socket.IO能够根据浏览器对通讯机制的支持情况自动地选择最佳的方式来实现网络实时应用。
一、下载Netty-SocketIO
- socket.io-client-master
- netty-socketio-master
- netty-socketio-demo-master
从netty-socketio的git上可下载到以上三个压缩包,分别对应的是web 客户端的所需文件、netty socketio的java服务端实现、以及对应的可以应用web推送的demo。
二、部署server的资源项目
从git上下载的socketio server压缩包中没有项目所需的jar包,我是自己新建了一个项目,本来上传到了CSDN的代码库里了,但写博客的时候怎么也打不开了,那么只能提供对应项目导航图,同时提供jar包的下载地址,需要的可动手去获得。
从http://mvnrepository.com/网站上课下载到需要的所有jar包。
然后将jar包添加到项目中。
切记jdk的版本一定要在1.7以上,我在本地环境中用的1.7,但是服务器上一直用的是1.6,部署项目的时候没有注意,导致服务端可以接收到客户端的socketio 的connect,但是客户端的response相应中却连接不通,开始的时候以为是跨域问题导致的,搜了好多帖子,但问题根本就是不是跨域引起的,jdk的版本换成1.7就ok了,因为netty的nio是基于java的1.7的。
三、应用server
在需要应用socketio的项目上右键,为项目添加socketio项目支持(注意红色标出的)。
新建main类。
public static void main(String[] args) throws InterruptedException {
Configuration config = new Configuration();
config.setHostname("localhost");
config.setPort(10015);
SocketIOServer server = new SocketIOServer(config);
server.addConnectListener(new ConnectListener() {// 添加客户端连接监听器
@Override
public void onConnect(SocketIOClient client) {
logger.info(client.getRemoteAddress() + " web客户端接入");
client.sendEvent("helloPush", "hello");
}
});
// 握手请求
server.addEventListener("helloevent", HelloUid.class, new DataListener<HelloUid>() {
@Override
public void onData(final SocketIOClient client, HelloUid data, AckRequest ackRequest) {
// 握手
if (data.getMessage().equals("hello")) {
int userid = data.getUid();
logger.info(Thread.currentThread().getName() + "web读取到的userid:" + userid);
// send message back to client with ack callback
// WITH data
client.sendEvent("hellopush", new AckCallback<String>(String.class) {
@Override
public void onSuccess(String result) {
logger.info("ack from client: " + client.getSessionId() + " data: " + result);
}
}, sessionTime);
} else {
logger.info("行情接收到了不应该有的web客户端请求1111...");
}
}
});
server.start();
Thread.sleep(Integer.MAX_VALUE);
server.stop();
}
当client通过ip和端口连接到server后,会构造一个SocketIOClient client的对象,在实际的应用中,可以将该client保存起来,通过client.sendEvent("helloPush", "hello");就可以向client端发送相应的数据了。
四、应用client
①、引入socket.io.js
<script type="text/javascript" src="${ctx}/components/socketio/socket.io.js"></script>
②、创建connection的公共方法
function connectQuotation(uid, callback) {
// 链接行情server
socket = io.connect('http://localhost:10015');
// 如果用户在web端登陆,那么发送握手请求
if (uid) {
// 连接上server后
socket.on('connect', function() {
// 发送握手请求
var jsonObject = {
uid : parseInt(uid),
message : "hello"
};
this.emit('helloevent', jsonObject);
this.on('hellopush', function(data, ackServerCallback, arg1) {
// base64转码的数据,可忽视
YUNM.session = {
sessionId : $.base64.atob(data.sessionId),
time : $.base64.atob(data.time)
};
if (ackServerCallback) {
ackServerCallback('server message was delivered to client!');
}
});
});
}
// 如果web端session超时,socket断开,10分钟扫描一次
int = window.setInterval(function() {
// 我是通过ajax判断session超时的,你也可以通过其他方式
$.ajax({
type : 'POST',
url : common.ctx + "/getSessionTimeout",
dataType : "json",
cache : false,
success : function(json) {
var timeout = parseInt(json.message);
// session超时后,socket断开,服务端就可以监听到释放资源
if (timeout == 0) {
socket.disconnect();
}
},
error : function() {
socket.disconnect();
// 清除
window.clearInterval(int);
}
});
}, YUNM._set.interval);
callback();
}
③、需要web推送的页面进行socketio的连接
$(function() {
connectQuotation($("#global_uid").val(), function() {
socket.on("pushQuotation", function(message) {
if (message.type == "dealOrder") {
var msg = message.response.result;
// 输出服务端消息
YUNM.debug(msg);
}
});
});
});
五、注意事项
- 关于socketio的ssl应用,一直没有弄出来,主要是java的toolkey生成的jks总是不被浏览器识别,socketio提供的例子也不能运行,在各大网站上暂时没有解决问题。可通过浏览器添加https的例外做法来规避错误,但不可取,后面还需要研究。
- socketio在浏览器刷新后,旧的连接断开,需要重新建立连接,这个请注意。
- 客户端session超时后,切记关闭socket,我是通过10分钟一次的扫描进行的session超时验证,该方法不够理想。
- server端,在实际应用中,需要将客户端断开的socket进行垃圾清理,注意判断方法如下:
NamespaceClient client = (NamespaceClient) socket;
if (client.getBaseClient().isConnected()) {
SessionManager.getSession(getSession().getSessionId());
} else {
logger.warn("web发送心跳包失败,客户端连接线程[" + this.getName() + "]已断开");
running = false;
break;
}
整体Netty-SocketIO的Web推送还是非常易于掌握的,但是缺少api,做起来需要不停实践,另外解决问题的方法不多,希望本篇可以给你提供些许帮助。
Netty-SocketIO的Web推送实战应用的更多相关文章
- atitit.web 推送实现方案集合(2)---百度云,jpush 极光推送 ,个推的选型比较.o99
atitit.web 推送实现方案集合(2)---百度云,jpush 极光推送 ,个推的选型比较.o99 1.1. 云推送有推送次数或频率的限制吗? 1 1.2. 推送的消息长度 1 1.3. 离线消 ...
- atitit.web 推送实现方案集合
atitit.web 推送实现方案集合 1. 俩中模式 Push/Pull 1 2. 需要实现的特性 2 2.1. 推送消息广播. 2 2.2. 推送定向消息. 2 2.3. 提供连接上线前.上线.下 ...
- .atitit.web 推送实现解决方式集合(3)----dwr3 Reverse Ajax
.atitit.web 推送实现解决方式集合(3)----dwr3 Reverse Ajax 1. 原理实现 1 2. Page 添加配置.添加回调函数dwr.engine.setActiveRev ...
- Android 基于Netty接收和发送推送解决方案的消息字符串(三)
在上一篇文章中<Android 基于Netty的消息推送方案之概念和工作原理(二)> .我们介绍过一些关于Netty的概念和工作原理的内容,今天我们先来介绍一个叫做ChannelBuffe ...
- JavaScript是如何工作的: Web推送通知的机制
摘要: 如何在Web端推送消息? 这是专门探索 JavaScript 及其所构建的组件的系列文章的第9篇. 如果你错过了前面的章节,可以在这里找到它们: JavaScript是如何工作的:引擎,运行时 ...
- .atitit.web 推送实现解决方案集合(3)----dwr3 Reverse Ajax
.atitit.web 推送实现解决方案集合(3)----dwr3 Reverse Ajax 1. 原理实现 1 2. Page 增加配置,增加回调函数dwr.engine.setActiveRev ...
- 基于netty-socketio的web推送服务
实时消息的推送,PC端的推送技术可以使用socket建立一个长连接来实现.传统的web服务都是客户端发出请求,服务端给出响应.但是现在直观的要求是允许特定时间内在没有客户端发起请求的情况下服务端主动推 ...
- SpringBoot项目集成socketIo实现实时推送
netty-socketio maven依赖 <dependency> <groupId>com.corundumstudio.socketio</groupId> ...
- web推送
WEB消息推送框架 web-msg-sender是一款web长连接推送框架,采用PHPSocket.IO开发,基于WebSocket长连接通讯,如果浏览器不支持WebSocket则自动转用comet推 ...
随机推荐
- JAVA-各种类型之间转换 parse() 与valueOf()
类型互转 1.各种类型转String 2.String转Bytes 3.数组转List 4.进制转换 5. parse 在 SimpleDateFormat 中是转换为Date类,其它的一些包装类都是 ...
- django用户认证系统——注销和页面跳转5
当用户想切换登录账号,或者想退出登录状态时,这时候就需要注销已登录的账号.现在我们来为网站添加注销登录的功能,这个功能 Django 也已经为我们提供,我们只需做一点简单配置. 注销登录 注销登录的视 ...
- CentOS firewalld 防火墙操作
Centos 7 开启端口CentOS 7 默认没有使用iptables,所以通过编辑iptables的配置文件来开启80端口是不可以的 CentOS 7 采用了 firewalld 防火墙 如要查询 ...
- getComputedStyle获取css属性与IE下的currentStyle获取到的值不同
<!doctype html><html lang="en"> <head> <meta charset="UTF-8&quo ...
- Web移动端使用localStorage缓存Js和css文件 | 强制不要缓存
1.尽量不把js放在onload事件中,而是放在由用户主动触发的事件 2.加时间戳,时间不同则会加载js而非使用缓存 强制不要缓存: <meta http-equiv=Cache-Control ...
- 170208、用Navicat自动备份mysql数据库
数据库备份很重要,很多服务器经常遭到黑客的恶意攻击,造成数据丢失,如果没有及时备份的话,后果不堪设想. 一:备份的目的: 做灾难恢复:对损坏的数据进行恢复和还原 需求改变:因需求改变而需要把数据还原到 ...
- delphi ---break,exit,continue等跳出操作的区别
1.break 强制退出最近的一层循环(注意:只能放在循环里:而且是只能跳出最近的一层循环),用于从for.while.repeat语句中强制退出 2.continue 用于从for.while.re ...
- 个人觉得存成char(12),优于varchar(12)
w 延展一点:0----(还是上边的url),varchar(10)则数据库的存储1-11bytes,而不是0-10bytes;varchar(256)则为2-258bytes; 1----如果待入库 ...
- <2014 05 09> Lucida:我的算法学习之路
[转载] 我的算法学习之路 关于 严格来说,本文题目应该是我的数据结构和算法学习之路,但这个写法实在太绕口——况且CS中的算法往往暗指数据结构和算法(例如算法导论指的实际上是数据结构和算法导论),所以 ...
- window安装redis数据库
1.下载安装包 1.百度网盘链接:https://pan.baidu.com/s/1MrAK5Suc1xpzkbp1WQbP0A 提取码:u9uq 2.GitHub:https://github.co ...