产品网站中很多地方需要用到实时交互,web端的实时交互。
具体为活动抽奖案例:
现场一个大屏,显示中奖人列表相关信息;
主持人一个pad控制开始抽奖结束抽奖;
每个活动现场的观众的手机。用来摇动手机进行抽奖
毫无疑问用websocket,WebSocket相较于HTTP来说,有很多的优点,主要表现在WebSocket只建立一个TCP连接,可以主动推送数据到客户端,而且还有更轻量级的协议头,减少数据传送量。所以WebSocket暂时来说是实时通讯的最佳协议了
至于服务器语言选择nodeJs,是因为NodeJs本身事件驱动的方式很擅长与大量客户端保持高并发的连接。所以就选择NodeJs了。
安装nodejs,然后再安装一个nodejs-websocket的模块。然后就可以开始建立服务器了,因为有了nodejs-websocket模块,所以很多工作都不用我们自己做,直接调用别人封装好的方法就行了
服务器代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 var ws = require("nodejs-websocket") 2 var net = require('net') 3 4 var clients_luck_show= new Array(); 5 var clients_luck_control= new Array(); 6 var clients_luck_client= new Array(); 7 var datas= new Array(); 8 9 10 // Scream server example: "hi" . "HI!!!"11 var server = ws.createServer(function (conn) {12 conn.on("text", function (str) {13 onData(str,conn);14 })15 conn.on("close", function (code, reason) {16 onDisconnect();17 })18 })19 server.listen(8000)20 21 22 function onDisconnect(){23 console.log("connect close");24 clients_luck_show.length=0;25 clients_luck_control.length=0;26 clients_luck_client.length=0;27 }28 29 function onData(data,conn){30 console.log("data="+data);31 32 //conn.sendText(str);33 var json = JSON.parse(data); 34 switch (json.action){35 case "reg":36 regClient(JSON.parse(data),conn);37 break;38 case "luckcontrol":39 sendtoclient(clients_luck_show,json,data);40 sendtoclient(clients_luck_client,json,data);41 break;42 case "luckok":43 sendtoclient(clients_luck_show,json,data);44 break;45 case "luckend":46 sendtoclient(clients_luck_show,json,data);47 sendtoclient(clients_luck_control,json,data);48 sendtoclient(clients_luck_client,json,data);49 break;50 51 }52 }53 54 function regClient(json , conn){55 var id = conn.key;56 datas[id] = json.showid;57 switch (json.type){58 case "luck_show":59 clients_luck_show[conn.key]=conn;60 break;61 case "luck_client":62 clients_luck_client[conn.key]=conn;63 break;64 case "luck_control":65 clients_luck_control[conn.key]=conn;66 break;67 }68 69 conn.sendText(json.type+",注册成功");70 71 }72 73 74 75 function sendtoclient(clients,json,data) {76 console.log("---------------------------------------------------------");77 for(var key in clients){78 var id = clients[key].key;79 if(datas[id] == json.showid){80 clients[key].sendText(data);81 console.log("sendText="+data);82 }83 } 84 85 86 }
主持人控制端js代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
/*远程控制开始----------------------------------------------*/ var ws = null; function init_connect() { if(ws == null){ // 取得WebSocket连接入口(WebSocket URI) var target = "ws://"+window.location.hostname+":8000"; // 创建WebSocket if ('WebSocket' in window) { ws = new WebSocket(target); } else if ('MozWebSocket' in window) { ws = new MozWebSocket(target); } else { alert('本浏览器不支持远程控制功能,请使用支持HTML5的浏览器。'); return; } // 定义Open事件处理函数 ws.onopen = function () { setConnected(true); reg_luck_control(); }; // 定义Message事件处理函数(收取服务端消息并处理) ws.onmessage = function (event) { processMessage(event.data) console.log('Received: ' + event.data); }; // 定义Close事件处理函数 ws.onclose = function () { ws = null; setConnected(false); }; } } // 关闭WebSocket连接 function disconnect() { if (ws != null) { ws.close(); ws = null; } setConnected(false); } function setConnected(connected) { if(connected){ console.log('Info: WebSocket connection opened.'); } else{ console.log('Info: WebSocket connection closed.'); } } //注册控制端 function reg_luck_control(){ if (ws != null) { var message = {action:"reg",type:"luck_control",showid:" "}; // 向服务端发送消息 var msg =JSON.stringify(message); console.log(msg); ws.send(msg); } else { init_connect(); } } function processMessage(msg){ var data=msg; if(typeof(msg) == "string"){ try{ data = JSON.parse(msg); }catch(e){ console.log(msg); return; } } if(data.action=="luckend"){ init_page(); } }
大屏端js代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
/*远程控制开始----------------------------------------------*/ var ws = null; function init_connect() { if(ws == null){ // 取得WebSocket连接入口(WebSocket URI) var target = "ws://"+window.location.hostname+":8000"; // 创建WebSocket if ('WebSocket' in window) { ws = new WebSocket(target); } else if ('MozWebSocket' in window) { ws = new MozWebSocket(target); } else { alert('本浏览器不支持远程控制功能,请使用支持HTML5的浏览器。'); return; } // 定义Open事件处理函数 ws.onopen = function () { setConnected(true); reg_luck(); select_luckstate(); }; // 定义Message事件处理函数(收取服务端消息并处理) ws.onmessage = function (event) { processMessage(event.data) console.log('Received: ' + event.data); }; // 定义Close事件处理函数 ws.onclose = function () { ws = null; setConnected(false); }; } } // 关闭WebSocket连接 function disconnect() { if (ws != null) { ws.close(); ws = null; } setConnected(false); } function setConnected(connected) { if(connected){ console.log('Info: WebSocket connection opened.'); } else{ console.log('Info: WebSocket connection closed.'); } } function reg_luck(){ if (ws != null) { var message = {action:"reg",type:"luck_show","showid":" "} // 向服务端发送消息 var msg =JSON.stringify(message); console.log(msg); ws.send(msg); } else { init_connect(); } } function processMessage(msg){ var data=msg; if(typeof(msg) == "string"){ try{ data = JSON.parse(msg); }catch(e){ console.log(msg); return; } } if(data.action=="luckcontrol"){ //来自抽奖控制页面的命令 console.log('luckcontrol: '+msg); select_luckstate(); } if(data.action=="luckok"){ //来自手机客户端的命令 console.log('luckok: '+msg); update_luck_show(msg); } if(data.action=="luckend"){ //来自手机客户端的命令 console.log('luckend: '+msg); update_luck_show(msg); } }
手机客户端
代码类似...