《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

相关文章
|
11天前
|
设计模式 前端开发 JavaScript
【JavaScript 技术专栏】JavaScript 设计模式与实战应用
【4月更文挑战第30天】本文探讨JavaScript设计模式在提升开发效率和代码质量中的关键作用。涵盖单例、工厂、观察者、装饰器和策略模式,并通过实例阐述其在全局状态管理、复杂对象创建、实时数据更新、功能扩展和算法切换的应用。理解并运用这些模式能帮助开发者应对复杂项目,提升前端开发能力。
|
15天前
|
JavaScript 前端开发
js变量的作用域、作用域链、数据类型和转换应用案例
【4月更文挑战第27天】JavaScript 中变量有全局和局部作用域,全局变量在所有地方可访问,局部变量只限其定义的代码块。作用域链允许变量在当前块未定义时向上搜索父级作用域。语言支持多种数据类型,如字符串、数字、布尔值,可通过 `typeof` 检查类型。转换数据类型用 `parseInt` 或 `parseFloat`,将字符串转为数值。
18 1
|
4天前
|
开发框架 JavaScript 中间件
中间件应用Koa.js(Node.js)
我们添加了两个中间件。第一个中间件记录请求的开始时间,并在下一个中间件执行完毕后计算并打印出请求的总时间。第二个中间件与之前的示例相同,它设置响应体为 "Hello World"
20 6
|
4天前
|
JavaScript 中间件 API
中间件应用Express.js(Node.js)
我们定义了一个名为 `logger` 的中间件函数。它接受请求对象、响应对象以及下一个中间件函数作为参数。当接收到请求时,它会打印出请求的 HTTP 方法和 URL,然后调用 `next()` 函数来将控制权传递给下一个中间件或路由处理器。我们使用 `app.use()` 方法将 `logger` 中间件添加到了应用级别的中间件堆栈中,这意味着它将对所有请求生效。
12 3
|
5天前
|
数据采集 JavaScript 数据可视化
Node.js爬虫在租房信息监测与分析中的应用
Node.js爬虫在租房信息监测与分析中的应用
|
11天前
|
开发框架 JavaScript 前端开发
【JavaScript 与 TypeScript 技术专栏】TypeScript 在 Web 开发中的前沿应用
【4月更文挑战第30天】TypeScript在Web开发中日益重要,以其强大的类型系统提升代码质量,支持组件化开发,与React、Vue、Angular等框架良好集成。在大型项目管理中,TypeScript助于代码组织和优化,提高团队协作效率。此外,它提升开发体验,提供智能提示和错误检测。众多成功案例证明其前沿应用,未来将在Web开发领域持续发挥关键作用。
|
11天前
|
前端开发 JavaScript 网络协议
【JavaScript技术专栏】WebSockets在JavaScript中的应用
【4月更文挑战第30天】WebSocket是为解决HTTP协议在实时通信上的局限而诞生的技术,提供全双工、持久连接的通信方式,适合在线聊天、实时游戏等场景。JavaScript中的WebSocket API使浏览器与服务器能建立持久连接,通过事件处理连接、发送/接收数据及错误。相较于AJAX轮询和长轮询,WebSockets更高效、实时,是现代Web实时通信的优选。
|
11天前
|
移动开发 JavaScript 前端开发
【JavaScript技术专栏】Web Worker在JavaScript中的应用
【4月更文挑战第30天】HTML5的Web Worker API解决了JavaScript单线程性能瓶颈问题,允许在后台线程运行JS代码。本文介绍了Web Worker的基本概念、类型、用法和应用场景,如复杂计算、图像处理和数据同步。通过实例展示了搜索建议、游戏开发和实时数据分析等应用,并提醒注意其无法直接访问DOM、需消息传递通信以及移动端资源管理。Web Worker为前端开发提供了多线程能力,提升了Web应用性能和用户体验。
|
12天前
|
JSON 前端开发 JavaScript
使用JavaScript制作一个简单的天气应用
使用JavaScript制作一个简单的天气应用
|
15天前
|
JavaScript 前端开发
js的let、const、var的区别以及应用案例
【4月更文挑战第27天】ES6 中,`let` 和 `const` 是新增的变量声明关键字,与 `var` 存在显著差异。`let` 允许重新赋值,而 `const` 不可,且两者都具有块级作用域。`var` 拥有函数级作用域,并可在函数内任意位置访问。`let` 和 `const` 声明时必须初始化,而 `var` 不需。根据需求选择使用:局部作用域用 `let`/`const`,全局或函数范围用 `var`,不可变值用 `const`。
23 2