js消息推送如何实现

JavaScript040

js消息推送如何实现,第1张

主要介绍其中的五种实现方式:短轮询、Comet、Flash XMLSocket、Server-sent、WebSocket

1、短轮询

指在特定的的时间间隔(如每10秒),由浏览器对服务器发出HTTP request,然后由服务器返回最新的数据给客户端的浏览器。浏览器做处理后进行显示。无论后端此时是否有新的消息产生,都会进行响应

2、Comet

包括了长轮询和长连接,长轮询是客户端向服务器发送Ajax请求,服务器接到请求后hold住连接,直到有新消息才返回响应信息并关闭连接,客户端处理完响应信息后再向服务器发送新的请求;长连接是在页面中的iframe发送请求到服务端,服务端hold住请求并不断将需要返回前端的数据封装成调用javascript函数的形式响应到前端,前端不断收到响应并处理

3、Flash XMLSocket

在 HTML 页面中内嵌入一个使用了 XMLSocket 类的 Flash 程序。JavaScript 通过调用此 Flash 程序提供的socket接口与服务器端的socket进行通信。JavaScript 在收到服务器端以 XML 格式传送的信息后可以很容易地控制 HTML 页面的内容显示

4、Server-sent

服务器推指的是HTML5规范中提供的服务端事件EventSource,浏览器在实现了该规范的前提下创建一个EventSource连接后,便可收到服务端的发送的消息,实现一个单向通信。客户端进行监听,并对响应的信息处理显示

5、WebSocket

WebSocket是HTML5下一种新的协议,是基于TCP的应用层协议,只需要一次连接,便可以实现全双工通信,客户端和服务端可以相互主动发送消息。客户端进行监听,并对响应的消息处理显示

针对自己系统的应用场景选择合适的推送方案才是合理的,因此最后简单说一下实现个性化推送的两种方式。第一种很简单,直接使用第三方实现的推送,无需复杂的开发运维,直接可以使用。第二种就是自己封装,可以选择如今较为火热的WebSocket来实现系统的推送。

关于第三方推送平台,极光推送,操作简单,稳定性高,送达率快

io = require('socket.io').listen(app), 

fs = require('fs'),

cookie=require('cookie')

request=require('request')

global.userlist={}

app.listen(8080)

//io.set('log level', 1)//将socket.io中的debug信息关闭

function handler (req, res) {

    res.writeHead(200, {

        'Content-Type': 'text/plain'

    })

    res.end('Hello World\n')

}

var content

var socketUser = {}

var settings={}

settings.host='http://localhost/test/node/myapp/'

io.sockets.on('connection', function (socket) {

    if(socket.handshake.headers.cookie){

        var curcookie=cookie.parse(socket.handshake.headers.cookie)

        var id=curcookie['PHPSESSID']

        request(settings.host+'getinfo.php?type=getinfo&sid='+id,function(err,res,body){

            if(!err&&res.statusCode==200){

                if(body){

                    body=eval('('+body+')')

                    var userid=body.ID

                    var username=body.UserName

                    var online=body.Online

                    //将新用户存进socket用户列表中

                    userlist[id]=socket

                

                    socketUser[id] = {

                        'userid':userid,

                        'username':username

                    }

                    //更改上线状态

                    request(settings.host+'getinfo.php?type=online&sid='+id,function(err,res,body){})

        

                    //发送信息给新登录用户

                    socket.emit('system',{

                        'alluser':socketUser

                    })

        

                    //上线欢迎

                    socket.emit('open',{

                        'msg':'welcome!'

                    })

        

                    //下线推送通知  disconnect方法名不能修改

                    socket.on('disconnect',function(){

                        //更改用户不在线

                        socketUser[id]=null

                        userlist[id]=null

                        request(settings.host+'getinfo.php?type=unline&sid='+id,function(err,res,body){})

                        socket.broadcast.emit('broadcast',{

                            'msg':'noline',

                            'unlineid':userid,

                            'unlinename':username,

                            'type':1

                        })

                    })

        

                    //监听接收用户信息

                    socket.on('sendnews', function (data) {

                        if(data.touserid&&userlist[data.touserid]!=undefined){

                            var user=userlist[data.touserid]

                            data.fromusername=socketUser[data.fromuserid].username

                            //将用户信息发送给指定用户

                            user.emit('receivenews',data)

                        }else{

                            socket.emit('receivenews',data)

                        }

                    })

    

                    //广播  推送已登录的用户

                    socket.broadcast.emit('broadcast',{

                        'userid':userid,

                        'username':username,

                        'type':2

                    })

                }else{

                    console.log('falseness connect') 

                }            

            }

        })      

    }else{

        console.log('cookie not exist')

    }

})

客户端代码:

<?php

$data = $_GET

if (!isset($data['username']) || $data['username'] === '' || !isset($data['id']) || $data['id'] === '') {

    header("location:login.php")

}

session_id($data['id'])

session_start()

$userid = $data['id']

$name = $data['username']

$con = mysql_connect("localhost", "root", "") or die("sds")

mysql_select_db("test", $con)

mysql_query("set names utf8")

$sql = 'select * from io_user where username="' . $name . '" and ID=' . $userid

$result = mysql_query($sql)

$res = mysql_fetch_assoc($result)

if (!$res) {

    header("location:login.php")

}

?>

<html lang="en">

    <head>

        <meta http-equiv="Content-Type" content="text/html charset=utf-8" />

        <title>Ssocket</title>

        <script type="text/javascript" src="public/javascripts/jquery.min.js"></script>   

        <script type="text/javascript" src="http://localhost:8080/socket.io/socket.io.js"></script>   

    </head>

    <body>

        <p>我的id:<?php echo $userid ?></p>

        <p>我的名字:<?php echo $name ?></p>

        <h4>在线用户列表</h4>

        <table border="1" id="userlists">

            <thead>

                <tr>

                    <th width="80px">ID</th>

                    <th width="80px">用户名</th>

                    <th width="80px">选中</th>

                </tr>

            </thead>

            <tbody>

            </tbody>

        </table>

        <p style="margin-top:10px">

            信息:

            <input type="text" style="width:338px" id="content">

            <button id="send">发送</button>

        </p>

        <div id="msg"></div>

        <div id="unline"></div>

        <script type="text/javascript">

            var userid='<?php echo $userid ?>'

            var username='<?php echo $name ?>'

            var socket = io.connect('http://localhost:8080')

            

            //欢迎信息

            socket.on('open',function(res){

                console.log(res)

            })

            

            //无连接

            socket.on('disconnect',function(res){

                console.log('not connect')

            })

            

            //接收用户消息

            socket.on('receivenews',function(res){

                var html='<p>来自用户 ('+res.fromusername+') 的消息: '+res.content+'</p>'

                $('#msg').append(html)

            })

            

            //接收系统消息

            socket.on('system',function(res){  

                if(res.alluser){

                    var html=''

                    var time=0

                    $.each(res.alluser,function(k,v){

                        if(v==null||v.userid==userid){

                            return

                        }

                        time++

                        html+='<tr userid="'+v.userid+'"><td>'+time+'<td>'+v.username+'</td>'

                        html+='<td><input type="checkbox" class="checkbox" userid="'+v.userid+'"></td></tr>'  

                        

                    })

                    $('#userlists tbody').html(html)                   

                }

            })

            

            //获取推送信息

            socket.on('broadcast',function(res){ 

                if(res.type==1&&res.unlineid!=userid){

                    $('#userlists tbody tr[userid="'+res.unlineid+'"]').remove()

                    $('#unline').append('<p>用户'+res.unlinename+'离线</p>')

                    return false

                }

                if(res.type==2&&res.userid){

                    if(res.userid==userid){

                        return false

                    }

                    if($('#userlists tbody tr[userid="'+res.userid+'"]').length>0){

                        return false

                    }

                    var html=''

                    var length=$('#userlists tbody tr').length

                    html+='<tr userid="'+res.userid+'"><td>'+(length+1)+'<td>'+res.username+'</td>'

                    html+='<td><input type="checkbox" class="checkbox" userid="'+res.userid+'"></td></tr>' 

                    $('#userlists tbody').append(html)    

                    $('#unline').append('<p>用户'+res.username+'上线</p>')

                    return false

                }

            })

            

            $(function(){

                $('.checkbox').live('click',function(){

                    if($(this).attr('checked')=='checked'){

                        $('.checkbox').removeAttr('checked')

                        $(this).attr('checked',true)

                    }

                    

                })

                

                //输入框回车事件

                $("#content").keyup(function(e){

                    if(e.keyCode==13){

                        $('#send').trigger('click')

                    }

                    return false

                })

                

                $('#send').click(function(){

                    var content=$('#content').val()

                    var data={}

                    var touserid=$('.checkbox[checked]').attr('userid')

                    if(touserid==undefined){

                        alert('请选择用户')

                        return false

                    }

                    if(content!=''){

                        $('#content').val('')

                        data.fromuserid=userid

                        data.touserid=touserid

                        data.content=content

                        //发送信息

                        socket.emit('sendnews',data)

                    }

                })

            })

        </script>

    </body>

</html>

websocket它是一种长连接,通过websocket我们能实现后端向前端推送数据,前端也可以向后端推送数据。这里我们主要讲前端H5 websocket怎样和nodejs配合。

因为它承载了socket大部分功能,而且相对稳定

文件在node_modules/socket.io-client/dist/socket.io.js