你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> 基於 socket.io, 簡單實現多平台類似你猜我畫 socket 數據傳輸

基於 socket.io, 簡單實現多平台類似你猜我畫 socket 數據傳輸

編輯:IOS開發綜合

本文為您介紹基於 socket.io, 簡單實現多平台類似你猜我畫 socket 數據傳輸的相關介紹,具體代碼請看下文

一、前言 socket.io 實現了實時雙向的基於事件的通訊機制,是基於 webSocket 的封裝,但它不僅僅包括 webSocket,還對輪詢(Polling)機制以及其它的實時通信方式封裝成了通用的接口,並且在服務端實現了這些實時機制的相應代碼 socket.io 是跨平台的,可以實現多平台的即時通訊 由於 IOS 端進行 socket 編程主要使用 GCDAsyncSocket 框架,但要實現 Android、IOS、web 多平台的通訊,還是選擇統一的框架或協議比較好。 基本 api,使用 socket.on 來監聽傳過來的數據,使用 socket.emit 來發送數據 二、本例說明 服務器端采用 Nodejs 開啟本地服務,統一使用 socket.io 對 IOS 端和 web 進行即時通訊,簡單實現類似你猜我畫的數據傳輸 效果 三、服務器端

使用 express 進行簡單的搭建,設置模板引擎及靜態服務,新手會遇到一個坑,就是路徑的問題,一般使用 __dirname,來拼接絕對路徑

// 模板引擎
app.set("views", path.join(__dirname, "/views/"));
app.set("view engine", "ejs");
// 靜態服務
app.use(express.static(path.join(__dirname, "/public/")));
app.use("/upload", express.static(path.join(__dirname, "/upload/")));

使用 socket.io,來進行 socket 數據監聽及數據廣播,這是服務器端做的主要事情,本例中傳輸的數據及格式是自定義的,分為三種,一種是畫筆畫的路徑(path),傳輸的是一系列的坐標點,一種是圖片(img),傳輸的是 base64 字符串,另一種是發送的文字(text),傳輸的是字符串

    var http = require('http').Server(app);
    var io = require('socket.io')(http);

    io.on('connection', function (socket) {
        console.log('one client connected');
        // 連接成功,自己給自己發個空的信息,回調下
        socket.emit('connection', null);
        // path
        socket.on('path', function (msg) {
            socket.broadcast.emit('path', msg);
        });
        // img
        socket.on('img', function (msg) {
            socket.broadcast.emit('img', msg);
        });
        // text
         socket.on('text', function (msg) {
            // 給出自己外的其他所有的 socket 廣播
            socket.broadcast.emit('text', msg);
            // 給所有的 socket 的廣播,包括自己
            // io.emit('text', msg);
        });
    });
四、web

關於筆畫的傳輸:使用 canvas,進行畫板的相關操作,並保存所有的路徑的坐標點,然後 socket 傳輸

// canvas 繪圖
// 拿到 canvas htmlElement
// var canvas = document.getElementById("canvas");
var canvas = $("#canvas").get(0);
// 創建上下文 
var ctx = canvas.getContext("2d");
var colorArray = ["black", "red", "blue", "green"];
// 鼠標畫圖
canvas.onmousedown = function (e) {
    // 開始畫
    ctx.beginPath();
    // ctx 屬性設置
    ctx.lineWidth = 3;
    ctx.lineCap = "round";
    ctx.lineJoin = "round";
    let randomNum = parseInt(Math.random() * colorArray.length);
    var mycolor = colorArray[randomNum];
    ctx.strokeStyle = mycolor;
    // tmp 為裝所有坐標點的數組
    var tmp = [];
    var e = e || Window.event;
    // 第一個坐標點
    var point = {
        x: e.clientX - canvas.offsetLeft,
        y: e.clientY - canvas.offsetTop
    }
    ctx.moveTo(point.x, point.y);
    tmp.push(point);

    document.onmousemove = function (e) {
            var e = e || Window.event;
            var point = {
            x: e.clientX - canvas.offsetLeft,
                y: e.clientY - canvas.offsetTop
        }
        ctx.l.neto(point.x, point.y);
        tmp.push(point);
        ctx.stroke();
    };
    document.onmouseup = function () {
        document.onmousemove = null;
        document.onmouseup = null;

    // socket 發送path
     var pathDataDict = {
     path: tmp,
     width: 3,
     color: randomNum,
     screenW: 400
    }
    socket.emit("path", pathDataDict);
    };
};
關於圖片的傳輸:由於 input type="file" 拿不到本地的圖片路徑,所以采取先上傳圖片到服務器,再拿到圖片路徑,然後通過 canvas 畫出來和用 canvas 轉換為 base64,然後 socket 發送出去

這裡采用 jquery.form 框架,使用 AJAX 異步提交表單,新手有個坑,就是 form 裡面提交按鈕的 type 要設置為 button,不然就是 form submit了,頁面會跳轉的

$("#selImg").click(function () {
// form 提交
$("#form").AJAXSubmit({
    url: "http://127.0.0.1:5000",
    type: "post",
    dataType: 'json',
    success: function (data) {
        if (data.status == -1) {
            alert("請選擇圖片發送!");
            return;
        } 
        if (data.status == 1) {
            alert("圖片上傳失敗!");
            return;
        }

        //  html Dom Element
        let image = new Image();
        image.src = "http://127.0.0.1:5000/upload/" + data.status;
        image.onload = function () {
            ctx.drawImage(image, 0, 0, 400, 400);
            var base64Url = canvas.toDataURL("image/png");
            let base64 = base64Url.toString()
            console.log(base64.substring(22));
            socket.emit("img", base64.substring(22));

        };
    },
    error: function (data) {

    }
});
});
關於文字,就很簡單,直接 socket 發送字符串

關於數據的接收,這裡要提到一個與 iOS 版 socket.io 不同的地方,在 iOS 端,發送數據是要把數據包裝成一個數組的,如 [self.clientSocket emit:@"text" with:@[self.chatTextField.text]];,但在前端接收的數據就直接是 iOS 端數組裡的對象,不用取數組第一個,但反過來,在 iOS 端就需要去數組裡的第一個了,這裡簡單說下圖片的接收吧,由於對 canvas 不熟,只能采取先創建一個臨時的 img 標簽展示 base64Url 的圖片,然後在 canvas 接收 img 這個 HTMLElement,畫出圖片,最後刪掉這個臨時的 img 標簽,如果有更好的方法可以留言

socket.on("img", function (msg) {
    console.log("img");
    // base64 可以直接用<img>展示出來 ,獲取 img 標簽對象,可畫出來
    $(".caozuo").append("<img id='tmpImg' width='0' height='0' src='data:image/png;base64," + msg + "'></img>");
    ctx.drawImage($("#tmpImg").get(0), 0, 0, 400, 400);
    $("#tmpImg").remove();
});
五、iOS 這裡官方最新的 socket.io 是只有 swift 版的,之前有舊的oc 版本,但支持的socket.io 是v0.9.x,參考鏈接 https://github.com/pkyeck/socket.IO-objc,但這很顯然不是我想要的,於是開始混編吧 一開始參考了https://github.com/socketio/socket.io-client-swift/issues/393 裡的做法,使用 carthage 打包好的 framework,但各種報錯 想起之前 oc 調用 swfit 文件,先是直接把 swift 文件拖進工程,然後使用的時候就import "項目名稱-swift.h"就行,不需要橋接文件什麼的,但在 xcode8 下,貌似感覺還是需要橋接文件。具體做法如下 先拖進一個 swift 文件到 oc 工程裡,xcode 會提示創建橋接文件,這裡就讓 xcode 自動創建橋接文件吧 然後把剩余的 socket.io-client-swift 框架 Source 文件夾裡的剩余文件全部拖進 oc 工程 使用的時候就import "項目名稱-swift.h" 在 iOS 端下,筆畫路徑坐標,就直接傳輸字典就行,我這裡字典裡包括筆畫的顏色,坐標點數組,筆畫的寬度及屏幕的寬度等信息,圖片就直接傳輸 base64 的,文字就直接傳輸字符串,但要注意和 web 端的 socket.io 的區別,具體代碼可參考 demo 鏈接 六、小 demo 地址 https://github.com/HOWIE-CH/-You-guess-I-painted-_socket 七、其他 使用 socket.io,感覺傳輸數據很方便,api 簡單,也沒有像 GCDAsyncSocket 傳輸數據會出現掉包的現象 對於服務器,Nodejs等,我也是新手,如果自己想玩一下的話,可以租國外性價比高的 vps,然後申請域名,可以采取使用 Nginx 做主服務,使用反向代理,這樣可方便綁定自己的各種二級域名了,應用服務可以使用 Nodejs 或其他,也可以自己研究下 Nginx 的負載均衡技術了。對與國外 vps 的好處,大家都知道,還可搭建自己的科學上網環境等

多多關注本站,我們將為您收集更多的Android開發相關文章.

【基於 socket.io, 簡單實現多平台類似你猜我畫 socket 數據傳輸】的相關資料介紹到這裡,希望對您有所幫助! 提示:不會對讀者因本文所帶來的任何損失負責。如果您支持就請把本站添加至收藏夾哦!

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved