HTML5+NodeJs实现WebSocket即时通讯
产品网站中很多地方需要用到实时交互,web端的实时交互。
具体为活动抽奖案例:
现场一个大屏,显示中奖人列表相关信息;
主持人一个pad控制开始抽奖结束抽奖;
每个活动现场的观众的手机。用来摇动手机进行抽奖
毫无疑问用websocket,WebSocket相较于HTTP来说,有很多的优点,主要表现在WebSocket只建立一个TCP连接,可以主动推送数据到客户端,而且还有更轻量级的协议头,减少数据传送量。所以WebSocket暂时来说是实时通讯的最佳协议了
至于服务器语言选择nodeJs,是因为NodeJs本身事件驱动的方式很擅长与大量客户端保持高并发的连接。所以就选择NodeJs了。
安装nodejs,然后再安装一个nodejs-websocket的模块。然后就可以开始建立服务器了,因为有了nodejs-websocket模块,所以很多工作都不用我们自己做,直接调用别人封装好的方法就行了
服务器代码:
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代码
/*远程控制开始----------------------------------------------*/ 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:"<?php echo $configluck['LuckId']; ?>"}; // 向服务端发送消息 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代码
/*远程控制开始----------------------------------------------*/ 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":"<?php echo $configluck['LuckId']; ?>"} // 向服务端发送消息 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); } }
手机客户端
代码类似...