èæ¯
æšå¹Žã®12æ20æ¥ãç§ã¯2é±éãäŒæãåããŸããã äŒæäžã«ãã¹ãããš ããã§ã-ã³ãŒãä»ãã å¶æ¥æéäžã«è¡ãæéããªãã³ãŒãã ããæ°å¹Žãç§ã¯ã³ãŒãã£ã³ã°ãã»ãšãã©ããŠããŸããã æãã€ãªãã§ããã 圌ãã¯äŒæäžã«ã©ã®ãããªã³ãŒããæžããŸããïŒ ããªãã®ããšã¯ç¥ããŸããããèªè»¢è»ãæžããŸãã ãªãã§ïŒ å€ãã®çç±ããããããããŸããããäž»ãªçç±ã¯ç§ã«ãšã£ãŠèå³æ·±ããã®ã§ãã C ++ãšLuaã倧奜ãã§ãã bashãšawkã倧奜ãã§ãã ç³ãæããªãã§ãã ãããããã¯å人çãªãã®ã§ããããã¯èµ·ãããŸããã ç§ã¯JavaScriptãããŸã奜ãã§ã¯ãããŸããïŒãã ããJSã§äœãããšã³ã³ãŒããããå Žåãéå»2幎éïŒããããå人çãªãã®ã§ãã
æçµçã«äœãèµ·ãã£ãã®ã
äŒæäžã®éå±ã®çµæã¯ã LAppS-Lua Application Serverã§ããã ãã®äŒæã®ã³ãŒãã£ã³ã°ã¯6ãæéç¶ããŸããïŒãã¡ããã12æ以éãã³ãŒãã«ããŸãæéããããŸããã§ãããããã¯githubã®ã³ãããããããããŸãïŒã ããããéå»2é±éã§ãäœããæ©èœãããããã«å€ãã®æéã奪ããŸããã
ããã¯äœã§ãã
ååã瀺ãããã«ã LAppS㯠Luaã¢ããªã±ãŒã·ã§ã³ãµãŒããŒã§ãã Luaã¯éåžžã«äººæ°ã®ããèšèªã§ãããNginx + LuaãšOpenRestyã©ã€ãã©ãªã®çµã¿åãããäžçäžã§ç©æ¥µçã«äœ¿çšãããŠãããCloudflareã«ã¯äŸ¡å€ããããŸãã éçºã®åæã«ã¯ãåè¿°ã®Nginxããã³Tarantoolçšã®Luaã¢ãžã¥ãŒã«ã§ããluvit.ioããã§ã«ååšããŠããŸããã ãããããããã®ã©ããWebSocketããµããŒãããŠããŸããã§ããã LAppSã¯HTTPããµããŒãããŠããŸããã ãããä»ã§ã¯ã LAppSã¯uWebSocketsãããããã©ãŒãã³ã¹ã«åªããŠããŸãïŒå€§èŠæš¡ãªã³ã³ãã¥ãŒãã£ã³ã°ãªãœãŒã¹ãæ¶è²»ããŸãïŒã
äž»ãªã¢ã€ãã¢ã¯ããã€ã¯ããµãŒãã¹ã®éçºãµã€ã¯ã«ãæå°éã«æããããšã§ããã Luaã®ãšã³ããªã®ãããå€ã¯JavaScriptãããäœããªã£ãŠããŸãã äžåŠçã§ãç°¡åã«Luaã§ããã°ã©ãã³ã°ãå§ããããšãã§ãããšç¢ºä¿¡ããŠããŸãã ããããLuaçšã®Webã¢ããªã±ãŒã·ã§ã³ãéçºããããã«å©çšã§ãããã¹ãŠã®ããŒã«ã¯æ¬¡ã®ãšããã§ããããã®ãããªæå°ãšã³ããªãŒãããå€ã¯ãããŸããã
ãããã£ãŠãéçºã«ãããäž»ãªéç¹ã¯ãæå°éã®APIãšã¢ããªã±ãŒã·ã§ã³äœæã®å®¹æããããã³ã¢ããªã±ãŒã·ã§ã³ãµãŒããŒãšãµãŒãã¹ã®æ§æã®å®¹æãã§ããã
詳现
LAppSã® Luaã¢ããªã±ãŒã·ã§ã³ïŒãµãŒãã¹ïŒã¯I / Oããããã¯ããŸããã ããã¯ãããããLuaã§ã¹ã¯ãªãããäœæããWebãµãŒããŒãšã®æ倧ã®éãã§ãã LAppSã¯2ã€ã®æ§æãã¡ã€ã«ã䜿çšããŠãWebSocketsãµãŒããŒã®åäœãæ§æããã¢ããªã±ãŒã·ã§ã³ãå±éããŸãã
ããã©ã«ãã§ã¯ãæ§æãã¡ã€ã«ããªãå ŽåãLAppSã¯ãã£ã¹ããªãã¥ãŒã·ã§ã³ã§å®è¡ãããŠãããã¢ã¢ããªã±ãŒã·ã§ã³ã®å®è¡ãè©Šã¿ãŸãã
ws.json-WebSocketsãµãŒããŒæ§æãã¡ã€ã«
{ "listeners" : 1, "connection_weight": 0.7, "ip" : "0.0.0.0", "port" : 5083, "workers": { "workers" : 3, "max_connections" : 1000 }, "tls" : true, "tls_certificates" : { "ca" : "/opt/lapps/etc/ssl/cert.pem", "cert" : "/opt/lapps/conf/ssl/cert.pem", "key" : "/opt/lapps/conf/ssl/key.pem" }, "auto_fragment" : true, "max_inbound_message_size" : 300000 }
- listeners-䞊è¡ããŠèµ·åããããªã¹ããŒã®æ°ããã®ãã©ã¡ãŒã¿ãŒã¯ã LAppSãçä¿¡æ¥ç¶ãåãå ¥ããé床ã«åœ±é¿ããŸã
- connection_weight -IOWorkersã®I / Oãã¥ãŒã®æ·±ããšæ¥ç¶æ°ãæ¯èŒããå éšãã©ã³ãµãŒã®ãã©ã¡ãŒã¿ãŒã åææ¥ç¶ãå€ãã»ã©ããã®ãã©ã¡ãŒã¿ãŒã¯å°ãªããªããŸãã æ¥ç¶ã¯ãç°ãªãè² è·ãããã¡ã€ã«ã§ç°ãªããµãŒãã¹ã䜿çšã§ããŸãã ãã®ãããªç¶æ³ã§ã¯ãæ¥ç¶æ°ã®å°ãªãIOWorkerããããæ°ããæ¥ç¶ã«è² è·ã®å°ãªãIOWorkerã䜿çšããããšããå§ãããŸãã
- ip-ãµãŒããŒãçä¿¡æ¥ç¶ãåŸ æ©ããã€ã³ã¿ãŒãã§ãŒã¹ã®IPã¢ãã¬ã¹ã ããã©ã«ãã§ã¯ããã¹ãŠã®ã€ã³ã¿ãŒãã§ãŒã¹ã
- ããŒã -ããŒãã ããã©ã«ãã¯5083ã§ãã
- workers.workers-åæã«åäœããIOWorkersã®æ°ã ããã©ã«ãã¯3ã§ãã
- workers.max_connections-ãŸã 䜿çšãããŠããŸããã å°æ¥çã«ã¯ãæåã®IOWorkerã®ã¢ã¯ãã£ããªæ¥ç¶ã®å¶éãèšå®ããŸãã
- tls -TLSã䜿çšããŸããïŒ ããã©ã«ãã¯yesã§ãã äžè¬çã«ããã®ãã©ã¡ãŒã¿ãŒã¯ç¡æå³ã§ãã TLSããã«ããã©ã¡ãŒã¿ã«ãã£ãŠæ±ºå®ããããã©ããã䜿çšããŸãã ããã©ã«ãã§ã¯ããµãŒããŒã¯LibreSSLããã³TLS 1.2ã䜿çšããŠæ§ç¯ãããŸãã
- tls_certificates.ca -LibreSSLã«å梱ãããŠãã蚌ææžãžã®ãã¹ã
- tls_certificates.cert-蚌ææžãã¹ïŒããã©ã«ãã¯localhostèªå·±çœ²å蚌ææžã§ãïŒ
- tls_certificates.key-蚌ææžããŒ
- auto_fragment-éä¿¡ã¡ãã»ãŒãžã«èªåæçåã䜿çšãããã©ããïŒãŸã æå¹ã§ã¯ãããŸããïŒ
- max_inbound_message_size-çä¿¡ã¡ãã»ãŒãžã®ãµã€ãºå¶éïŒãŸã æå¹ã§ã¯ãããŸããïŒ
lapps.json-ãµãŒãã¹æ§æãã¡ã€ã«
{ "directories" : { "applications" : "apps", "app_conf_dir" : "etc", "tmp": "tmp", "workdir": "workdir" }, "services" : { "echo" : { "internal" : false, "request_target" : "/echo", "protocol" : "raw", "instances" : 3 }, "echo_lapps" : { "internal" : false, "request_target" : "/echo_lapps", "protocol" : "LAppS", "instances" : 3 } } }
- directory.applications-ç°å¢å€æ°LAPPS_HOMEã«é¢é£ããã¢ããªã±ãŒã·ã§ã³ãã£ã¬ã¯ããªãžã®ãã¹ïŒããã©ã«ã/ opt / lappsïŒã-ããã©ã«ãã¢ããª
- directory.app_conf_dir-ãµãŒãã¹æ§æãã¡ã€ã«ãžã®ãã¹ïŒãŸã 䜿çšãããŠããŸããïŒ
- *ãã£ã¬ã¯ããª{tmpãworkdir}-䜿çšãããŸãã
- services-ãµãŒãã¹èšå®ã®ããã
äžèšã®äŸã§ã¯ãechoãšecho_lappsã®2ã€ã®ãã¢ãµãŒãã¹ãæ§æãããŠããŸãã ãµãŒãã¹ã®ååã¯ããã©ã«ãã§ãããLuaã¢ããªã±ãŒã·ã§ã³ã¢ãžã¥ãŒã«ã®æ€çŽ¢ãã¹ã§ãã æ¬è³ªçã«ã LAppSã®ã¢ããªã±ãŒã·ã§ã³ã¯ãç¹å®ã®ã€ã³ã¿ãŒãã§ã€ã¹ã«åŸãã¢ãžã¥ãŒã«ã§ãã
å éšãã©ã¡ãŒã¿ãŒã«å ããŠãä»ã®ãã¹ãŠã®ãµãŒãã¹èšå®ãå¿ èŠã§ãã
- servicesã{name} -äŸã®services.echoããã³services.echo_lappsã§ã¯ããµãŒãã¹ã®ååã
- servicesã{name} .request_target -WebSockets URLã®ã¿ãŒã²ãããäŸwssïŒ//127.0.0.1ïŒ5083 / echowssïŒ//127.0.0.1ïŒ5083 / echoãŸãã¯wssïŒ//127.0.0.1ïŒ5083 / echo_lappsã ãã³ãã·ã§ã€ã¯åŸã®IOWorkersã¯ããã®ç®æšã«åºã¥ããŠãœã±ãããç¹å®ã®ã¢ããªã±ãŒã·ã§ã³ã«é¢é£ä»ããŸãã ãµãŒãã¹ãããã«ã¯ã©ã€ã¢ã³ããèŠæ±ããç®æšããªãå Žåããã³ãã·ã§ã€ã¯ã¯ã³ãŒã403ã§äžæããŸãã
- servicesã{name} .protocol-ã¢ããªã±ãŒã·ã§ã³ãããã³ã«ã®ã¿ã€ãã çŸåšã2ã€ã®ã¿ã€ãã®ãããã³ã«ã®ã¿ã䜿çšãããŠããŸãïŒrawããã³LAppSïŒãããã«ã€ããŠã¯ä»¥äžïŒ
- servicesã{name} .instances-åæã«å®è¡ãããŠããã¢ããªã±ãŒã·ã§ã³ã€ã³ã¹ã¿ã³ã¹ã®æ°ã åæ¥ç¶ã¯ãç¬èªã®ã¢ããªã±ãŒã·ã§ã³ã€ã³ã¹ã¿ã³ã¹ã«å²ãåœãŠãããŸãã
çµã¿ç«ãŠãšèšçœ®
çµã¿ç«ãŠããã³ã€ã³ã¹ããŒã«æé ã¯ããããžã§ã¯ãwikiããŒãžã§èªãããšãã§ããŸã
æºåãããdebããã±ãŒãžã䜿çšããŠãubuntu-xenialã«ã€ã³ã¹ããŒã«ã§ããŸãã
ã¢ããªã±ãŒã·ã§ã³/ãµãŒãã¹
ã¢ããªã±ãŒã·ã§ã³ã¯å®éã«ã¯Luaã¢ãžã¥ãŒã«ã§ãããåäœãäºåå®çŸ©ãããããã€ãã®äºåå®çŸ©ã¡ãœãããå¿ èŠã§ãã
- onStart-ã¢ããªã±ãŒã·ã§ã³ãéå§ããåã«1åå®è¡ãããonStartã¡ãœããã ããã§ãåæèšå®ãå®è¡ããã¢ããªã±ãŒã·ã§ã³ã®åæåã«éèŠãªã³ãŒããå®è¡ã§ããŸãã ãã®æ¹æ³ã§ã¯ãLuaä»®æ³ãã·ã³ãç¡æéã«ãããã¯ããªãã§ãã ããã ã€ãŸã ãã®ã¡ãœããã§whileïŒ1ïŒã«ãŒããå®è¡ãããšããµãŒãã¹ã¯çä¿¡èŠæ±ã«å¿çããªããªããŸãã
- onShutdown㯠onStartã«äŒŒãŠãããã¢ããªã±ãŒã·ã§ã³ãåæ¢ãããšãã«ã¡ãœããã1åå®è¡ãããŸãã ãŸããLuaãã·ã³ã®å®è¡ã¹ã¬ãããééãªããããã¯ããŠã¯ãªããŸããã ããã§ãªãå ŽåããµãŒãã¹ã¯ããèªäœãåæ¢ãããã¢ããªã±ãŒã·ã§ã³ãµãŒããŒã®åæ¢ãèš±å¯ããŸããã
- onMessage -rawãããã³ã«ãšLAppSãããã³ã«ã«å¯ŸããŠå¥ã
ã«å®è£
ãããŸãã æ§æã§æå®ããããã©ã¡ãŒã¿ãŒã«å¿ããŠããã®ã¡ãœããã¯ããŸããŸãªã¿ã€ãã®ããŒã¿ãåãåããŸãã
- rawïŒ bool onMessageïŒhandlerãopcodeãmessageïŒ -ããã§ã handlerã¯æ¥ç¶ã®äžæã®èå¥åã§ãã opcode -WebSockets OpCodeã¯ã1ïŒTEXTïŒãŸãã¯2ïŒBINARYïŒã®2ã€ã®å€ã®ã¿ãåããŸããä»ã®ãªãã³ãŒããæã€ãã¹ãŠã®ãã¬ãŒã ã¯ãµãŒããŒã«ãã£ãŠåŠçãããã¢ããªã±ãŒã·ã§ã³ã«ã¯è»¢éãããŸããã message-ãã€ããªãŸãã¯ããã¹ãã¡ãã»ãŒãžãå«ãLuaæååå€ïŒãã¬ãŒã ã®éä¿¡ã«äœ¿çšããããªãã³ãŒãã«ãã£ãŠç°ãªããŸãïŒã
- LAppSïŒ bool onMessageïŒhandlerãmsg_typeãmessageïŒ - ãã³ãã©ãŒã¯äžæã®æ¥ç¶èå¥åã§ãã message -LAppS 1.0ä»æ§ã«æºæ ããå®éã®ã¡ãã»ãŒãžãããã¯ãnljsonåã®ãŠãŒã¶ãŒããŒã¿ãªããžã§ã¯ãã§ãã msg_type-è£å©ãã©ã¡ãŒã¿ãŒãã¡ãã»ãŒãžã¿ã€ãã¯ã1ã4ã®4ã€ã®å€ãåããŸãã
- 1-ã¯ã©ã€ã¢ã³ãéç¥ïŒCNïŒ
- 2-paramsé åã«è¿œå ãã©ã¡ãŒã¿ãŒãæã€CN
- 3-ãã©ã¡ãŒã¿ãŒãªãã®ã¡ãœããã®å®è¡ã®èŠæ±
- 4-paramsé åã®ãã©ã¡ãŒã¿ãŒãæã€ã¡ãœããã®å®è¡ã®èŠæ±
- onDisconnectïŒhandlerïŒ - ã¯ã©ã€ã¢ã³ããåæããïŒ RFC 6455ã«åŸã£ãŠæ£ãããªã»ãããŸãã¯éããïŒãšãã«åŒã³åºãããã¡ãœããã ãã³ãã©-æ¥ç¶ã®äžæã®èå¥åã
æ³šïŒ onMessageã¡ãœããã¯ããŒã«å€ãè¿ãå¿ èŠããããŸãã å€ãè¿ããšããããã¯falseã§ãããã¡ãœãããåŒã³åºãããæ¥ç¶ã¯å£ããŠããŸãïŒã³ãŒã1000ãéããŸãïŒã
ãšã³ãŒãµãŒããŒïŒrawãããã³ã«ïŒãå®è£ ããæãåçŽãªã¹ã±ã«ãã³ã¢ããªã±ãŒã·ã§ã³ã
myapp = {} myapp.__index = myapp; myapp["onStart"]=function() -- do something on start end myapp["onDisconnect"]=function(handler) -- handler - is a unique client identifier -- react on client disconnect end myapp["onShutdown"]=function() -- do something on shutdown end myapp["onMessage"]=function(handler,opcode, message) -- it is an echo, - we return back the same message local result, errmsg=ws:send(handler,opcode,message); if(not result) then print("myapp::OnMessage(): "..(errmsg or "none")); end return result; end return myapp;
ãã®ãµãŒãã¹ã®æ§æïŒ
"myapp" : { "internal" : false, "request_target" : "/myapp", "instances" : 1, "protocol": "raw" }
LAppSãããã³ã«
LAppSãããã³ã«ä»æ§ã¯ãGoogle JSON-RPCä»æ§ã«åºã¥ããŠããã次ã®éèŠãªéãããããŸãã
- CBOR圢åŒã®ãã€ããªã¡ãã»ãŒãžã³ã°
- ãããã³ã«ã¯ããµãŒããŒã«ãã£ãŠéå§ãããã¡ãã»ãŒãžã®ã¿ã€ãã§ãããOut of Order NotificationsãïŒOONïŒãæå®ããŸãã
- ãããã³ã«ã¯ã¡ãã»ãŒãžãã£ãã«ãæå®ããŸãã èŠæ±/å¿çã¡ãã»ãŒãžã®å¿ èŠæ§ãããã³ãµãŒããŒåŽã®éç¥ã®å¿ èŠæ§ãèæ ®ããŠããã£ãã«ã䜿çšãããšãã¯ã©ã€ã¢ã³ãã¢ããªã±ãŒã·ã§ã³ã¯åãæ¥ç¶ã®ç°ãªããã£ãã«ã§äžŠåããŒã¿ã¹ããªãŒã ã䜿çšã§ããŸãã ãã£ãã«0ïŒCCHïŒã¯ãèŠæ±/å¿çã¡ãã»ãŒãžçšã«äºçŽãããŠãããä»ã®ãã¹ãŠã®ãã£ãã«ã¯ã¢ããªã±ãŒã·ã§ã³ã«ãã£ãŠåæãããŠããŸãã
ä»æ§ã¯githubã§å ¥æã§ããŸã
LAppS察å¿ã¢ããªã±ãŒã·ã§ã³
å®å šãªã¢ããªã±ãŒã·ã§ã³ã³ãŒãã¯æäŸããŸãããonMessageã¡ãœããã®å®è£ ã®ã¿ãæäŸããŸãã ãã¢ã¢ããªã±ãŒã·ã§ã³ã®è©³çŽ°ã¯ãgithubã®ãœãŒã¹ã«ãããŸãã
echo_lapps["onMessage"]=function(handler,msg_type, message) -- local switch={ [1] = function() -- -- ( ) -- local err_msg=nljson.decode([[{ "status" : 0, "error" : { "code" : -32600, "message": "This server does not accept Client Notifications without params" }, "cid" : 0 }]]); -- ws:send(handler,err_msg); -- WebSocket 1003 - " " ws:close(handler,1003); end, [2] = function() -- CN . . local method=methods._cn_w_params_method[message.method] or echo_lapps.method_not_found; method(handler,message.params); end, [3] = function() -- local method=echo_lapps.method_not_found; method(handler); end, [4] = function() -- local method=methods._request_w_params_method[message.method] or echo_lapps.method_not_found; method(handler,message.params); end } -- switch[msg_type](); return true; end
èªåããŒãã¢ãžã¥ãŒã«
LAppSã¯ããµãŒãã¹ãéå§ããåã«ã nljson ã ws ã bcastã®ããã€ãã®ã¢ãžã¥ãŒã«ãããŒãããŸãã ã¢ãžã¥ãŒã«ã®ä»æ§ã®è©³çŽ°ã¯ããããžã§ã¯ãwikiã«ãããŸãã
ç°¡åã«ïŒ
- nljson -JSONïŒecode / decode / cborïŒãæäœããããã®ã¢ãžã¥ãŒã«ã
ã¢ãžã¥ãŒã«ã§ã®äœæ¥ã¯ããã€ãã£ãLuaããŒãã«ã§ã®äœæ¥ãšå€§å·®ãããŸããã ããã«ãLuaããŒãã«ã¯ãåçŽãªå²ãåœãŠã§nljsonãŠãŒã¶ãŒããŒã¿ã«å€æãããŸãã ãã ããLuaã¯ãªããžã§ã¯ãïŒããŒå€ïŒãšé åãåºå¥ããªããããããšãã°ã空ã®LuaããŒãã«ã®å Žåãããããnljsonã«å€æããããšã¯é害ã§ãã äŸãã°
local object=nljson.decode({})
ããã«ããããªããžã§ã¯ããšããååã®JSONé åãäœæãããŸãã ãããã£ãŠããã®åæåã䜿çšããããšããå§ãããŸãã
local object=nljson.decode('{}')
ãã®å®çŸ©ã«ãããJSONãªããžã§ã¯ããäžæã«äœæãããŸãã
ããã«ããã®ãªããžã§ã¯ãã¯ãã€ãã£ãluaããŒãã«ãšããŠäœ¿çšã§ããŸãã
object["test"]=""; print(object.test) object["map"]={ ["key1"] = "value", ["key2"] = 33 } print(object)
nljsonãªããžã§ã¯ãã®é床ã¯ããã€ãã£ãã®LuaããŒãã«ãšã»ãšãã©ç°ãªããŸããã
- wsã¯WebSocketã¡ãã»ãŒãžãéä¿¡ããããã®ã¢ãžã¥ãŒã«ã§ãsendãcloseã®2ã€ã®ã¡ãœãããããããŸããã
- bcast-ãããŒããã£ã¹ãã¡ãã»ãŒãžã®ã¢ãžã¥ãŒã«ãå©çšå¯èœãªã¡ãœããïŒãµãã¹ã¯ã©ã€ãããµãã¹ã¯ã©ã€ã解é€ãäœæãéä¿¡ã
ã¯ã©ã€ã¢ã³ãã¢ããªã±ãŒã·ã§ã³
ããã§ã¯ããã¹ãŠãèžãã«ããããåçŽã§ã-ãã©ãŠã¶ãŒåãã®WebSockets APIã®å©ç¹ã¯ãèãæãããã·ã³ãã«ãªãã®ã§ãã
å¿
èŠãªã©ã€ãã©ãªcbor.jsã Webixã¯æ£ã°ã©ãã®è¡šç€ºã«äœ¿çšãããŸãã
ã³ãŒãããã¹ãã«ãã¹ã¯ãŒããå
¥åããªãã§ãã ããã ããã¯åãªããã¢ã§ãã
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> </head> <body> <link rel="stylesheet" href="http://cdn.webix.com/edge/webix.css" type="text/css"> <script src="http://cdn.webix.com/edge/webix.js" type="text/javascript"></script> <script src="cbor.js" type="text/javascript"></script> <div id="chart" style="width:100%;height:300px;margin:3px"></div> <div id="stime" style="width:100%;height:300px;margin:3px"></div> <script> // globals window["secs_since_start"]=0; window["roundtrips"]=0; window["subscribed"]=false; window["lapps"]={ authkey : 0 }; // initial data set for the chart var dataset = [ { id:1, rps:0, second:0 } ] // the chart webix.ui({ id:"barChart", container:"chart", view:"chart", type:"bar", value:"#rps#", label:"#rps#", radius:0, gradient:"rising", barWidth:40, tooltip:{ template:"#rps#" }, xAxis:{ title:"Ticking RPS", template:"#second#", lines: false }, padding:{ left:10, right:10, top:50 }, data: dataset }); // might be a dialog instead. never do this in production. var login = { lapps : 1, method: "login", params: [ { user : "admin", password : "admin" } ] }; // echo request var echo= { lapps : 1, method: "echo", params: [ { authkey : 0 }, [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25] ] }; // create a websocket var websocket = new WebSocket("wss://127.0.0.1:5083/echo_lapps"); websocket.binaryType = "arraybuffer"; // on response websocket.onmessage = function(event) { window.roundtrips=window.roundtrips+1; // CBOR to native JavaScript object var message = CBOR.decode(event.data); // Verifying the channel if(message.cid === 0) { if(message.status === 1) { if(window.lapps.authkey === 0) { if(typeof message.result[0].authkey !== "undefined") // authkey is arrived { window.lapps.authkey=message.result[0].authkey; echo.params[0].authkey = window.lapps.authkey; websocket.send(CBOR.encode(echo)); } else { console.log("No authkey: "+JSON.stringify(message)); } } else { websocket.send(CBOR.encode(echo)); // already authenticaed, may subscribe to OONs if(!window.subscribed) { var subscribe={ lapps : 1, method: "subscribe", params: [ { authkey: window.lapps.authkey } ], cid: 5 }; websocket.send(CBOR.encode(subscribe)); window.subscribed=true; } } } else { console.log("ERROR: "+JSON.stringify(message)); } } else if(message.cid === 5) // server time OON { console.log("OON is received"); webix.message({ text : message.message[0], type: "info", expire: 999 }); window.secs_since_start++; $$("barChart").add({rps: window.roundtrips, second: window.secs_since_start}); window.roundtrips=0; if(window.secs_since_start > 30 ) { $$("barChart").remove($$("barChart").getFirstId()); } } else // other OONs are just printed to console { console.log("OON: "+JSON.stringify(message)); } }; // login on connection websocket.onopen=function() { console.log('is open'); window.teststart=Date.now()/1000; websocket.send(CBOR.encode(login)); } // close connection if peer sent close frame websocket.onclose=function() { console.log("is closed"); } </script> </body> </html>
ã¯ã©ã€ã¢ã³ãã¢ããªã±ãŒã·ã§ã³ã¯ãLAppSãããã³ã«ã®ãšã³ãŒã¯ã©ã€ã¢ã³ãã§ãã ã¢ããªã±ãŒã·ã§ã³ã®ãµãŒããŒéšåã¯ãæéã1ç§ã«1åãããŒããã£ã¹ããããã®OONã«åŸã£ãŠã¹ã±ãžã¥ãŒã«ãæŽæ°ãããŸãã
泚ïŒãã©ãŠã¶ã§è€æ°ã®ã¯ã©ã€ã¢ã³ããå®è¡ãããšããããŒããã£ã¹ãã®æ°ãå¢å ããŸãã ãããŒããã£ã¹ãã¯onMessageãã1ç§ã«1åéä¿¡ãããŸãã
ãããä¿®æ£ããã«ã¯ãLAppSã¹ã¿ãã¯ã®æ®ããšéä¿¡ããã¹ã¿ã³ãã¢ãã³ã¢ããªã±ãŒã·ã§ã³ãå®è£ ããå¿ èŠããããŸãã ãã®éšåã¯çŸåšéçºäžã§ãã