使用nodeJs实现webSocket,比较流行使用socket.io,nodeJs比较流行一些只是io操作的方式,
比如截图修图什么的,还有聊天,推送之类的,socket.io就是实现聊天或推送之类的。
webSocket是h5出的新东西,因为长连接和短连接,还有轮询之类的太浪费资源了,所以
出现了webSocket协议,其实就是http转TCP的过程,只是它是可以实现客户端到服务器端,还有
服务器端到客户端发送请求的过程,因为一般http请求都只能客户端到服务器端,不能服务器端到
客户端,而为了服务器端也能发送内容,需要长连接或别的之类,这样会很浪费资源,所以出现webSocket,
webSocket就是两头都可以实现发送。
而node实现很简单,不过如果关系到多节点服务器或负载均衡那就比较麻烦,这个暂时不会,不过一般不上百万并发量
应该没有问题的。
node:
//公式写法var express=require(‘express‘);var app = express();var server = require(‘http‘).Server(app);//一定需要这个,不是页面不能引入socket.iovar io = require(‘socket.io‘)(server);var session = require(‘express-session‘);app.use(session({ ?secret: ‘keyboard cat‘, ?resave: false, ?saveUninitialized: true}));server.listen(3000);app.set("view engine","ejs");app.use(express.static("./public"));var chartPerArr=[];app.get(‘/‘, function (req, res) { ?res.render("index");});app.get("/login",function(req,res){ ???var name=req.query["name"]; ???if(chartPerArr.indexOf(name)!=-1){ ???????res.end("用户名已存在!!!"); ???????return; ???} ???req.session.usename=name; ???chartPerArr.push(name); ???res.redirect("/chart");});app.get(‘/chart‘, function (req, res) { ???if(!req.session.usename){ ???????res.redirect("/"); ???????return ; ???} ???var name=req.session.usename; ?????res.render("chart",{ ?????????name:name ?????});});app.get("/leave",function(req,res){ ???delete req.session.usename;});/*=====================socket.io====================================*///保存当前用户名和socketvar users={};var userArr=[]; ???/*每个用户连接都会产生一个socket对象,connection的回调函数每次 ???????有用户访问都会调用一次,会返回一个socket ???????所以可以保存当前socket来实现私聊 ???????退出只要删除保存的当前的socket对象就可以了 ???????虽然io.scokets有保存这个对象,如果不会可以自己来实现 ???????io是面向所有连接socket对象,所以使用io对象会向所有用户发送 ???*/io.on(‘connection‘, function (socket) { ???//监听进入的用户 ?socket.on(‘join user‘, function (data) { ?????if(!users[data.username]){ ?????????userArr.push(data.username); ?????} ?????users[data.username]={}; ?????users[data.username]["usename"]=data.username; ?????users[data.username]["socket"]=socket; ?????io.emit(‘join user‘,userArr); ?}); ?socket.on("chart msg",function(data){ ?????if(data.type==1){ ?????????sendAllMsg(data); ?????}else if(data.type==2){ ?????????sendUserMsg(data); ?????} ?}); ?//离开 ?socket.on("leave chart",function(data){ ?????leaveHome(data); ?????socket.broadcast.emit("leave chart",data); ???socket.broadcast.emit(‘join user‘,userArr); ?});});//私聊function sendUserMsg(data){ ???console.log("私聊中..."); ???users[data.to]["socket"].emit(data.to,data); ???users[data.name]["socket"].emit(data.name,data);}//对所有广播消息function sendAllMsg(data){ ???io.emit("charts",data);}//离开function leaveHome(data){ ???if(userArr.indexOf(data.name)==-1){ ???????return ; ???} ???delete users[data.name]; ???userArr.splice(1,userArr.indexOf(data.name));}
登录页面:
<!DOCTYPE html><html lang="en"><head> ???<meta charset="UTF-8"> ???<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> ???<title>聊天室</title> ???<link rel="stylesheet" href="/lib/css/bootstrap.min.css"> ???<style> ???.h1{ ???????text-align: center; ???} ???.btnG{ ???????margin-top: 15px; ???} ???.w{ ???????width: 90%; ???????margin: 0 auto; ???} ???</style></head><body><h1 class="h1">聊天室</h1><div class="container login" id="login"> ???<div class="row"> ???????<div class="w"> ???????????<input id="idName" class="form-control" type="text" placeholder="请输入名称"> ???????</div> ???</div> ???<div class="row btnG"> ???????<div class="col-md-1 col-lg-1"> ???????????<button type="button" id="goChartBtn" class="btn btn-default" >进入聊天室</button> ???????</div> ???</div></div><form action="/login" type="get" name="chart"> ???<input type="hidden" name="name" id="name"></form><script src="/lib/js/jquery-3.1.0.min.js"></script><script src="/lib/js/bootstrap.min.js"></script><script>$("#goChartBtn").click(function(){ ???var val=$.trim($("#idName").val()); ???if(val==""){ ???????return ; ???} ???$("#name").val(val); ???document.chart.submit();});</script></body></html>
聊天页面:
<!DOCTYPE html><html lang="en"><head> ???<meta charset="UTF-8"> ???<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> ???<title>聊天室</title> ???<link rel="stylesheet" href="/lib/css/bootstrap.min.css"> ???<style> ???.h1{ ???????text-align: center; ???} ???.panel-body{ ???????height: 400px; ???????overflow: auto; ???} ???.footer{ ???????position: fixed; ???????bottom: 10px; ???????left: 0; ???????width: 100%; ???} ???.chartText{ ???????width: calc(100% - 60px); ???????display: inline-block; ???} ???</style></head><body><div class="panel panel-default"> ?<div class="panel-heading"> ???<h3 class="panel-title">聊天室,欢迎:<span id="uName"><%=name%></span></h3> ?</div> ?<div class="panel-body"> ???<ul class="list-group" id="fayan"> ?????????????</ul> ?</div></div><div class="footer"> ???<div class="all"> ???????<select name="all" id="all"> ???????????<option value=""></option> ???????</select> ???</div> ???<input type="text" name="chart" placeholder="请发言..." class="form-control chartText" id="chart"><button class="btn" id="send">发送</button> ???<button class="btn btn-lg btn-danger" id="leave">离开</button></div><script src="/socket.io/socket.io.js"></script><script src="/lib/js/jquery-3.1.0.min.js"></script><script src="/lib/js/bootstrap.min.js"></script><script>var socket = io();var username=$("#uName").text();socket.emit("join user",{ username:username });//所有用户展示socket.on("join user",function(data){ ???$("#all").empty(); ???var opt=‘<option value="_val_">_val_</option>‘; ???var str=‘<option value="charts">所有</option>‘; ???for(var i=0;i<data.length;i++){ ???????if(data[i]!=username){ ???????????str+=opt.replace(/_val_/g,data[i]); ???????} ???} ???$("#all").html(str);});//私聊socket.on(username,function(data){ ???$("#fayan").prepend(‘<li class="list-group-item"><span>私聊:‘+data.name+‘</span>:<span>‘+data.d+‘</span></li>‘);});//所有socket.on("charts",function(data){ ???$("#fayan").prepend(‘<li class="list-group-item"><span>所有:‘+data.name+‘</span>:<span>‘+data.d+‘</span></li>‘);});//离开socket.on("leave chart",function(data){ ???$("#fayan").prepend(‘<li class="list-group-item"><span>‘+data.name+‘</span><span>‘+data.d+‘</span></li>‘);});$("#chart").on("keyup",function(e){ ???????if(e.keyCode==13){ ???????????sendSocket(); ???????} ???}); ???$("#send").on("click",function(){ ???????sendSocket(); ???});function sendSocket(){ ???????var val=$("#chart").val(); ???????if(val==""){ ???????????return ; ???????} ???????var sel=$("#all").val(); ???????if(sel=="charts"){ ???????????socket.emit("chart msg", { ????????????????type:"1", ???????????????name:$("#uName").text(), ???????????????d: val ????????????}); ???????}else{ ???????????socket.emit("chart msg", { ????????????????type:"2", ???????????????to:sel, ???????????????name:$("#uName").text(), ???????????????d: val ????????????}); ???????} ???????????????$("#chart").val(""); ???}$("#leave").click(function(){ ???socket.emit("leave chart",{ ???????name:$("#uName").text(), ???????d:"离开..." ???}); ???$.get("/leave"); ???window.location.reload();});</script></body></html>
这个比较厉害的是互相之间可以送对象,那很简单,所以可以进行一个你猜我答之类的画图。
webSocket
原文地址:http://www.cnblogs.com/zhangzhicheng/p/7664210.html