<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>EventSource</title>
</head>
<body>
<script>
window.onload=function(){
name();
function name(){
var username=prompt("请输入您的昵称");
if(!username){
return false;
}
var xml=new XMLHttpRequest();
xml.open("POST","/addUser");
xml.send("name="+username);
xml.onreadystatechange=function(){
if(xml.status=200&&xml.readyState==4){
var res=JSON.parse(xml.responseText)
if(res.success=="ok"){
alert("欢迎你的加入");
window.hiddenValue.value=res.name;
var es = new EventSource("/chat");
es.addEventListener("message", function(e){
var temp=document.createElement("li");
temp.innerHTML= e.data;
window.message.scrollIntoView();
window.content.appendChild(temp);
},false);
}else{
alert(res.msg+",如果你还想加入,行刷新重新输入用户名称");
//本来用的递归,但是体验不好,就改了
//name();
}
}
}
}
var div=document.getElementsByTagName("div")[0]
div.style.width=window.innerWidth+"px";
}
function sendMessage(){
var message=window.message.value;
if(message.trim()){
var b=new XMLHttpRequest();
b.open("POST","/chat");
b.send("message="+window.message.value+"&name="+ window.hiddenValue.value);
}
} </script>
<div>
<ul id="content">
</ul>
</div>
<input type="text" name="message" id="message" /><input type="button" value="发送" onclick="sendMessage()"/>
<input type="hidden" id="hiddenValue">
</body>
</html>
var server=require("http");
var url=require("url");
var file=require("fs");
var querystring=require("querystring");
var clientName=[];
var responseArray=[]; server.createServer(function (request, response) {
var message="";
var name="";
var urlContent=url.parse(request.url); //首页
if(urlContent.pathname=="/"){
response.writeHead(200,{"Content-Type":"text/html;charset=utf-8"});
file.readFile("../views/Index.html",function(err,data){
response.end(data);
})
return false;
}
else if(urlContent.pathname=="/chat"){ //发送消息
if(request.method=="POST"){ //并不能根据response得到正确的name索引,所以前台传递name
request.on("data",function(data){
data= querystring.parse(data.toString());
message+=decodeURIComponent(data.message.trim());
name+=decodeURIComponent(data.name.trim());
})
request.on("end",function(){
responseArray.forEach(function(i){
i.write("data:"+name+"说:"+message+"\n\n");
})
})
response.end();
}else{ //建立长连接,保存相应
responseArray.push(response);
response.writeHead(200,{"Content-Type":"text/event-stream"});
response.write("data:已连接至服务器\n\n");
request.connection.on("end",function(){
var index=responseArray.indexOf(response)
clientName.splice(index,1);
responseArray.splice(index,1);
response.end();
})
}
}else if(urlContent.pathname=="/addUser"){ //添加用户名
request.on("data",function(data){
data= querystring.parse(data.toString().trim());
name+=decodeURIComponent(data.name.trim());
});
request.on("end",function(){
response.writeHead(200,{"Content-Type":"text/json;charset=utf-8"});
if(clientName.some(function(i){
if(i==name) return true;
})){
response.write("{\"success\":\"fail\",\"msg\":\"用户名重复\"}")
}else{
response.write("{\"success\":\"ok\",\"name\":\""+name+"\"}");
responseArray.forEach(function(i){
i.write("data:欢迎"+name+"的加入"+"\n\n");
})
clientName.push(name);
}
response.end(); })
}
else{
response.writeHead(404,{"Content-Type":"text/json"});
response.end();
}
}).listen(8012);

后台使用Node.js  博主是一个新人,会有很多不太适合的代码,希望大家能多多帮助。代码中注意路径问题。代码仍有缺陷,现在连接断开,不一定能够删除用户名称。以下的总结都是基于上面的代码的,如果有其他情况,麻烦您给我说一下,谢谢。

 
可以跟服务器建立一个保持连接状态的连接,这样服务器能在服务端来对客户端推送信息。服务端在推送的时候要注意格式。write的内容必须是data:内容的,当write中的内容 有一个空行的时候就会推送消息,推送后,会触发EventSource的message事件,事件对象的data属性为推送的消息内容。
当write的时候发现客户端不再保持连接的时候,就会断开连接,如果还在write,就会触发write after end错误。只有服务端第一次wirte的时候才算连接成功,第一次write即使没有空格不进行推送,客户端也会得到200的状态,正式建立连接。如果服务端没有进行及时的write,则客户端认为还在请求过程中,等待服务端响应,会有一个等待时间,在等待的时间内write会正确的建立200链接。如果超过等待时间还是没有write,则请求将会失败,将重新发起请求。如果服务端明确发回404,并且response结束,则不会再次发出请求,否则,长连接请求会一直等待正式建立连接,并过时,再请求。
第一个长连接请求在进行请求的时候,一直没有建立正式的连接,超时后,会再次发送一个连接,在Chrome中观看的话,同一个network发了两次请求,但是这两次请求的是不同的请求
 
open事件为服务器连接打开的时候触发
error当发生错误的时候出发
 
如果服务器一直不触发messag事件,则过了一段时间后,不管还以前的连接是否还在,都会重新发起一个请求。服务器与客户端针对一个EventSource的request和response只存在一个,用前面的response.write的时候,将不会推送到客户端(此response已经被客户端放弃),如果连接建立后,服务器停掉了,则客户端会一直发送长连接请求。当在客户端使用eventsource的close或者关闭网页的时候,触发自己和服务器对应的request.connection的end事件。

EventSource的更多相关文章

  1. Html5实践之EventSource

    最近尝试了一下服务器端的推送,之前的做法都是客户端轮询,定时向服务器发送请求.但这造成了我的一些困扰: 1:轮询是由客户端发起的,那么在服务端就不能判别我要推送的内容是否已经过期,因为我很难判断某个信 ...

  2. EventSource (node.js 与 OC)

    node.js服务器代码: var http = require('http'); http.createServer(function (req, res) { res.writeHead(200, ...

  3. HTML5 EventSource的用法

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  4. 服务端事件EventSource揭秘

    服务端推 服务端推,指的是由服务器主动的向客户端发送消息(响应).在应用层的HTTP协议实现中,"请求-响应"是一个round trip,它的起点来自客户端,因此在应用层之上无法实 ...

  5. H5 EventSource 实现web页面推送功能demo

    /** * H5 EventSource 实现web页面推送功能demo */ var serverData,statusDiv; var SERVER_URL = "index.php&q ...

  6. polyfill-eventsource added missing EventSource to window ie浏览器 解决方案

    今天遇到一个 ie浏览器显示空白,报错内容是: polyfill-eventsource added missing EventSource to window的问题, import 'babel-p ...

  7. EventSource 对象用于接收服务器发送事件通知,是网页自动获取来自服务器的更新

    //--------------------------------客户端代码----------------------------- if(typeof(EventSource) !== &quo ...

  8. 通过html5 的EventSource来进行数据推送

    以往我们要获取服务器的数据更新,一般通过ajax的定时请求,不过这样效率就低了.我们通过html5的EventSource可以很方便的获取服务器的数据更新,不过IE好像不支持.   例1如下: ind ...

  9. 【JavaScript】论一个低配版Web实时通信库是如何实现的之二( EventSource篇)

    前情提要 「 话说上回说到!那WebSocket大侠,巧借http之内力,破了敌阵的双工鸳鸯锁,终于突出重围. 然而玄难未了,此时web森林中飞出一只银头红缨枪,划破夜色. "莫非!?&qu ...

随机推荐

  1. paper 102:极限学习机(Extreme Learning Machine)

    原文地址:http://blog.csdn.net/google19890102/article/details/18222103   极限学习机(Extreme Learning Machine) ...

  2. Excel应该这么玩——4、命名区域:搞定下拉框

    前三篇都是讲的给Excel元素命名,本篇再介绍一种命名的使用方式:命名区域.区域是多个单元格的集合,可以是单行.单列或者类似表格的单元格矩阵,也可以是不连续的多个单元格,但很少用到.当然,一个单元格也 ...

  3. jenkins解决jenkins内存溢出问题

    在jenkins master-slave配置中,总是出现内存溢出问题,更换了机器设备仍然跑不起来: 问题如下: Status Code: 500 Exception: org.apache.comm ...

  4. 十九、Java基础--------IO流之字节流

    在上一篇文章中介绍了IO体系以及一些基本概念和字符流的相关应用,本文着重介绍字节流的相关操作. 字节流 它的操作与字符流类似,可以参与字符流的定义.读取.写入.处理异常的格式,只不过是处理的数据不同, ...

  5. 详解 Array.prototype.slice.call(arguments)

    首先,slice有两个用法,一个是String.slice,一个是Array.slice,第一个返回的是字符串,第二个返回的是数组 在这里我们看第二个方法 1.在JS里Array是一个类 slice是 ...

  6. postgresql如何实现回收站机制

         在oracle10G之后:oracle提供一种回收站的机制:即闪回技术.闪回技术通常用于快速简单恢复数据库中出现的认为误操作等逻辑错误.发展到11G之后:回收站更加完善:对在可闪回时间内:数 ...

  7. viewport 详解

    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale= ...

  8. 我的android学习经历39

    关于像第一次进qq一样的那个渐变企鹅图的制作 渐变动画 package com.moonweather.app.activity; import com.moonweather.app.R; impo ...

  9. 【leetcode❤python】 225. Implement Stack using Queues

    #-*- coding: UTF-8 -*-class Stack(object):    def __init__(self):        """        i ...

  10. 从零开始HTML(一 2016/9/19)

    就是准备跟着W3C上的教程过一遍HTML啦,边看边记录更便于理解记忆吧~ 1.属性 HTML 标签可以拥有属性.属性提供了有关 HTML 元素的更多的信息.属性总是以名称/值对的形式出现,比如:nam ...