在页游时代,大部分游戏都是经过socket来实现玩家之间的实时通讯互动的,在H5时代,利用websocket,咱们也一样能够达到这个目的,而且目前websocket的浏览器兼容度已经很高,下面记录一下基于socket.io库来实现H5画板功能的过程,很是的简单方便。javascript
socket.io是一个基于Node.js的websocket库,能够方便快捷地在web端创建socket通讯。前端
npm install socket.io
安装好socket.io后,咱们创建app.js(服务器的入口程序),添加以下代码:java
var app = require('http').createServer(handler) var io = require('socket.io')(app); var fs = require('fs'); // socket端口 app.listen(8080); // 处理请求 function handler(req, res) { res.writeHead(200); res.end('Hello World2\n'); } // 客户端链接的事件处理函数 io.on('connection', function(socket) { // todo... });
上面简单的几行代码已经创建了一个socket服务器,而且能处理客户端的链接与收发消息。web
// 链接socket var socket = io('http://localhost'); // 监听画图消息 socket.on('draw-event', function(data) { console.log(data); // 处理画图消息 if (data.type == 'start') { onTouchStart(data.x, data.y); } else if (data.type == 'move') { onTouchMove(data.x, data.y); } });
在同一个房间里的全部用户能够很方便的管理和传递消息,默认状况下,socket.io都是为每一个用户建立一间房间,而且房间id存在socket.id属性中。咱们在第一个用户进入时取到房间号,而后经过二维码方式让后面的用户扫码,后面的用户经过扫码进入时加入到指定的房间。npm
前端逻辑:canvas
socket.on('connect', function() { // 判断是经过扫码进入房间仍是房主 if (isHost) { // 生成二维码 new QRCode(document.getElementById("qrcode"), url + '?r=' + socket.id); console.log('url', url + '?r=' + socket.id) } else { // 发消息给服务器加入房间 socket.emit('sys', { type: 'join', roomId: params.r }); } });
上面的代码用到了QRCode.js这个前端库生成代码。后端
后端逻辑:浏览器
// 处理系统消息 socket.on('sys', function(data) { console.log(data); if (data.type == 'join') { // 猜的一方进入房间 console.log(socket.id + ' join room: ' + data.roomId); socket.join(data.roomId); // 通知房间其它用户 io.in(data.roomId).emit('sys', { type: 'join', roomId: data.roomId }); } });
画图是用canvas的绘图实现的,核心部分代码:服务器
// 笔触移动 $('#canvas').on('touchmove', function(event) { touch = event.touches[0]; render(); // 发送到后端 socket.emit('draw-event', { type: 'move', x: touch.pageX, y: touch.pageY, }); }).on('touchstart', function(event) { // 点击屏幕 event.preventDefault(); touch = event.touches[0]; onTouchStart(touch.pageX, touch.pageY); isTouched = true; // 发送到后端 socket.emit('draw-event', { type: 'start', x: touch.pageX, y: touch.pageY, }); }).on('touchend', function(event) { // 离开屏幕 event.preventDefault(); isTouched = false; touch = null; }); ... var render = function() { onTouchMove(touch.pageX, touch.pageY); }; var onTouchStart = function(x, y) { context.moveTo(x - canvasOffset.left, y - canvasOffset.top); }; var onTouchMove = function(x, y) { context.lineTo(x, y); context.stroke(); context.moveTo(x - canvasOffset.left, y - canvasOffset.top); console.log(x, y) };
后端转发消息给另外的客户端:websocket
socket.on('draw-event', function(data) { console.log(data); // 转发画图消息 socket.to(roomId).emit('draw-event', data); });
接收方处理消息:
socket.on('draw-event', function(data) { console.log(data); if (data.type == 'start') { onTouchStart(data.x, data.y); } else if (data.type == 'move') { onTouchMove(data.x, data.y); } });
至此,一个简单的经过websocket进行实时通讯交互的例子实现了,咱们经过扩展细节,能够作成我画你猜的画图游戏,也能够发挥创造力作出更多好玩的交互。