在頁遊時代,大部分遊戲都是經過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進行實時通訊交互的例子實現了,咱們經過擴展細節,能夠作成我畫你猜的畫圖遊戲,也能夠發揮創造力作出更多好玩的交互。