EventSource
2015-11-30 11:30
211 查看
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);
View Code
后台使用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事件。
相关文章推荐
- centos源码安装git
- [Javascript] RegExp 正则
- Spring的注解
- L10 keepalived 基本使用(主备模式)
- linux下的线程锁----原子锁
- github 如何合并不同分支
- 稀疏表达和压缩感知的一些对比
- 插件式开发
- WPF自定义控件与样式(9)-树控件TreeView与菜单Menu-ContextMenu
- windows下python程序开机自启动
- 自定义UIAlertView第三方类库
- pAdTy_2 构建连接网络和云的应用程序
- 如何为KDE/XFCE桌面系统安装坚果云
- 快速排序
- js 去空格
- ARM 关于PINSEL的解释
- absolute的left和right的妙用
- urllib
- div css 多行文本 最后一行自动显示省略号
- IOS学习之 网络编程(5)--多线程断点下载