《JavaScript高效图形编程(修订版)》——6.11 一个图形使用画布的WebSockets聊天应用

简介: HTTP数据携带了大量的头信息。请求一个字节的数据可能会导致发送数百个字节的、额外的、“看不见的”头信息也被发送。头信息通常包含被传送数据的性质,如内容类型、缓存、编码等。

本节书摘来自异步社区《JavaScript高效图形编程(修订版)》一书中的第6章,第6.11节,作者:【美】Raffaele Cecco著,更多章节内容可以访问云栖社区“异步社区”公众号查看

6.11 一个图形使用画布的WebSockets聊天应用

在下面的例子中我们将看到一个更实用的画布应用程序:一个伪3D聊天应用程序(如图6-15所示)。这个例子将演示如何将画布和其他HTML5特性如WebSockets结合。

screenshot

6.11.1 WebSockets优势
除画布外,另一个同样令人振奋(但可能比较不知名)的HTML5元素是WebSockets。虽然这本书是关于图形的,但还是值得讨论一下为什么WebSockets对现代Web应用程序意义重大,以及如何将它们与画布集成。

通常服务器和客户端浏览器之间是用HTTP协议传递数据的,但HTTP有一定的局限性(和新的WebSockets相比),使它不适合高速、双向的网络通信。

HTTP是单行线

HTTP的模式是:客户端Web浏览器向服务器请求数据,服务器满足其要求。服务器不能在没有被请求的情况下“推送”信息到客户端。

它的开销很大

HTTP数据携带了大量的头信息。请求一个字节的数据可能会导致发送数百个字节的、额外的、“看不见的”头信息也被发送。头信息通常包含被传送数据的性质,如内容类型、缓存、编码等。

它的连接都是非持久的

为每个HTTP请求,都必须重新建立连接,发送数据,再关闭连接。这好比是电话交谈时每说完一句话就得重新拨号。

你可以使用Comet/长轮询等编程技术,模拟持久、双向的连接,从而提高HTTP的性能。虽然这些技术可以提供一些改善,但有可能服务器无法支持这些技术所需要的超高HTTP连接数;如Apache这样的服务器在处理此类连接时就不是特别有效率。最终你会发现:对多人游戏和其他快速通信的应用程序而言,HTTP的网络传输效率太低,即使用前面的技术还是无力回天。

WebSockets通过真正持久和双向的连接来解决这些问题。客户端可以在任何时候给服务器发送数据,反之亦然。此外,数据开销非常小,因为一旦建立了连接就不需要传递头数据。只是在数据前后各加了一个0字节(0x00)和0xFF表示结束和终止。

6.11.2 WebSockets支持和安全
目前有Firefox 4+、Google Chrome 4+、Opera 10.70+和Safari5支持WebSockets。不过由于WebSockets通信相关的安全问题,使得Firefox和Opera的开发者关闭了默认的WebSockets功能,而其他浏览器厂商可能也会采取同样的行动。
在解决安全问题之前,默认WebSockets功能看来还处于不太稳定的状态。然而,我们可以现在就试验WebSockets协议,为未来做好准备。

在Firefox 4和Opera 11上的WebSockets

幸运的是,Firefox和Opera用户可以在开发中打开WebSockets功能。

Firefox4:

1.在浏览器的地址栏输入about:config。

2.查找和更改network.websocket.override-security-block标志。

Opera:

1.在浏览器的地址栏输入opera:config。

2.在首选项编辑器,打开“用户首选项”部分,并设置Enable WebSockets。

6.11.3 聊天应用程序
我们的聊天应用程序大致由4个主要部分组成:

  • 在Web服务器上运行的套接字服务器;
  • 可以左右移动和“聊天”的客户化身(avatar);
  • 聊天文字;
  • 文本输入区。

当用户连接到聊天页面时,将自动为他创建一个颜色随机的化身。然后用户可以在页面上点击来移动化身,也可以在聊天框中输入文字。化身的移动和聊天文字将反映给所有其他的连接用户。也就是说,每个用户看到的都是相同的页面,但只能控制自己的化身。

1.套接字服务器
套接字服务器需要处理连接,并在连接的客户端之间传输信息。它必须运行在所有客户端可以连接到的服务器上。

套接字服务器的编程语言可以是任何流行的服务器端语言,如PHP、Java或Python。JavaScript程序员可以关注node.js,它是一个基于服务器的JavaScript实现和使其适合高效网络编程的一些相关库。

这个例子里我选择了PHP,因为几乎所有基于Linux的托管主机上都已安装了PHP。

提示:
套接字服务器(server.php)实际上由两部分组成:一个通用的套接字处理类(WebSocketServer),可用于各种应用;一个聊天应用程序特定的回调函数(process()),这是为我们的聊天应用程序定制的。请从本书的代码中阅读server.php的源代码。
本书不可能展开讨论PHP。PHP语言比较简单易学,网上有大量的学习资源。如果你打算仔细看看套接字服务器代码,请注意下面几个PHP语法:

  • 变量前面有一个美元符号(不要和jQuery中的$混淆)。
  • 字符串连接符号不是加号(+),而是句号(.)。这点比较特殊。

套接字服务器至少要执行以下操作:

  • 接受新连接,并保持连接的客户端列表;
  • 接收来自客户端的数据更新(聊天的文字和位置);
  • 传输数据更新到所有连接的客户端;
  • 当连接断开时(如浏览器关闭),从列表中删除客户。

2.在本地安装一个网站托管环境
除非你有专门或虚拟主机的root权限,否则是不可能让套接字服务器工作的。正确配置的共享网站托管环境都会有一个防火墙,防止使用任何的通信端口。幸运的是,你可以安装一个本地环境来运行服务器端代码。

安装一个网站托管环境曾经是痛苦而漫长的过程。幸好“Apache Friends”XAMPP软件将所需模块(Apache和PHP)合并到一个下载文件中,你可以在几分钟之内将其安装到Windows、Mac或Linux系统上。

图6-16显示了XAMPP的控制面板。注意PHP是以透明方式运行的,在控制面板中不显示。

screenshot

要通过XAMPP启动套接字服务器,单击XAMPP控制面板上的Shell按钮。这将呈现一个命令行,使你可以运行套接字服务器(如图6-17所示)。输入php path-to-socket-serverserver.php来运行套接字服务器,然后按Enter键。

screenshot

你需要将server.php的路径改为这个文件在你本地机器上的位置。

套接字服务器现在正在等待聊天应用JavaScript端的连接。

最后,我们需要在浏览器中运行实际的聊天网页(JavaScript)。

当我们使用file:///协议时,我们从浏览器直接访问HTML文件,并没有用到Apache。

你还可以打开多个浏览器来测试多个聊天网页的实例,自己和自己聊天。

测试聊天应用程序更精细的一个方式是通过网络(Web服务器)来运行聊天服务器、提供聊天页面。这里涉及的步骤有:

(1)在Web服务器上,修改Apache的httpd.conf文件中的一个虚拟主机条目,将Web服务器的IP地址映射到Web服务器上聊天应用程序的位置。定义的第一个虚拟主机是Web服务器IP地址的默认主机。

(2)通过XAMPP控制面板启动Apache。

网络上其他计算机的用户可以通过在合适的浏览器上输入Web服务器的IP地址,连接到聊天应用程序。

3.相机
相机对象决定了聊天区域的透视图。它包含了3个应用函数:

setFOVandYPos()

传入相机的视野(FOV, Field of View)的角度和垂直位置。从视野计算相机距离使你可以改变画布大小,而不影响呈现的视图(假设高宽比不变)。我们使用125度的视野和−128的相机y位置。

worldToScreen()

从传入的世界坐标计算画布屏幕上的坐标。它给化身计算尺度使得它们在远处显得比较小,有效地模拟透视效果。

screenToWorld()

这个函数和 worldToScreen()相反,从画布上的位置得到对应的世界坐标。screenToWorld()将鼠标单击的位置转化为用户化身的新世界坐标位置。我们使用toFixed()方法防止返回值过于精细。例如,188.42620390960207将被188.426替代,因为前者需要更长的网络传输时间且没有太多必要。

screenshot

4.化身
化身是客户端的图形表示。它们各自以随机颜色出现,以区别于其他化身。我们通过单击鼠标将其移动要新位置上。它们由分别代表头和身体的两个矢量形状组成。我们对化身用径向渐变填充以增加其深度效果,使用深色描边来将其和背景分离。
screenshot
screenshot

5.聊天文字
聊天的文字将在“发言的”化身上方出现,并随着用户输入更多文字逐渐向屏幕上方移动。为了使文字更清晰并加入聊天泡泡的效果,我们用白色填充的圆角矩形环绕文字,并用化身的颜色给这个矩形描边。

当化身聊天时,textScroller对象管理和绘制生成的文字。addText()方法将新的文字添加到列表的开始,同时删除5句之前的文字。这创建了垂直的滚动效果,文字向画布上方移动时最顶层的文字将丢失。这个方法接受化身的水平位置作为文字的中心位置,以及化身的颜色。

drawText()方法遍历文字列表,并绘制每一行文字。为使文字更加突出,我们在文字周围显示白色填充的圆角矩形,并用化身颜色对其描边。我们使用画布的 measureText()方法来计算文本和圆角矩形的宽度。

screenshot

6.背景
drawBackground 对象绘制一个渐变的蓝天和绿地。蓝天和绿地都被渐变为白色以给人一种三维的深度感。

screenshot

7.初始化
initAndGo()函数执行各种设置工作,如建立事件处理程序、连接到服务器。最后它执行移动和绘制头像与文字的循环:
screenshot
screenshot
screenshot

8.页面代码
下面是聊天应用程序的HTML页面布局,被保存在一个名为canvas-webSockets- chat.htm的文件中:

screenshot

相关文章
|
5天前
|
JavaScript 前端开发 算法
JavaScript 中通过Array.sort() 实现多字段排序、排序稳定性、随机排序洗牌算法、优化排序性能,JS中排序算法的使用详解(附实际应用代码)
Array.sort() 是一个功能强大的方法,通过自定义的比较函数,可以处理各种复杂的排序逻辑。无论是简单的数字排序,还是多字段、嵌套对象、分组排序等高级应用,Array.sort() 都能胜任。同时,通过性能优化技巧(如映射排序)和结合其他数组方法(如 reduce),Array.sort() 可以用来实现高效的数据处理逻辑。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
5天前
|
JavaScript 前端开发 API
JavaScript中通过array.map()实现数据转换、创建派生数组、异步数据流处理、复杂API请求、DOM操作、搜索和过滤等,array.map()的使用详解(附实际应用代码)
array.map()可以用来数据转换、创建派生数组、应用函数、链式调用、异步数据流处理、复杂API请求梳理、提供DOM操作、用来搜索和过滤等,比for好用太多了,主要是写法简单,并且非常直观,并且能提升代码的可读性,也就提升了Long Term代码的可维护性。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
5天前
|
移动开发 运维 供应链
通过array.some()实现权限检查、表单验证、库存管理、内容审查和数据处理;js数组元素检查的方法,some()的使用详解,array.some与array.every的区别(附实际应用代码)
array.some()可以用来权限检查、表单验证、库存管理、内容审查和数据处理等数据校验工作,核心在于利用其短路机制,速度更快,节约性能。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
5天前
|
供应链 JavaScript 前端开发
通过array.every()实现数据验证、权限检查和一致性检查;js数组元素检查的方法,every()的使用详解,array.some与array.every的区别(附实际应用代码)
array.every()可以用来数据验证、权限检查、一致性检查等数据校验工作,核心在于利用其短路机制,速度更快,节约性能。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
5天前
|
JavaScript 前端开发 Java
详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用
柯里化是一种强大的函数式编程技术,它通过将函数分解为单参数形式,实现了灵活性与可复用性的统一。无论是参数复用、延迟执行,还是函数组合,柯里化都为现代编程提供了极大的便利。 从 Redux 的选择器优化到复杂的数据流处理,再到深度嵌套的函数优化,柯里化在实际开发中展现出了非凡的价值。如果你希望编写更简洁、更优雅的代码,柯里化无疑是一个值得深入学习和实践的工具。从简单的实现到复杂的应用,希望这篇博客能为你揭开柯里化的奥秘,助力你的开发之旅! 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一
|
5天前
|
数据采集 JavaScript 前端开发
JavaScript中通过array.filter()实现数组的数据筛选、数据清洗和链式调用,JS中数组过滤器的使用详解(附实际应用代码)
用array.filter()来实现数据筛选、数据清洗和链式调用,相对于for循环更加清晰,语义化强,能显著提升代码的可读性和可维护性。博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
2月前
|
缓存 NoSQL JavaScript
Vue.js应用结合Redis数据库:实践与优化
将Vue.js应用与Redis结合,可以实现高效的数据管理和快速响应的用户体验。通过合理的实践步骤和优化策略,可以充分发挥两者的优势,提高应用的性能和可靠性。希望本文能为您在实际开发中提供有价值的参考。
69 11
|
2月前
|
敏捷开发 人工智能 JavaScript
Figma-Low-Code:快速将Figma设计转换为Vue.js应用,支持低代码渲染、数据绑定
Figma-Low-Code 是一个开源项目,能够直接将 Figma 设计转换为 Vue.js 应用程序,减少设计师与开发者之间的交接时间,支持低代码渲染和数据绑定。
152 3
Figma-Low-Code:快速将Figma设计转换为Vue.js应用,支持低代码渲染、数据绑定
|
2月前
|
JavaScript 前端开发
【Vue.js】监听器功能(EventListener)的实际应用【合集】
而此次问题的核心就在于,Vue实例化的时机过早,在其所依赖的DOM结构尚未完整构建完成时就已启动挂载流程,从而导致无法找到对应的DOM元素,最终致使计算器功能出现异常,输出框错误地显示“{{current}}”,并且按钮的交互功能也完全丧失响应。为了让代码结构更为清晰,便于后续的维护与管理工作,我打算把HTML文件中标签内的JavaScript代码迁移到外部的JS文件里,随后在HTML文件中对其进行引用。
58 8
|
2月前
|
监控 安全 中间件
Next.js 实战 (十):中间件的魅力,打造更快更安全的应用
这篇文章介绍了什么是Next.js中的中间件以及其应用场景。中间件可以用于处理每个传入请求,比如实现日志记录、身份验证、重定向、CORS配置等功能。文章还提供了一个身份验证中间件的示例代码,以及如何使用限流中间件来限制同一IP地址的请求次数。中间件相当于一个构建模块,能够简化HTTP请求的预处理和后处理,提高代码的可维护性,有助于创建快速、安全和用户友好的Web体验。

热门文章

最新文章