2020年11月11日 星期三

重新踏入網頁開發 (5) - Blocking & Non-Blocking

Blocking & Non-Blocking

    Nodejs 為事件觸發的單一執行緒,不像 Apache + PHP 會自動開一個 Thread 去接每一個 Request。
    Blocking Code 示範 (程式碼另有 index.js 請參照重新踏入網頁開發 (4) - Dependency injection)
  • route.js
        function start_requset_handle () {
            console.log("Start request.");
            
            // Sleep for 10 seconds
            function sleep(milliSeconds) {
                var startTime = new Date().getTime();
                while (new Date().getTime() < startTime + milliSeconds);
            }
            sleep(10000);
        }
    
        function upload_requset_handle () {
            console.log("Upload request.");
        }
    
        function requset_handler (url) {
            var handle = {};
            handle['/'] = start_requset_handle;
            handle['/start'] = start_requset_handle;
            handle['/upload'] = upload_requset_handle;
    
            if (typeof handle[url] === 'function') {
                handle[url]();
            } else {
                console.log("No request handler found for " + url);
            }
        }
    
        export function route(url) {
            requset_handler(url);
        }
  • server.js
        import http from 'http'
        import url from 'url'
    
        export function serverStart(route) {
            function onRequest(request, response) {
                var path_name = url.parse(request.url).pathname;
                console.log("Request for " + path_name + " received");
                
                // Routing function
                route(path_name);
    
                response.writeHead(200, {"Content-Type": "text/plain"});
                response.write("Hello World.\n");
                response.end();
            }
            http.createServer(onRequest).listen(8888);
            console.log("Server has started...");
        }
    這裡先用 requset_handler() 這 function 去應對 2 種 url 的 request。client 端 request http://localhost:8888/start 會等 10 秒才回覆 Hello World.,request http://localhost:8888/upload 則立即回覆。因為 nodejs 為單一執行緒,如果有人先 request start, 後面即使是 request upload 也要跟著等 10 秒。
    Non-Blocking Code 示範 (程式碼另有 index.js 請參照重新踏入網頁開發 (4) - Dependency injection)
  • route.js
        import { exec } from 'child_process';
    
        function start_requset_handle (response) {
            console.log("Start request.");
            var content = "empty\n";
            exec("ls -alh", function (error, stdout, stderr) {
                content = stdout;
                response.writeHead(200, {"Content-Type": "text/plain"});
                response.write(content);
                response.end();
            });
            // 放在外面會讓 server 直接回 empty
            // response.writeHead(200, {"Content-Type": "text/plain"});
            // response.write(content);
            // response.end();
        }
    
        function upload_requset_handle (response) {
            console.log("Upload request.");
            response.writeHead(200, {"Content-Type": "text/plain"});
            response.write("Uploading...\n");
            response.end();
        }
    
        function requset_handler (url, response) {
            var handle = {};
            handle['/'] = start_requset_handle;
            handle['/start'] = start_requset_handle;
            handle['/upload'] = upload_requset_handle;
    
            if (typeof handle[url] === 'function') {
                handle[url](response);
            } else {
                console.log("No request handler found for " + url);
            }
        }
    
        export function route(url, response) {
            requset_handler(url, response);
        }
  • server.js
        import http from 'http'
        import url from 'url'
    
        export function serverStart(route) {
            function onRequest(request, response) {
                var path_name = url.parse(request.url).pathname;
                console.log("Request for " + path_name + " received");
                
                // Routing function
                route(path_name, response);
            }
            http.createServer(onRequest).listen(8888);
            console.log("Server has started...");
        }
    import nodejs 內建的 child_process,解決了問題。傳 response 進去是為了讓 request 處理完再做回覆。
上一篇 :
下一篇 :
參考資料 :

Popular Posts