NESHouse 背后的那些技术选型
NESHouse 作为一个黑客松项目，相比于其他正式运行的项目，可能生命周期更短，也不会走入正式运营的阶段。不过，在我个人看来，这个项目的选型、设计等，还是有一些有意思的点，值得和大家分享。
NESHouse
NESHouse 作为一个黑客松项目，相比于其他正式运行的项目，可能生命周期更短，也不会走入正式运营的阶段。不过，在我个人看来，这个项目的选型、设计等，还是有一些有意思的点，值得和大家分享。
NESHouse 作为一个黑客松项目，相比于其他正式运行的项目，可能生命周期更短，也不会走入正式运营的阶段。不过，在我个人看来，这个项目的选型、设计等，还是有一些有意思的点，值得和大家分享。


### 1、 黑客松，要的就是快！


这几天前几篇文章发出去后，不断有一些开发者留言评论：**这个项目使用的都是别人的服务，你的价值是什么？**


NESHouse 作为一个黑客松项目，目的是在有限的时间内，从 0 到 1 将需求实现，在这个过程中，开发者需要去仔细评估自己所拥有的资源和要达成的目标，让资源和目标匹配，才能很好的完成自己的开发工作，达成自己本次黑客松的目标。


![](/data/attachment/album/202102/09/140214b07mfbc7jd47xmb4.jpg)


作为一个 Go 后端开发者，在这个项目中，我使用的是 LeanCloud 提供的云服务，而不是使用 gin 自己写一个 http 服务器，似乎不合常理，没有使用自己最熟悉的技术方案。但如果将资源和需求结合起来看，就会发现这个选择是很正常的。gin 固然熟悉，但我不熟悉的是前端，如果我将一部分时间安排在了后端的研发上，必然挤压我在前端开发的时间。


所以在 NEShouse 项目中，**我选择了我比较熟悉，且开发时间周期最短的 Serverless 云服务 —— LeanClod 来完成我的后端工作量，这样我可以几乎不用在后端上花费时间和精力来完成工作**。在音频服务上选择使用声网，而不是自己实现一套，原因也一致，**我的预期是在 72 小时内完成这个项目的研发，而不是自己打造一套完整的实时音频系统**。所以必然会选择更加好用，更加现成的解决方案，来简化我自己的工作。


此外，在这个项目中，有一个比较适合进行工作量评估的事情，便是我在项目中使用到了 LeanCloud 的 LiveQuery 的能力。LiveQuery 提供了实时数据同步的能力，使用 WebSocket 也可以实现相同的功能，不过，如何能又好又快，同时在 WebSocket 服务器上完成各种鉴权和扩展能力，是一个麻烦的事情。你可以用这个非常简单的功能，来评估假设你自己来完成所有的功能所需要耗费的时间。这样就可以理解为什么在这个项目中，我选择 LeanCloud 来完成工作。


### 2、浏览器兼容，你是真的坑！


在 NESHouse 的开发中，其实并没有花费太多的时间，倒是中间因为我回老家，花了不少时间在路上。实际上，在整个项目中，最为费心的，是各种浏览器之间的兼容问题。


![](/data/attachment/album/202102/09/140215dkqthl0kpfkd22om.png)


基于浏览器的 NESHouse 和其他基于系统原生 API 的音频应用相比，一个很大的问题在于浏览器在处理音频设备上的不同。NESHouse 使用的音频接口是基于浏览器封装后一层的 API，而这个 API 处于考虑保护用户的考虑，在某些特定的场景下，会要求你先产生一些操作才能触发音频播放，所以针对不同的浏览器，你需要编写不同的适配代码，这些代码最终就会让你的代码变得又臭又长，存在大量的冗余代码。


比如说，在微信浏览器中，默认情况下你是无法听到 WebRTC 传回的音频的，需要用户在页面上进行点击，才能进行播放。


NESHouse 在实现这部分的逻辑时，采用的是判断如果用户使用的是微信浏览器，则会显示一个用户授权页面，让用户主动去点击，来完成音频播放的能力。


如果你希望以其他的方式来解决这个问题，那也可以参考 Agora 文档中的相关说明，来实现这部分能力：<https://docs.agora.io/cn/Voice/autoplay_policy_web?platform=Web>


### 3、Alpine.js，真香


作为一个后端开发者，对于前端的几大框架，也仅仅局限在可以用，可以写出我想要的功能的应用。但在具体的实现的时候，由于一些原因，我没有使用 Vue/React/Angular 之类的应用，再加上希望在黑客松中使用一些新的技术，于是我使用了 Alpine.js。


什么是 Alpine.js？Alpine.js 是一个在基础的 DOM 上实现了类似 Vue/React 的双向绑定的一个框架，使用 Alpine.js 和 Vue/React 的一个很大的不同点就在于，他可以让你在现有的 HTML 中非常轻松的实现双向绑定，而不需要重写整个代码。


举个例子来说，假设你想要在 Vue/React 中实现双向绑定，你需要将你的代码放在模板中或者转换为 JSX 来获取相应的双向绑定的能力。但在 Alpine.js 中，你需要做的仅仅是在你需要绑定的地方加入 `x-model=xxx` 来实现绑定，十分简单。


不仅如此，Alpine 也实现了大部分 Vue/React 之类应用实现的功能，比如 `x-for`、`x-on`、`x-if` 等常用的命令，在实际写逻辑的时候，我大量的应用了这些逻辑来完成我自己的工作，十分方便。


![](/data/attachment/album/202102/09/140216gocq9hfdowulqzh2.png)


在 NESHouse 中，随处可见 Alpine.js 的应用：


![](/data/attachment/album/202102/09/140217h1u7pszzvbookq0k.png)


Alpine.js 可以很轻松让一个不熟悉 Webpack 等前端构建工具的后端工程师，在自己的应用中实现双向绑定。对于后端工程师来说，这个工具你们不可错过。


### 总结


NESHouse 的技术栈相比于很多复杂的应用来说，十分的简单，仅仅是 Leancloud + Agora 就可以完成几乎所有功能，但我相信，这样的技术架构选型，对于一些不需要那么大计算量、没有那么高业务负载的项目而言，是有帮助的。**就算你有屠龙技，又何需在杀鸡之时用它呢？**

