基于netty-socketio的web推送服务

简介:

实时消息的推送,PC端的推送技术可以使用socket建立一个长连接来实现。传统的web服务都是客户端发出请求,服务端给出响应。但是现在直观的要求是允许特定时间内在没有客户端发起请求的情况下服务端主动推送消息到客户端。

有哪些可以实现web消息推送的技术:

  • 不断地轮询(俗称“拉”,polling)是获取实时消息的一个手段:Ajax 隔一段时间(通常使用 JavaScript 的 setTimeout 函数)就去服务器查询是否有改变,从而进行增量式的更新。但是间隔多长时间去查询成了问题,因为性能和即时性造成了严重的反比关系。间隔太短,连续不断的请求会冲垮服务器,间隔太长,务器上的新数据就需要越多的时间才能到达客户机。

    • 优点:服务端逻辑简单;

    • 缺点:其中大多数请求可能是无效请求,在大量用户轮询很频繁的情况下对服务器的压力很大;

    • 应用:并发用户量少,而且要求消息的实时性不高,一般很少采用;

  • 长轮询技术(long-polling):客户端向服务器发送Ajax请求,服务器接到请求后hold住连接,直到有新消息或超时(设置)才返回响应信息并关闭连接,客户端处理完响应信息后再向服务器发送新的请求。

    • 优点:实时性高,无消息的情况下不会进行频繁的请求;

    • 缺点:服务器维持着连接期间会消耗资源;

  • 基于Iframe及htmlfile的流(streaming)方式:iframe流方式是在页面中插入一个隐藏的iframe,利用其src属性在服务器和客户端之间创建一条长链接,服务器向iframe传输数据(通常是HTML,内有负责插入信息的javascript),来实时更新页面。

    • 优点:消息能够实时到达;

    • 缺点:服务器维持着长连接期会消耗资源;

  • 插件提供socket方式:比如利用Flash XMLSocket,Java Applet套接口,Activex包装的socket。

    • 优点:原生socket的支持,和PC端和移动端的实现方式相似;

    • 缺点:浏览器端需要装相应的插件;

  • WebSocket:是HTML5开始提供的一种浏览器与服务器间进行全双工通讯的网络技术。

    • 优点:更好的节省服务器资源和带宽并达到实时通讯;

    • 缺点:目前还未普及,浏览器支持不好;

综上,考虑到浏览器兼容性和性能问题,采用长轮询(long-polling)是一种比较好的方式。

netty-socketio是一个开源的Socket.io服务器端的一个java的实现, 它基于Netty框架。 项目地址为: https://github.com/mrniko/netty-socketio

以下是一个来自netty-socketio的推送示例,web聊天系统。

服务器端push server:

消息实体:

  View Code

监听事件:

复制代码
package com.nettysocketio.test;

import com.corundumstudio.socketio.AckRequest;
import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.listener.DataListener;

public class CharteventListener implements DataListener<ChatObject> {

    SocketIOServer server;

    public void setServer(SocketIOServer server) {
        this.server = server;
    }

    public void onData(SocketIOClient client, ChatObject data,
            AckRequest ackSender) throws Exception {
        // chatevent为 事件的名称, data为发送的内容
        this.server.getBroadcastOperations().sendEvent("chatevent", data);
    }
}
复制代码

推送服务:

复制代码
package com.nettysocketio.test;

import com.corundumstudio.socketio.Configuration;
import com.corundumstudio.socketio.SocketIOServer;

public class App {
    public static void main(String[] args) throws InterruptedException
    {
        Configuration config = new Configuration();
        config.setHostname("localhost");
        config.setPort(9092);

        SocketIOServer server = new SocketIOServer(config);
        CharteventListener listner = new CharteventListener();
        listner. setServer(server);
        // chatevent为事件名称
        server.addEventListener("chatevent", ChatObject.class, listner);
        //启动服务
        server.start();
        Thread.sleep(Integer.MAX_VALUE) ;
        server.stop();
    }
}
复制代码

浏览器端Client:

客户端使用的是socket.io-client,项目地址为:https://github.com/Automattic/socket.io-client

客户端聊天代码:

复制代码
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Socketio chat</title>
<script src="./jquery-1.7.2.min.js" type="text/javascript"></script>
<script type="text/javascript" src="./socket.io/socket.io.js"></script>
<style>
body {
    padding: 20px;
}
#console {
    height: 400px;
    overflow: auto;
}
.username-msg {
    color: orange;
}
.connect-msg {
    color: green;
}
.disconnect-msg {
    color: red;
}
.send-msg {
    color: #888
}
</style>
</head>
<body>
    <h1>Netty-socketio chat demo</h1>
    <br />
    <div id="console" class="well"></div>
    <form class="well form-inline" onsubmit="return false;">
        <input id="name" class="input-xlarge" type="text" placeholder="用户名称. . . " />
        <input id="msg" class="input-xlarge" type="text" placeholder="发送内容. . . " />
        <button type="button" onClick="sendMessage()" class="btn">Send</button>
        <button type="button" onClick="sendDisconnect()" class="btn">Disconnect</button>
    </form>
</body>
<script type="text/javascript">
    var socket = io.connect('http://localhost:9092');
    socket.on('connect',function() {
        output('<span class="connect-msg">Client has connected to the server!</span>');
    });
    
    socket.on('chatevent', function(data) {
        output('<span class="username-msg">' + data.userName + ' : </span>'
                + data.message);
    });
    
    socket.on('disconnect',function() {
        output('<span class="disconnect-msg">The client has disconnected! </span>');
    });
    
    function sendDisconnect() {
        socket.disconnect();
    }
    
    function sendMessage() {
        var userName = $("#name").val()
        var message = $('#msg').val();
        $('#msg').val('');
        socket.emit('chatevent', {
            userName : userName,
            message : message
        });
    }
    
    function output(message) {
        var currentTime = "<span class='time' >" + new Date() + "</span>";
        var element = $("<div>" + currentTime + " " + message + "</div>");
        $('#console').prepend(element);
    }
</script>
</html>
复制代码

先运行push server,再打开chat html就可以看到连接信息和服务器推送的聊天信息。

 

参考:

https://github.com/mrniko/netty-socketio

https://github.com/mrniko/netty-socketio-demo

 

作者: 阿凡卢
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
http://www.cnblogs.com/luxiaoxun/p/4279997.html
相关文章
|
存储 缓存 NoSQL
跟着源码学IM(十一):一套基于Netty的分布式高可用IM详细设计与实现(有源码)
本文将要分享的是如何从零实现一套基于Netty框架的分布式高可用IM系统,它将支持长连接网关管理、单聊、群聊、聊天记录查询、离线消息存储、消息推送、心跳、分布式唯一ID、红包、消息同步等功能,并且还支持集群部署。
13515 1
|
7月前
|
消息中间件 Oracle Dubbo
Netty 源码共读(一)如何阅读JDK下sun包的源码
Netty 源码共读(一)如何阅读JDK下sun包的源码
134 1
|
NoSQL Java Redis
跟着源码学IM(十二):基于Netty打造一款高性能的IM即时通讯程序
关于Netty网络框架的内容,前面已经讲了两个章节,但总归来说难以真正掌握,毕竟只是对其中一个个组件进行讲解,很难让诸位将其串起来形成一条线,所以本章中则会结合实战案例,对Netty进行更深层次的学习与掌握,实战案例也并不难,一个非常朴素的IM聊天程序。 原本打算做个多人斗地主练习程序,但那需要织入过多的业务逻辑,因此一方面会带来不必要的理解难度,让案例更为复杂化,另一方面代码量也会偏多,所以最终依旧选择实现基本的IM聊天程序,既简单,又能加深对Netty的理解。
170 1
|
7月前
|
编解码 前端开发 网络协议
Netty Review - ObjectEncoder对象和ObjectDecoder对象解码器的使用与源码解读
Netty Review - ObjectEncoder对象和ObjectDecoder对象解码器的使用与源码解读
168 0
|
7月前
|
编解码 安全 前端开发
Netty Review - StringEncoder字符串编码器和StringDecoder 解码器的使用与源码解读
Netty Review - StringEncoder字符串编码器和StringDecoder 解码器的使用与源码解读
260 0
|
分布式计算 网络协议 前端开发
【Netty底层数据交互源码】
【Netty底层数据交互源码】
|
Java 容器
【深入研究NIO与Netty线程模型的源码】
【深入研究NIO与Netty线程模型的源码】
|
编解码 弹性计算 缓存
Netty源码和Reactor模型
Netty源码和Reactor模型
106 0
|
设计模式 监控 前端开发
第 10 章 Netty 核心源码剖析
第 10 章 Netty 核心源码剖析
134 0
|
编解码 分布式计算 Java
基于 netty 封装的超简单通俗易用 服务端客户端交互框架 《net-framework》原理,源码和使用说明,开箱即用,只需要开发业务逻辑,完全自定义无限扩充 [结尾附github源码]
基于 netty 封装的超简单通俗易用 服务端客户端交互框架 《net-framework》原理,源码和使用说明,开箱即用,只需要开发业务逻辑,完全自定义无限扩充 [结尾附github源码]
基于 netty 封装的超简单通俗易用 服务端客户端交互框架 《net-framework》原理,源码和使用说明,开箱即用,只需要开发业务逻辑,完全自定义无限扩充 [结尾附github源码]