什么是TogetherJS?
我们来介绍一下TogetherJS,一个从Mozilla实验室出来的实时协作工具。
TogetherJS是这样的一种服务,你能为一个已经存在的网站增加实时协作特性。使用这种工具,两个或者更多的网站或者web应用访问者能够看到别人鼠标位置,单击,追踪他人的浏览记录,一起编辑表单,观看视频,还能够通过声音以及WebRTC聊天。
TogetherJS包括这样一些特性:
- 查看他人的鼠标和点击情况。
- 查看滚动位置。
- 观察某人浏览过的页面。
- 文本聊天。
- 通过WebRTC语音聊天。
- 表单域同步(文本域,复选框等等)。
- 同步播放/暂停/追踪视频。
- 同一网站跨多个页面延续会话。
如何集成
许多TogetherJS的特性无需更改你的网站。TogetherJS浏览DOM,并决定许多应该做什么—检测表单域,一些诸如CodeMirror和Ace的编辑器,以及在你的页面注入工具条。
要想尝试TogetherJS,仅仅要做的是把这个添加到你的页面里:
|
1
|
&
lt
;
script
src
=&
quot
;
https
:
//togetherjs.com/togetherjs.js"></script>
|
然后创建一个按钮,让你的用户开始TogetherJS:
|
1
2
3
4
5
|
&
lt
;
button
id
=&
quot
;
collaborate
&
quot
;
type
=&
quot
;
button
&
quot
;
&
gt
;
Collaborate
&
lt
;
/
button
&
gt
;
&
lt
;
script
&
gt
;
document
.
getElementById
(
&
quot
;
collaborate
&
quot
;
)
.
addEventListener
(
&
quot
;
click
&
quot
;
,
TogetherJS
,
false
)
;
&
lt
;
/
script
&
gt
;
|
如果你想看一些Together做了什么,jsFiddle已经启用了TogetherJS:
只需要单击下Collaboration,就会启动TogetherJS了。你也可以自如地使用TogetherJS,下面我们会讲到。
扩展你的应用
TogetherJS可以通过浏览DOM来解决一些事情,但不能同步你的JavaScript应用。比如,在你的应用中有一些条目是通过JavaScript来更新的,那么它们就不会相互间自动同步。有时人们期望能自动更新,但即使做了跨页面间的DOM同步,我们也不可能会做到同步底层的JavaScript对象。不像有些产品,如Firebase或者谷歌Drive实时API,TogetherJS没有赋予你实时的持久性。网站持久性这样的功能是由你决定,我们仅仅只是在浏览器中同步会话而已。
我们使用了一个简单的绘画应用来举例。我们已经发布了完整的例子作为模板,你可以派生以及亲自体验。
一个非常小的绘画应用
我们开始一个非常简单的绘画程序,我们有一个简单的画布:
|
1
2
3
|
&
lt
;
canvas
id
=&
quot
;
sketch
&
quot
;
style
=&
quot
;
height
:
400px
;
width
:
400px
;
border
:
1px
solid
#000">
&
lt
;
/
canvas
&
gt
;
|
然后是一些设置:
|
1
2
3
4
5
6
7
8
9
|
// get the canvas element and its context
var
canvas
=
document
.
querySelector
(
&
#039;#sketch');
var
context
=
canvas
.
getContext
(
&
#039;2d');
// brush settings
context
.
lineWidth
=
2
;
context
.
lineJoin
=
&
#039;round';
context
.
lineCap
=
&
#039;round';
context
.
strokeStyle
=
&
#039;#000';
|
我们使用画布的mousedown和mouseup事件去为mousemove事件注册move()处理程序。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
var
lastMouse
=
{
x
:
0
,
y
:
0
}
;
// attach the mousedown, mousemove, mouseup event listeners.
canvas
.
addEventListener
(
&
#039;mousedown', function (e) {
lastMouse
=
{
x
:
e
.
pageX
-
this
.
offsetLeft
,
y
:
e
.
pageY
-
this
.
offsetTop
}
;
canvas
.
addEventListener
(
&
#039;mousemove', move, false);
}
,
false
)
;
canvas
.
addEventListener
(
&
#039;mouseup', function () {
canvas
.
removeEventListener
(
&
#039;mousemove', move, false);
}
,
false
)
;
|
然后move()函数就会计算出需要绘画的线条:
|
1
2
3
4
5
6
7
8
|
function
move
(
e
)
{
var
mouse
=
{
x
:
e
.
pageX
-
this
.
offsetLeft
,
y
:
e
.
pageY
-
this
.
offsetTop
}
;
draw
(
lastMouse
,
mouse
)
;
lastMouse
=
mouse
;
}
|
最后是绘画线条的函数:
|
1
2
3
4
5
6
7
|
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也能让应用发送自己的消息,如这样发送消息(每个消息必须有一个类型):
|
1
2
3
4
|
TogetherJS
.
send
(
{
type
:
&
quot
;
message
-
type
&
quot
;
,
.
.
.
any
other
attributes
you
want
to
send
.
.
.
}
)
|
然后这样去监听:
|
1
2
3
4
5
6
7
|
TogetherJS
.
hub
.
on
(
&
quot
;
message
-
type
&
quot
;
,
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自己的消息。
为了要同步绘画中我们想观看的任意一条正在画的线,并且把这些发送给其它人:
|
1
2
3
4
5
6
7
8
9
10
11
|
function
move
(
e
)
{
var
mouse
=
{
x
:
e
.
pageX
-
this
.
offsetLeft
,
y
:
e
.
pageY
-
this
.
offsetTop
}
;
draw
(
lastMouse
,
mouse
)
;
if
(
TogetherJS
.
running
)
{
TogetherJS
.
send
(
{
type
:
&
quot
;
draw
&
quot
;
,
start
:
lastMouse
end
:
mouse
}
)
;
}
lastMouse
=
mouse
;
}
|
在发送前,我们应该检查下TogetherJS确实正在运行(TogetherJS.running)。我们发送的消息应该要一目了然的。
下面,我们要去监听这些消息:
|
1
2
3
4
5
6
|
TogetherJS
.
hub
.
on
(
&
quot
;
draw
&
quot
;
,
function
(
msg
)
{
if
(
!
msg
.
sameUrl
)
{
return
;
}
draw
(
msg
.
start
,
msg
.
end
)
;
}
)
;
|
当我们注册这个监听器时,我们不必担心TogetherJS是否正在运行,因为只有在它在运行时才能被调用。
这样足够让我们的绘画更生动并且协作的。但我们还缺少一个:如果我开始画一个图像,然后你加入了我,你仅仅会看到我画的新的线条,你看不到我已经画过的图像。
为了要解决这个,我们会去监听togertherjs.hello消息,它在每个客户端首次访问一个新的页面时发送。当我们监听到这个消息时,我们会发送我们的画布上的图像给其他人。
|
1
2
3
4
5
6
7
8
9
10
|
TogetherJS
.
hub
.
on
(
&
quot
;
togetherjs
.
hello
&
quot
;
,
function
(
msg
)
{
if
(
!
msg
.
sameUrl
)
{
return
;
}
var
image
=
canvas
.
toDataURL
(
&
quot
;
image
/
png
&
quot
;
)
;
TogetherJS
.
send
(
{
type
:
&
quot
;
init
&
quot
;
,
image
:
image
}
)
;
}
)
;
|
现在我们只要去监听新的init消息:
|
1
2
3
4
5
6
7
8
|
TogetherJS
.
hub
.
on
(
&
quot
;
init
&
quot
;
,
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的#togetherjs上联系我们。irc.mozilla.org
在Github上查找代码,如果你遇到bug或者有特性请求,请提一个问题。请别害羞,我们对许多种反馈非常感兴趣:想法,潜在用例(以及来自这些用例的挑战),和那些看起来通过文档无法回答的问题(这也同时表示我们文档上的bug)。请告诉我们有关潜在的协同应用。
TogetherJS 是一款由 Mozilla 实验室开发的实时协作工具,它允许用户在现有网站上增加实时协作功能,如鼠标和点击追踪、表单同步、视频同步等。本文介绍了如何将 TogetherJS 集成到一个简单的在线绘画应用中,实现多人同步绘画。




1196

被折叠的 条评论
为什么被折叠?



