用socket.io簡單快速實現H5實時互動

在頁遊時代,大部分遊戲都是經過socket來實現玩家之間的實時通訊互動的,在H5時代,利用websocket,咱們也一樣能夠達到這個目的,而且目前websocket的瀏覽器兼容度已經很高,下面記錄一下基於socket.io庫來實現H5畫板功能的過程,很是的簡單方便。javascript

socket.io

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

相關文章
相關標籤/搜索