Tulisan ini saya buat karena menyadari bahwa lingkungan LAN kami tidak memperolehkan koneksi ke internet selain port 80 untuk keperluan browsing internet. Aplikasi akan melakukan sinkronisasi waktu ke situs web www.google.com dengan melakukan HTTP HEAD request yang biasanya digunakan untuk memeriksa apakah layanan url tersedia, atau file yang diinginkan tersedia (HTTP HEAD request adalah berbeda dengan HTTP GET request).Berikut ini adalah contoh HTTP HEAD request yang dapat dikirim sesaat setelah koneksi berhasil dilakukan.
HEAD / HTTP/1.1\r\nDimana \r\n adalah merepresentasikan CRLF, dan berikut ini adalah hasil response dari server.
Accept: */*\r\n
User-Agent: Mozilla/4.0 (compatible; ESP8266 NodeMcu Lua;)\r\n\r\n
Location: http://www.google.co.id/?gws_rd=cr&ei=6kYjWNOYFovvvgSzw424AgDiantara request tersebut terdapat baris Date yang nantinya akan kita parse untuk menggambil komponen tahun, bulan, tanggal, jam, menit dan detik.
Cache-Control: private
Content-Type: text/html; charset=UTF-8
P3P: CP="This is not a P3P policy! See https://www.google.com/support/accounts/answer/151657?hl=en for more info."
Date: Wed, 09 Nov 2016 15:55:22 GMT
Server: gws
Content-Length: 261
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
Set-Cookie: NID=90=tP2nCmiU8y7o7oZt24v2mLxAE7WSyvUcu0hYL6kreKdKrlV5C98ut_KYTK7SljVgk7B0XdzRrwNVEXUIE4JHYI2WUh8ssyDJpebpLtNltY6F9OaF-ez5l-43PoZK_HY5; expires=Thu, 11-May-2017 15:55:22 GMT; path=/; domain=.google.com; HttpOnly
Karena belum familiar dengan HTTP request dengan menggunakan Lua, maka saya memulai dengan mencoba source-code yang disediakan pada situs www.nodemcu.com dengan rangkaian koding sebagai berikut:
Yaitu conn:send langsung dibawah baris conn:connect, sehingga tidak ada suatu jaminan bahwa ketika HTTP GET request dilakukan, conn:connect telah berhasil membuka koneksi dengan server, sehingga response yang diharapkan tidak terjadi. Berdasarkan hasil surfing akhirnya saya melakukan perbaikan dengan koding sebagai berikut:-- A simple http client conn=net.createConnection(net.TCP, false) conn:on("receive", function(conn, pl) print(pl) end) conn:connect(80,"www.google.com") -- tidak ada jaminan koneksi telah berhasil conn:send("GET / HTTP/1.1\r\nHost: www.nodemcu.com\r\n" .."Connection: keep-alive\r\nAccept: */*\r\n\r\n")
Dimana HTTP GET request dilakukan setelah terjadi event on connection, yang berarti bahwa koneksi ke server telah berhasil dilakukan, dan aplikasi client berhasil mendapatkan response dari server.-- A simple http client conn=net.createConnection(net.TCP, false) conn:on("connection", function(conn, pl)
conn:send("GET / HTTP/1.1\r\nHost: www.nodemcu.com\r\n"
.."Connection: keep-alive\r\nAccept: */*\r\n\r\n")
end)conn:on("receive", function(conn, pl) print(pl) end) conn:connect(80,"www.google.com")
Berikut ini adalah koding lengkap untuk melakukan HTTP HEAD request, yang diserta dengan setting waktu rtctime.
credentials.lua
Dapat diperoleh pada tulisan sebelumnyamylib.lua
Dapat diperoleh pada tulisan sebelumnyainit.lua
Dapat diperoleh pada tulisan sebelumnyaapp.lua
--Date: Wed, 09 Nov 2016 15:57:58 GMT
-- 1 2 3
--12345678901234567890123456789012345
-- diadaptasikan kembali oleh Hendra Soewarno (0119067305)
require("mylib")
retried = 1
conn=net.createConnection(net.TCP, false)
function sendHeader(conn, pl)
conn:send("HEAD / HTTP/1.1\r\n"
.. "Accept: */*\r\n"
.. "User-Agent: Mozilla/4.0 (compatible; ESP8266 NodeMcu Lua;)\r\n"
.. "\r\n")
end
function setTime(conn, pl)
--contain Date signature
posisi = string.find(pl, "Date")
if posisi > 0 then
--cancel next alarm
tmr.stop(0)
year = 2000+tonumber(string.sub(pl,posisi+19,posisi+22))
mon = string.sub(pl,posisi+14,posisi+16)
month = math.floor(string.find("JanFebMarAprMayJunJulAugSepOctNovDec",mon)/3)+1
day = tonumber(string.sub(pl,posisi+12,posisi+13))
hour = tonumber(string.sub(pl,posisi+23,posisi+24))
minute = tonumber(string.sub(pl,posisi+26,posisi+27))
second = tonumber(string.sub(pl,posisi+29,posisi+30))
mikrosecond = 0
--datetime to unix epoch time
unixtime = mylib.cal2epoch(year, month, day, hour, minute, second)
-- update software RTC
rtctime.set(unixtime, mikrosecond)
utc = rtctime.epoch2cal(rtctime.get())
print("Waktu adalah UTC:" .. string.format("%04d/%02d/%02d %02d:%02d:%02d", utc["year"], utc["mon"], utc["day"], utc["hour"], utc["min"], utc["sec"]))
-- WIB UTC + 7
wib = rtctime.epoch2cal(rtctime.get()+7*60*60) -- tambah 7
print("Waktu adalah WIB:" .. string.format("%04d/%02d/%02d %02d:%02d:%02d", wib["year"], wib["mon"], wib["day"], wib["hour"], wib["min"], wib["sec"]))
end
end
function syncTime()
print("trying www.google.com " .. retried)
conn:on("connection", sendHeader)
conn:connect(80,"www.google.com")
retried = retried + 1
-- close connection if not got response in minute
tmr.alarm(1,1000,0, function() conn:close() end)
end
syncTime()
--no more frequently than once every 4 seconds
tmr.alarm(0,5000,1, syncTime)
Gambar 1. Hasil Run Aplikasi
Tidak ada komentar:
Posting Komentar