<!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. 怎样手动添加 Sublime 3 右键菜单

    [Version] Signature="$Windows NT$" [DefaultInstall] AddReg=SublimeText3 [SublimeText3] hkc ...

  2. 一个平台BUG,好吧,找到了一个新的办法,同样的效果

    问题的来源,我是看到别人这么做,我只是看到了这个程序运行的视频,具体是当你选择通信方式时1  COM ,  2  网口:要求在combobox中选择,selectindex为0时显示COM的选项,为1 ...

  3. 1350. Primary Arithmetic

    Children are taught to add multi-digit numbers from right-to-left one digit at a time.  Many find th ...

  4. Linux和Windows下ping命令详解(转:http://linux.chinaitlab.com/command/829332.html)

    一.Linux下的ping参数 用途 发送一个回送信号请求给网络主机. 语法 ping [ -d] [ -D ] [ -n ] [ -q ] [ -r] [ -v] [ \ -R ] [ -a add ...

  5. 错误,这个如何解决呢?内存溢出的问提。把JAVA_OPTS="-server -XX:PermSize=64M -XX:MaxPermSize=128m 还是不行

    java.lang.OutOfMemoryError: PermGen space at java.lang.ClassLoader.defineClass1(Native Method) at ja ...

  6. java 中继承,组合,重载,重写的实现原理 (转)

    我们知道,继承,组合,重载,重写是java语言的面向对象实现的基本特征. 那么在java内部,究竟是如何实现这些面对对象的基本特征的呢? 继承和组合是面向对象中代码复用的主要实现方式,他们可以达到类似 ...

  7. java list倒序输出及复制list集合

    如原来有一个集合list,list里面是有数据的,现在如果把list中的集合倒序过来,加这代码 Collections.reverse(list);此代码中传入原来的list数据 有这代码后list在 ...

  8. android常见问题

    1.广播接收器中启动Activity,需要在intent中添加FLAG_ACTIVITY_NEW_TASK /** * Demo描述: * 在BroadcastReceiver中启动Activity的 ...

  9. Hadoop之Hive(2)--配置Hive Metastore

    Hive metastore服务以关系性数据库的方式存储Hive tables和partitions的metadata,并且提供给客户端访问这些数据的metastore service的API.下面介 ...

  10. [问题2014S07] 复旦高等代数II(13级)每周一题(第七教学周)

    [问题2014S07]  设 \(A\in M_n(\mathbb{K})\) 在数域 \(\mathbb{K}\) 上的初等因子组为 \(P_1(\lambda)^{e_1},P_2(\lambda ...