Blog

【創意編程】運用Socket.IO,完成簡易網路即時雙向傳輸!

簡易完成網路雙向傳輸!

文:駱若瑀

近期融聲創意的作品多圍繞著「網路傳輸」,包括《無重力星空》、《地衣荒物》、紀柏豪的《距離之歌》等,都使用了網路的特性,讓觀者使用手機即時參與、影響現場的作品。今天就來分享如何簡單做到網路傳輸的功能!

先來看看「示範範例」的效果:

Animated GIF - Find & Share on GIPHY

上圖中,點選任意網頁的任意位置,都會觸發所有開著的網頁隨機切換背景色。

咦?不是只有一個網頁被點到嗎?怎麼有辦法讓開著的網頁都一起變色?

這個範例的概念和現代人所熟悉的「通訊軟體」非常相似,我們在使用通訊軟體(Messenger、Line)的時候,會有「傳送的對象」(朋友A、群組B)以及「傳送的資訊」(訊息、圖片等等),而對範例而言,當按下網頁,被按下的網頁就會透過網路傳輸將「背景顏色」這個資訊傳給「開啟的網頁」。這時候,所有被開啟的網頁便會接收到顏色的資訊囉。

暸解大概念後,直接進入實作階段!

首先,在 html 的 header 中,加入 socket.io 的函式庫。socket io 是一套函式庫,實作了網路封包傳送的細節,讓我們能夠輕鬆地在網頁上做到即時的雙向傳輸。

html
 <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.1.0/socket.io.js" ></script >

並在 javascript 中建立和伺服器的連線:

js
var socket = io('https://xxxxxxxx');

等等,伺服器又是什麼?

雖然範例看起來是網頁間的傳輸,事實上,網頁之間還有伺服器這個中介者。可以暫時把伺服器想像成一台一直開著的電腦,只要知道這台電腦在哪裡,網頁就可以與伺服器互傳資料。當網頁 A 要傳送資訊給網頁 B 時,網頁 A 會先告訴伺服器,他想要跟誰溝通,再由伺服器轉達這個資訊給 B。

在上面程式中,io()括弧中填入的便是伺服器的位址。這次範例使用的伺服器程式在『此處』,下一篇文章我們會接續介紹如何架設這裡用到的伺服器。

(還不會架設伺服器的話,可以暫時使用 https://osc-server.glitch.me/ 網址。但這個網址可能不久就會被移除。)

接著,加入「按下」網頁的事件:

js
document.body.addEventListener('click', ()=>{
    //do something when user clicks the page
});

並在事件中,傳送資料:

js
document.body.addEventListener('click', ()=>{
    //do something when user clicks the page
    socket.emit('osc', {
        r: random(),
        g: random(),
        b: random()
    });
});

上面的 socket 是我們剛剛建立的和伺服器的連線,emit()函式中包含了兩個參數,第一個代表「要傳送到哪」,第二個是「要傳送的訊息」。

「要傳送的到哪」實際上沒有真的傳到不同的地方,比較像是告訴伺服器這筆訊息是什麼,伺服器才能接著判斷要如何處理這筆訊息。

而這裡選擇寫 osc是因為,在前面提供的伺服器程式中,我們預先寫好了只要這筆訊息是 osc,就會再將收到的訊息傳送給所有和伺服器連線的網頁。

第二個參數「要傳送的訊息」,則是以 JSON 傳送了顏色的 r、g、b 數值。因為要隨機變換顏色,r、g、b 使用了函式 random() 得到隨機數值。函式如下:

js
function random() {
    return Math.floor(Math.random()*256);
}

完成傳送端後,網頁又如何接收與處理訊息呢?

js
socket.on('connect', (data) => {
    //do something when socket is connected.
})

socket.on() 代表「當和伺服器的連線 socket 接收到訊息」。試著解讀上面的程式碼,翻過來的意思便是,當 socket 接收到'connect' 的訊息後,會往下做某些事。

接著在大括弧裡,再加入「當 socket 接收到osc」要做的事。

js
socket.on('connect', (data) => {
    socket.on('osc', (msg) => {
        document.body.style.background = `rgb(${msg.r}, ${msg.g}, ${msg.b})`
    });
})

這裡的msg就是接受到的訊息,由於這次用的伺服器原封不動的把網頁傳送給他的資料,傳送給所有網頁,所以我們可以從 msg 裡面拿出 r、g、b,改變整個網頁的背景顏色。

到這裡就大功告成啦!其實除了傳送顏色,也可以傳送按下的按鈕、音樂播放的時間等等,很多在網頁上看到的東西,都可以化作能被傳輸的訊息。熟悉了網路傳輸的實作方法後,也不坊嘗試傳輸不同的訊息,做出自己的遠端控制網頁!

Write a comment