什么是 TogetherJS?
我们想介绍一下 TogetherJS,这是一款来自 Mozilla Labs 的实时协作工具。
TogetherJS 是一种服务,您可以将其添加到现有网站以添加实时协作功能。使用该工具,网站或 Web 应用程序上的两个或多个访问者可以相互看到对方的鼠标/光标位置、点击、跟踪彼此的浏览、一起编辑表单、一起观看视频,以及通过音频和 WebRTC 进行聊天。
TogetherJS 包含的一些功能
- 查看他人的光标和点击
- 查看滚动位置
- 观看一个人在页面上访问的页面
- 文字聊天
- 使用 WebRTC 进行音频聊天
- 表单字段同步(文本字段、复选框等)
- 同步播放/暂停/跟踪视频
- 跨站点多个页面继续会话
如何集成
TogetherJS 的许多功能不需要修改您的网站。TogetherJS 会查看 DOM 并确定它应该做的事情 - 它检测表单字段、检测一些编辑器,如 CodeMirror 和 Ace,并将它的工具栏注入您的页面。
要试用 TogetherJS,您只需要将以下代码添加到您的页面
然后为您的用户创建一个按钮来启动 TogetherJS
如果您想了解 TogetherJS 的部分功能,jsFiddle 已经启用了 TogetherJS
只需点击 **协作** 即可启动 TogetherJS。您也可以在自己的 fiddles 中使用 TogetherJS,如下所示。
扩展您的应用程序
TogetherJS 可以通过查看 DOM 来找出一些东西,但它不能同步您的 JavaScript 应用程序。例如,如果您在应用程序中有一个通过 JavaScript 更新的项目列表,该列表不会自动同步到两个用户。有时人们期望(或者至少希望)它会自动更新,但即使我们确实跨两个页面同步了 DOM,我们也无法同步您的底层 JavaScript 对象。与 Firebase 或 Google Drive Realtime API 这样的产品不同,TogetherJS 不会为您提供实时持久性 - 您的持久性和网站的功能由您自己决定,我们只是在浏览器本身中同步会话。
因此,如果您有一个丰富的 JavaScript 应用程序,您将不得不编写一些额外的代码来保持会话同步。不过,我们努力让它更容易!
举个例子,我们想使用一个简单的绘图应用程序。我们发布了 完整的示例作为 fiddle,您可以自行分叉和玩耍。
一个非常小的绘图应用程序
我们从一个非常简单的绘图程序开始。我们有一个简单的画布
然后是一些设置
// get the canvas element and its context
var canvas = document.querySelector('#sketch');
var context = canvas.getContext('2d');
// brush settings
context.lineWidth = 2;
context.lineJoin = 'round';
context.lineCap = 'round';
context.strokeStyle = '#000';
我们将使用画布上的 mousedown
和 mouseup
事件来注册我们对 mousemove
事件的 move()
处理程序
var lastMouse = {
x: 0,
y: 0
};
// attach the mousedown, mousemove, mouseup event listeners.
canvas.addEventListener('mousedown', function (e) {
lastMouse = {
x: e.pageX - this.offsetLeft,
y: e.pageY - this.offsetTop
};
canvas.addEventListener('mousemove', move, false);
}, false);
canvas.addEventListener('mouseup', function () {
canvas.removeEventListener('mousemove', move, false);
}, false);
然后 move()
函数将找出需要绘制的线条
function move(e) {
var mouse = {
x: e.pageX - this.offsetLeft,
y: e.pageY - this.offsetTop
};
draw(lastMouse, mouse);
lastMouse = mouse;
}
最后是一个绘制线条的函数
function draw(start, end) {
context.beginPath();
context.moveTo(start.x, start.y);
context.lineTo(end.x, end.y);
context.closePath();
context.stroke();
}
这足以让我们得到一个非常简单的绘图应用程序。此时,如果您在此应用程序上启用 TogetherJS,您将看到对方移动并看到他们的鼠标光标和点击,但您不会看到绘图。让我们解决这个问题!
添加 TogetherJS
TogetherJS 有一个“集线器”,它在会话中的每个人之间回显消息。它不解释消息,并且所有消息都来回传递,包括来自可能在另一个页面上的用户的消息。TogetherJS 还允许应用程序发送自己的消息,例如
TogetherJS.send({
type: "message-type",
...any other attributes you want to send...
})
发送消息(每条消息必须有一个 type
),以及监听
TogetherJS.hub.on("message-type", function (msg) {
if (! msg.sameUrl) {
// Usually you'll test for this to discard messages that came
// from a user at a different page
return;
}
});
消息类型是带命名空间的,因此您的应用程序消息不会意外地与 TogetherJS 自己的消息重叠。
为了同步绘图,我们希望监视任何正在绘制的线条并将它们发送给其他对等方
function move(e) {
var mouse = {
x: e.pageX - this.offsetLeft,
y: e.pageY - this.offsetTop
};
draw(lastMouse, mouse);
if (TogetherJS.running) {
TogetherJS.send({type: "draw", start: lastMouse end: mouse});
}
lastMouse = mouse;
}
在发送之前,我们检查 TogetherJS 是否正在运行(TogetherJS.running
)。我们发送的消息不言而喻。
接下来,我们必须监听消息
TogetherJS.hub.on("draw", function (msg) {
if (! msg.sameUrl) {
return;
}
draw(msg.start, msg.end);
});
当我们注册此监听器时,我们不必担心 TogetherJS 是否正在运行,它只能在 TogetherJS 运行时被调用。
这足以使我们的绘图变得实时和协作。但我们缺少一个东西:如果我开始绘制图像,而你加入我,你只会看到我新绘制的线条,你不会看到我已经绘制的图像。
为了解决这个问题,我们将监听 togetherjs.hello
消息,这是每个客户端在第一次到达新页面时发送的消息。当我们看到该消息时,我们将向对方发送我们画布的图像
TogetherJS.hub.on("togetherjs.hello", function (msg) {
if (! msg.sameUrl) {
return;
}
var image = canvas.toDataURL("image/png");
TogetherJS.send({
type: "init",
image: image
});
});
现在,我们只需监听这个新的 init
消息
TogetherJS.hub.on("init", function (msg) {
if (! msg.sameUrl) {
return;
}
var image = new Image();
image.src = msg.image;
context.drawImage(image, 0, 0);
});
只用几行代码,TogetherJS 就让我们创建了一个实时绘图应用程序。当然,我们必须做一些代码,但以下是一些 TogetherJS 为我们处理的事情
- 为用户提供一个 URL,与另一个用户共享以启动会话
- 建立到我们 集线器服务器 的 WebSocket 连接,该连接在客户端之间来回回显消息
- 允许用户设置他们的姓名和头像,并查看还有谁在会话中
- 跟踪谁可用、谁已离开以及谁处于空闲状态
- 简单的但必要的特性,如文本聊天可用
- 会话初始化和跟踪由 TogetherJS 处理
我们在本示例中没有做的一些事情
- 我们使用了一个固定大小的画布,这样我们就不必处理两个客户端和两个不同的分辨率。通常,TogetherJS 会处理不同类型的客户端和使用与分辨率无关的定位(甚至适用于响应式设计)。解决此问题的一种方法可能是确保固定纵横比,然后使用高度/宽度的百分比来表示所有绘图位置。
- 我们没有任何有趣的绘图工具!您可能不想同步工具本身 - 如果我用红色画笔绘制,那么您没有理由不能同时用绿色画笔绘制。
- 但清除画布之类的事情应该同步。
- 我们不保存或加载任何绘图。一旦绘图应用程序有了保存和加载功能,您可能必须更多地考虑要同步的内容。如果我创建了一张图片,保存了它,然后返回到网站加入您的会话,您的图像会覆盖我的图像吗?将每个图像放在唯一的 URL 上将使每个人要编辑哪个图像更加清晰。
想了解更多吗?
- 对 TogetherJS 的架构感兴趣吗?阅读 技术概述。
- 在 jsFiddle 上试用 TogetherJS
- 通过 文档中的按钮 找到我们:“获取实时帮助”,它将要求与我们其中一位开始 TogetherJS 会话。
- 在 irc.mozilla.org 的
#togetherjs
上通过 IRC 找到我们。 - 在 GitHub 上找到代码,如果您发现错误或有功能请求,请 打开一个问题。不要害羞,我们对各种形式的问题反馈感兴趣:想法、潜在用例(以及来自这些用例的挑战)、通过我们的文档似乎没有得到解答的问题(每个问题也暗示了我们文档中的错误)、告诉我们可能协同的应用程序。
- 在 Twitter 上关注我们:@togetherjs。
您希望在哪些类型的网站上看到 TogetherJS?我们很乐意在评论区听到您的想法。
关于 Robert Nyman [荣誉编辑]
Mozilla Hacks 的技术布道者和编辑。发表关于 HTML5、JavaScript 和开放网络的演讲和博客文章。Robert 是 HTML5 和开放网络的坚定支持者,自 1999 年以来一直在从事 Web 前端开发工作 - 在瑞典和纽约市。他经常在 http://robertnyman.com 上写博客,并且喜欢旅行和结识新朋友。
35 条评论