在没有websocket技术之前,我们想要在网页上面进行长时间的通讯聊天,一般都用的是AJAX轮循,直到现在AJAX轮循依然被很多网站广泛使用,这种传统的绑定交互模式虽然有比较良好的兼容性,但其性能问题令人堪忧,并且延时调用并不能实现真正意义上面的“即时通讯”,比如有高质量链接效率的游戏、聊天、股票等等,这种将交互频率精确于毫秒之间的是不可能通过ajax轮循实现的,本篇文章就为大家来介绍一下websocket在nodeJs下面的使用场景。
本次demo的源码:https://github.com/renjianfeng/nodejs/tree/master/gamesocket
关于nodejs-websocket
nodejs-websocket
是nodejs
的一个框架,用于实现基于nodeJS
的websocket
模块封装。
它的优点是可以利用js的事件驱动模型进行更加友好、简单的进行websocket握手链接。
关于websocket
WebSocket protocol 是HTML5一种新的协议。它实现了浏览器与服务器全双工通信(full-duplex)。一开始的握手需要借助HTTP请求完成。
浏览器支持情况
IE 9以上,chrome/firefox
在nodeJS环境下使用npm安装nodejs-websocket
npm install nodejs-websocket
这个例子中,我们实现一个很简单的交互游戏;
现在有两个页面test.html和test2.html,
我们在test.html里面可以通过监听按键的w、s、a、d或方向键可以让test.html里面的方块进行上下左右的移动,同时可以在test2.html里面看到一个方块和test.html里面的方块同步移动。
别小看这些,也许这个是你开发网络游戏的关键。
首先创建服务器端代码index.js
//引入nodejs-websocket var ws = require("nodejs-websocket"); console.log("开始建立连接...") //game1为test.html传过来的websocket链接对象 //game2为test2.html传过来的websocket链接对象 //game1Ready game2Ready为两个页面的链接状态 var game1 = null,game2 = null , game1Ready = false , game2Ready = false; var server = ws.createServer(function(conn){ conn.on("text", function (str) { console.log("收到的信息为:"+str) if(str==="game1"){ game1 = conn; game1Ready = true; conn.sendText("success"); } if(str==="game2"){ game2 = conn; game2Ready = true; } if(game1Ready&&game2Ready){ //把str推送给game2 game2.sendText(str); } conn.sendText(str) }) conn.on("close", function (code, reason) { console.log("关闭连接") }); conn.on("error", function (code, reason) { console.log("异常关闭") }); }).listen(8001,'127.0.0.1') console.log("WebSocket建立完毕")
客户端test.html页面
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>操作端</title> <style> .value{width: 200px;height:200px;border:1px solid;text-align: center; margin-top:200px;margin-left:200px;line-height: 200px;display: block;position: absolute;} </style> </head> <body> <div id="mess">正在连接...</div> <div class="kuang"> <div class="value" id="value1">盒子的位置</div> </div> <script> // !(function(){})() var mess = document.getElementById("mess"); //向127.0.0.1:8001发起WebSocket请求 var ws = new WebSocket('ws://127.0.0.1:8001'); if(window.WebSocket){ ws.onopen = function(e){ console.log("连接服务器成功"); //请求的对象名为game1 ws.send("game1"); } ws.onclose = function(e){ console.log("服务器关闭"); } ws.onerror = function(){ console.log("连接出错"); } ws.onmessage = function(e){ mess.innerHTML = "连接成功,按住“w,s,a,d或方向键,test2.html中的div位置会跟随test.html中的位置!" document.onkeydown = test; } } var _top=200; var _left=200; var positionXY=[] var moveForward,moveLeft,moveBackward,moveRight function test(){ //监听按键状态 var onKeyDown = function ( event ) { switch ( event.keyCode ) { case 38: // up case 87: // w moveForward = true; break; case 37: // left case 65: // a moveLeft = true; break; case 40: // down case 83: // s moveBackward = true; break; case 39: // right case 68: // d moveRight = true; break; } }; var onKeyUp = function ( event ) { switch( event.keyCode ) { case 38: // up case 87: // w moveForward = false; break; case 37: // left case 65: // a moveLeft = false; break; case 40: // down case 83: // s moveBackward = false; break; case 39: // right case 68: // d moveRight = false; break; } }; document.addEventListener( 'keydown', onKeyDown, false ); document.addEventListener( 'keyup', onKeyUp, false ); if(moveForward){ //w _top=_top-3; document.getElementById("value1").style.marginTop="+"+_top+"px"; console.log(_top) //将盒子个坐标赋值给一个数组 positionXY=[_top,_left] //将当前位置的数组positionXY推送到服务器 ws.send(positionXY); } if(moveBackward){ //s _top=_top+3; document.getElementById("value1").style.marginTop="+"+_top+"px"; console.log(_top) positionXY=[_top,_left] ws.send(positionXY); } if(moveLeft){ //a _left=_left-3; document.getElementById("value1").style.marginLeft="+"+_left+"px"; positionXY=[_top,_left] ws.send(positionXY); } if(moveRight){ //d _left=_left+3; document.getElementById("value1").style.marginLeft="+"+_left+"px"; positionXY=[_top,_left] ws.send(positionXY); } } </script> </body> </html>
客户端test2.html页面
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>接收端</title> <style> .value{width: 200px;height:200px;border:1px solid;text-align: center; margin-top:200px;margin-left:200px;line-height: 200px;display: block;position: absolute;} </style> </head> <body> <div id="mess">websocket练习:注意这是一个群组接收端,div的位置会被当前服务中的多人操作影响!网络不流畅时会有延迟。</div> <div class="kuang"> <div class="value" id="value1">盒子的位置</div> </div> <script> var mess = document.getElementById("mess"); if(window.WebSocket){ var ws = new WebSocket('ws://127.0.0.1:8001'); ws.onopen = function(e){ console.log("连接服务器成功"); ws.send("game2"); } ws.onclose = function(e){ console.log("服务器关闭"); } ws.onerror = function(){ console.log("连接出错"); } ws.onmessage = function(e){ //获取服务器发送过来的值 var string = e.data; //转化为数组 var ss = string.split(","); //绑定到状态 document.getElementById("value1").style.marginTop="+"+ss[0]+"px"; document.getElementById("value1").style.marginLeft="+"+ss[1]+"px"; console.log(e.data) } } </script> </body> </html>
运行 index.js
然后分别在两个窗口打开test.html和test2.html 如果链接成功则会有下面的效果
test.html中的方块按w、a、s、d或方向键会有移动效果,同时test2.html中的方块会跟随其移动。同时nodejs的控制台会输出方块的坐标
rrr
r
vv
新手学习中~感谢分享!