服务器端渲染

在本节中,您将了解如何在服务器上运行Verge3D以在无外设模式(headless mode)下执行渲染。如果用户的硬件较低端,或网络速度较慢,或需要在视觉效果最佳时仍可进行三维交互,则可以考虑使用服务器端渲染。

在服务器端以headless mode模式运行Chrome

您可以在headless mode下运行Chrome(或Chromium),例如不使用屏幕或图形界面。要开启该模式,请指定 --headless 参数:

google-chrome --headless --use-gl=egl https://www.soft8soft.com/webglreport

指定 --use-gl=egl 参数,可启用headless模式下的GPU加速渲染:

WebGL report page
Unmasked Vendor/Renderer 行表示Chrome Headless使用目标系统的真实GPU

默认情况下,headless命令没有任何意义。要启用远程调试页面,还需指定 --remote-debugging-port=9222 参数。

google-chrome --headless --use-gl=egl --remote-debugging-port=9222 https://www.soft8soft.com/webglreport

之后即可运行常规桌面Chrome来检查页面。配置 Discover network targets ,然后点击 inspect

Headless模式的另一个重要功能是能够用于生成屏幕截图:

google-chrome --headless --use-gl=egl --screenshot https://www.soft8soft.com/webglreport

或者用来生成PDF文件:

google-chrome --headless --use-gl=egl --print-to-pdf https://www.soft8soft.com/webglreport

请在Google官方 文档中 了解有关Chrome Headless的更多信息。

使用 Node.js 和 Puppeteer

有时您可能需要更好地控制 Chrome Headless 模式,例如以自动方式截取屏幕截图,或实现一些客户端-服务器例程以从服务器请求屏幕截图。为此,Google 开发了一个不错的 Node.js 库,名为 Puppeteer 。

安装方式很简单,只需在任意目录下添加一个名为 package.json 的文件(点击下载),添加如下脚本:

{ "description": "Headless Chrome tests with Puppeteer", "dependencies": { "commander": "*", "puppeteer": "*" } }

然后转到该目录并执行:

npm install

以安装Puppeteer和所有必需的依赖项(包括Chromium浏览器的预构建二进制文件)。

使用以下 Node.js 脚本(点击下载)自动截取 Verge3D 应用的屏幕截图:

#!/usr/bin/node const program = require('commander'); const puppeteer = require('puppeteer'); program .option('-u, --url [url]', 'URL to open', 'http://localhost:8668/') .option('-s, --screenshot-path programmers_guide/Server-Side-Rendering', 'A path where to save the screenshot', './screenshot.png') .option('-t, --timeout [ms]', 'Timeout after page loading before taking the screenshot', function(val) { return parseInt(val); }, 1000) .option('-W, --viewport-width [px]', 'The width of the viewport', function(val) { return parseInt(val); }, 1920) .option('-H, --viewport-height [px]', 'The height of the viewport', function(val) { return parseInt(val); }, 1080) .parse(process.argv); async function run() { console.log('Launching headless Chrome...'); const browser = await puppeteer.launch({ args: ['--use-gl=egl'] }); console.log('Opening new page...'); const page = await browser.newPage(); const opts = program.opts(); console.log('Setting viewport size to ' + opts.viewportWidth + 'x' + opts.viewportHeight + '...'); await page.setViewport({ width: opts.viewportWidth, height: opts.viewportHeight }); console.log('Opening ' + opts.url + ' ...'); await page.goto(opts.url); console.log('Waiting for ' + opts.timeout + 'ms ...'); await timeout(opts.timeout); console.log('Taking screenshot...'); await page.screenshot({ path: opts.screenshotPath, type: 'png' }); console.log('Page\'s screenshot saved to ' + opts.screenshotPath); console.log('Closing Chrome...'); await browser.close(); } function timeout(ms) { return new Promise(resolve => setTimeout(resolve, ms)); }; run();

将代码作为 screenshot.js 放在您安装 Puppetter 的同一目录中并启动:

node screenshot.js -u https://cdn.soft8soft.com/demo/applications/spinner/spinner.html

为Spinner应用截图并保存为 screenshot.png 图片文件:

这个屏幕截图脚本还有各种有用的选项。在运行时带上 -h 参数可查看帮助信息:

node screenshot.js -h

您还可以使用Puppeteer捕获Verge3D渲染的视频。有关详细信息,请参阅此处

后续步骤

screenshot.js 脚本中,我们使用 timeout 属性来等待应用加载。在实际场景中,您可能需要提供更高级的等待例程 (点击下载):

console.log('Waiting for application loading...'); await page.evaluate(() => { return new Promise(resolve => { const interval = setInterval(() => { if (window.v3d.apps !== undefined && window.v3d.apps.length > 0) { clearInterval(interval); resolve(); } }, 0); }); }); await page.evaluate(() => { const app = window.v3d.apps[0]; return new Promise(resolve => { app.addEventListener('onAfterRender', () => { resolve(); }); }); });

此外,我们没有涵盖任何客户端-服务器交互。如果需要,您可以通过 Node.js 实现简单的 simple HTTP server 或更高级的 WebSocket server

遇到问题?

欢迎您随时在 论坛上提问!您还可以加入中文用户社区QQ群(171678760),在线寻求帮助。