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