作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.
Alexandre Mondaini Calvão
Verified Expert in Engineering
15 Years of Experience

Alexandre是Ruby on Rails开发专家,他在Java和各种前端技术方面也很有经验.

Share

我在Toptal做工程师已经一年了, 自从我加入网络以来,一直在做同一个WebRTC框架项目: Ondello这是一项连接医生和病人的服务 WebRTC. 想想医疗保健领域的Google+ Hangouts吧.

(WebRTC是一种允许通过web浏览器进行实时通信的技术. The best example, again, 是Google+ Hangouts:没有任何外部应用程序, 你可以进行实时视频聊天. There’s a good write-up here.)

当我刚加入昂代洛时,我被聘为 高级Ruby on Rails开发人员, tasked to build a service up from scratch. 如今,我们是一个由多个开发人员组成的团队,致力于一个相当大、复杂的系统.

在这篇文章中,我想分享昂代洛背后的故事. 具体来说,我想谈谈:

  1. 尖端技术(e.g., WebRTC)是非常困难的……
  2. 一个简单的WebRTC Rails应用程序如何变得不那么简单,以及……
  3. 为什么一个受雇的Ruby开发人员最终几乎没有编写Ruby代码.

尖端技术及其带来的问题

正如我前面提到的,Ondello完全是关于WebRTC平台的. But only Chrome, Firefox, and Opera 目前支持WebRTC调用而不使用插件. 我们的目标是支持所有的浏览器(Safari和Internet Explorer是上面列表中明显遗漏的), as such, 我们不得不使用一个相对年轻的插件.

当我开始使用插件时, 事情进展得很顺利,因为他们有很好的文档和官方的WebRTC教程和指南. 但是随着我们产品的扩展,我们的需求变得越来越复杂, 情况急转直下. 这并不像排除Rails问题那么简单.

缺乏WebRTC支持社区

由于WebRTC是一项最近的技术,特别是这个插件是相当新的(仍然是邀请式的,并且有相当大的使用费), 它们还没有吸引到大量的开发者, 更不用说为像我这样的人编写指南和教程的WebRTC Rails开发人员了. 这些因素严重损害了围绕它的开发者社区,而这实际上是不存在的.

WebRTC应用程序开发人员从太空进行宇航员故障排除.

我从来没有认为这是一个大问题——直到我错过了它. 对于大多数应用平台和技术, 一般情况下容易处理, 但要在一个非常具体的期限内以一种非常具体的方式工作,这需要对技术有深入的了解 or 访问其他开发人员.

想象一下在一个没有 StackOverflow——你的工作效率会受到多大的阻碍?

当然,我们可以访问插件的开发人员,他们提供了我所期望的帮助. 这减轻了一些问题,但这与简单的谷歌搜索是不一样的 “WebRTC插件foo不工作,由于酒吧”.

Who’s at Fault?

每个软件都有bug.

但是在这些新的WebRTC技术中, 很难分辨谁是父亲,谁是孩子. 换句话说:当我们发现一个失败的测试用例或明显的错误时,我们并不清楚是否 we 是谁的错,还是我们利用的代码库中存在错误.

在谷歌上很容易搜索到的大多数技术变成了一个巨大的电子邮件链,随后是代码审查和, in some cases, 与WebRTC开发者的会议.

在谷歌上很容易搜索到的大多数技术变成了一个巨大的电子邮件链,随后是代码审查和, in some cases, 与开发者的会议.

在这个问题上,我想说,由于插件的开发团队和我们自己的团队,我们有大约50%的bug率.

WebRTC平台的频繁更新

这个WebRTC插件相对幼稚的另一个后果是 update rate. 较年轻的软件更新更频繁,而这些更新经常会中断. With the plugin, 我们不能继续使用旧版本(作为电信技术), 所有用户必须使用相同的版本来相互通信), 所以每个版本都需要重构.

这些更新很痛苦. 通常,我们必须完全重写稳定的代码以与最新的更改同步. In some cases, 如果没有社区,测试就会失败, 你向哪里寻求帮助?

In some cases, 如果没有社区,测试就会失败, 你向哪里寻求帮助?

与WebRTC移动支持的问题

随着我们产品的发展,我们的大多数客户开始询问移动支持.

如果说WebRTC JavaScript库很困难,那么Android库更是如此. 我花了两天时间来编译示例应用程序, 五个多小时只是为了了解它是如何工作的——整个过程赋予了“痛苦”这个词新的含义.

经过10个小时的不成功的编译,我精神崩溃了,哭了一下. 两个多小时后,我振作起来,把事情做好了. Pff—and 奥巴马说你们应该制作自己的电子游戏.

WebRTC iOS库更简单,开发团队显然在它上面花了更多的时间. 我们只用了几个小时就把它用起来了.

WebRTC Meets JavaScript

除了WebRTC插件,我们的JavaScript代码库教会了我很多关于复杂性的知识. 由于大多数WebRTC框架都是基于JavaScript进行配置的.g., Plivo的VoIP网络框架),这是我在昂代洛的头三个月里唯一使用的语言.

随着代码库的增长,它自然变得越来越难以管理. 我们有深度嵌套的回调, poor modularization, 这是一家初创公司第一次使用WebRTC JavaScript应用程序, as you might expect, it was a little messy.

最终,我们过渡到 CoffeeScript. This reduced the size 我们的代码库,并增加了它 readability 很重要,但不足以解决我们真正的复杂性问题.

PubSub

Then, we found PubSub这是一个很棒的JavaScript发布/订阅库,我强烈推荐它. This little guy helped us decouple a significant portion of our JavaScript logic; our refactoring process took a turn for the best with its discovery.

Why was PubSub so useful? WebRTC本质上与媒体和连接有关,因此充满了事件. 有了PubSub,我们可以很容易地在高层次的抽象上观察特定的事件. 这是一个很好的解决方案, 还有一个很好的例子:当你写得很好的时候,你不会解决已经解决的问题, 有良好文档的开源(甚至专有)解决方案可以简化您的代码库并加快开发速度, use them.

更具体地说:没有PubSub, 每次用户的相机响了, 我们必须更新三个代表摄像机状态的复选框:

Camera_went_off = function() {
    $(''#checkbox1').removeAttr('checked');
    $(''#checkbox2').removeAttr('checked');
    $(''#checkbox3').removeAttr('checked');
}

With PubSub, 我可以触发“camera_went_off”事件,并让所有三个复选框都侦听它. In addition, 如果有人点击了其中一个复选框, 它还可以发布此事件以通知其他复选框更新自己.

用AngularJS创建一个单页的WebRTC应用

如前所述,我们使用了一个WebRTC插件来支持更广泛的浏览器. 但是这个插件必须在用户加载新页面时加载. 这可能会对性能、流动性等产生可怕的影响.

唯一的答案是保持插件加载,只要用户进入网站, 并确保用户不会重新加载或进入不同的网页. This sounds impossible. 但实际上,它可以用 single-page application (SPA).

At this point, AngularJS came into play.

在Angular中,我们过渡到了SPA. 当用户进入网站时,他们只加载一次插件. 性能的提升是瞬间的.

Angular允许我们构建SPA, 这反过来又允许我们加载插件一次(当用户进入系统时),而且只有一次. 然后,用户的任何调用几乎都是即时的,因为插件已经被加载了. 这需要大量的工作,但它是值得的——性能的提升是即时的.

Angular还从整体上改进了我们的JavaScript代码 MVC structure. 而大部分JavaScript都必须重写以适应Angular的模式, 这是一项值得的努力.

WebRTC Meets CSS

我们在CSS中遇到了类似的复杂性问题:模块化不是很正确, we had overlapping styles, etc. 说我们的代码库比许多其他系统庞大是不公平的, 但作为一个在创业公司工作的小团队:1)时间是必不可少的,2)组织是关键.

降低CSS复杂性的关键是使用 Sass and Compass.

第一次使用Sass时,我不是很满意. 但今天,我无法想象没有它的生活. In short, Sass是一种CSS扩展语言 它允许您用Sass语法编写样式表并将其编译为CSS.

Sass大量壮观的功能: variables, control directives, SassScript in general, and more. 但真正打动我的是萨斯,真正对昂德洛产生巨大影响的是萨斯 nested rules.

这些最好用例子来说明. 没有Sass,我可能会有一些CSS代码看起来像这样:

.container_div {
  float: left;
  height: 10px;
  width: 20px;
}

.container_div a {
  margin-left: 15px;
}

但对于Sass,这可以简化为:

.container_div
  float: left
  height: 10px
  width: 20px
  a
    margin-left: 15px

在这个简单的示例中,我只保存了几行代码. 但是想象一下,如果我有一些行业级的CSS代码,可以用Sass表示为:

.admin-section-menu
  width: 270px
  float: left
  margin-right: 8px
  padding-top: 30px
  ul
    padding-right: 10px
    li
      width: 230px
    	a
        float: left
        text-align: right
        letter-spacing: 1px
        font-size: 20px
        color: #666
        width: 220px
        margin-bottom: 20px
    &.active
      a
        width: 230px
        color: #52672d
        &:after
          content: '\25b8'
          display: inline
          position: relative
          left: 10px

Compass 是一个CSS创作框架,建立在Sass之上,并真正帮助我们完成界面设计. 我们用指南针来制作 sprites—there’s a great tutorial here, if you’re interested.

使用Compass,我们可以加快创建复杂按钮的速度. 这就像把按钮的图像状态放在一个文件夹里一样简单, 这时Compass就会生成一个精灵来包含它们.

中的所有文件 administration_buttons 文件夹,并把它们放到一个Sprite文件中.

@ import”administration_buttons / *.png"
@include all-administration_buttons-sprites

.add-user-button
  width : 37px
  height : 37px
  cursor : pointer
  float: right
  @include administration_buttons-sprite (add_user)

  &:hover
    @include administration_buttons-sprite (add_user_rollover)

Through the @include administration_buttons-sprite (add_user) command, I add the file add_user.png 作为背景图像 add-user-button class.

使用Compass,我所要做的就是把一些图片放到一个文件夹里.

如果没有指南针,我将不得不:

  1. 把所有的图片放在一个文件里.
  2. 获取每个图像的所有坐标并将它们放到类中.

对于像我这样的开发者来说 Photoshop-savvy,这是一个巨大的节省时间. 在这个阶段,时间是至关重要的.

WebRTC Meets Rails

经过几个月的JavaScript和CSS开发,我们最终转向了Ruby on Rails后端.

Rails模式非常适合保持项目的简单性,因为它与MVC结构有非常清晰的分离. 如果您的系统开始增长,单独使用Rails模式可能是不够的. Instead, 你需要思考新的东西, 解决问题的高级方法——新的抽象方法.

我们都学习过代码模式、意识形态、教程、指南等等. 我们都知道把逻辑分成类,把类分成函数等等. But rarely are we taught solutions. 我从来没有读过关于它的书,也从来没有看过关于它的课程.

在使用Rails一段时间后, 我开始意识到问题不在于代码, 问题就是解决客户问题的解决方案.

回到webbrtc的Ondello:作为一个具体的例子, 我们有一个建立在Rails之上的非常简单的邮件系统. 有一段时间,这对我们很有效. 但最终,我们需要为每个客户提供一种特殊的电子邮件. As time went on, 电子邮件之间的变化开始变得越来越大——最后, 每个客户需要的电子邮件完全不同.

如果您的系统开始增长,单独使用Rails模式可能是不够的. Instead, 你需要思考新的东西, 解决问题的高级方法——新的抽象方法.

随着代码库的增长,我开始意识到这一点, 这种功能将对我的整个WebRTC框架和邮件系统产生巨大的影响. 这时我们决定为邮件系统创建一个单独的项目, 负责处理各类信息. 主项目只会通过 REST)一些参数和一个客户端标识符. 然后,邮件系统将负责收集和发送电子邮件.

This approach, 将项目分成不同的项目, 对开发昂代洛有帮助吗. 它使主项目保持简单,没有不必要的责任.

这种解决问题的方法就是我所说的 solutions approach. 我发现它对于开发复杂的应用程序至关重要.

Conclusion

不管你是不是Ruby, Java, or PHP developer, 当涉及到web开发时, 现在有很多框架和技术, 您可以或应该使用许多不同的工具来使您的系统工作, that in my eyes, it’s hard to see anyone 作为一个“Ruby”程序员或“Java”程序员.

当涉及到大系统时, 您需要设计精心设计的解决方案来满足客户的需求,而这些解决方案并不总是适合您最喜欢的技术,甚至不适合您所熟悉的技术. 我开发《欧博体育app下载》的共同主题是,我必须灵活和敏捷, 使用最适合的技术,在任何给定的时刻,不管我的喜好.

In developing Ondello, I remembered that, above all, we must be engineers, 用最好的工具解决问题, 以高效的方式完成工作, scalable, and practical manner.

聘请Toptal这方面的专家.
Hire Now
Alexandre Mondaini Calvão

Alexandre Mondaini Calvão

Verified Expert in Engineering
15 Years of Experience

里约热内卢-巴西里约热内卢州

2012年10月5日成为会员

About the author

Alexandre是Ruby on Rails开发专家,他在Java和各种前端技术方面也很有经验.

作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.

世界级的文章,每周发一次.

输入您的电子邮件,即表示您同意我们的 privacy policy.

世界级的文章,每周发一次.

输入您的电子邮件,即表示您同意我们的 privacy policy.

Toptal Developers

Join the Toptal® community.