记录一哈自建的博客弹幕系统
📝2827 个字
 | ⌛要看完怎么也得7分钟吧
链接汇总
Durable Objects文档:https://developers.cloudflare.com/durable-objects/
PartyKit官网:https://www.partykit.io/
PartySocket API文档:https://docs.partykit.io/reference/partysocket-api
PartyServer API文档:https://github.com/cloudflare/partykit/tree/main/packages/partyserver
整活起因:
- 其实很早以前,刚刚搭建这个小博客的时候,就有想过整个在线聊天室的功能。当初也在网上稍微搜罗了一下,确实找到了很多类似功能的插件。接入的方式也非常简单,基本只要嵌入一行代码即可完成。
- 但这种插件,一般都是作为客服平台进行接入的,所以不管是界面样式还是使用方式,都和本人博客的风格不是很搭。同时又因为,作为一个聊天室,用第三方的插件,总感觉有一种底裤被扒光的背德感🤡。所以还是想着,能不能直接自己写代码,在网页上整一个类似功能。
- 但是因为本科博客是基于cloudflare的全静态网页,所以不存在真正的服务器作为支持。因此像聊天室这种,需要相互建立长链接的功能,不管是用cloudflare的page还是worker都无法实现。
- 但强如cloudflare肯定是有专门支持长链接的解决方案的,不过就是需要使用付费计划里的Durable Objects功能。而咱这种小博客,用的肯定只会是免费计划,所以久而久之,这个功能就被我忘在了某个犄角旮旯的角落里了。
- 诶,但是就是这么巧,最近又被我给挖出来了。主要也是因为cloudflare更新的速度非常快,所以平时有事没事也会关注着新功能变化。所以最近在翻新功能的时候,碰巧发现Durable Objects居然可以免费使用了!!而且免费额度,同样也非常的肯给,至少就咱这小网站肯定是用不完😆。

- 所以趁着这个机会,是时候搭建一个只属于咱自己的聊天室了,正好还可以熟悉一下cloudflare的新技术,可谓是一举两得🌈!
啥是Durable Objects:
- 总之先摊牌,我自己不是那种喜欢啃文档的类型。所以要我从头开始把官方说明文档读一遍,那除非是鸣人开嘴遁——不服不行🤪。但是吧,作为一个技术宅,还是得有基本的代码操守的,好歹也要先花个10分钟大致了解一下,到底啥是Durable Objects。
- 众所周知,cloudflare中的worker,是一种无状态服务器。简单来说就是每次请求,都可能会被cloudflare,分配到实际不同物理位置的机器上进行处理。同时在执行完成后即刻销毁,不会保留任何内存数据。因此无法处理像聊天室这种长交互的场景,毕竟服务器也不造,除了你还有哪些其他的客户端,在跟你访问同一个网页。当然也不是完全没有办法知道,只要把内存数据存到统一的存储空间,需要的时候再读再写就行。但这种io消耗对服务器来说,尤其是对咱这种使用免费计划的用户来说,是非常致命的🙁。
- 而Durable Objects这个名字起的似乎很响亮的样子,其实实际上还是个worker。但最重要的变化,就是这个worker是有状态的😮!这就意味着所有的请求,实际都会分配到相同的一个实例上,所以也就能支持,同时和多个客户端建立长链接。但也不能让该实例一直处于工作状态,不然就算免费额度给的再怎么豪爽,也经不起24小时不间断的消耗。所以Durable Objects自己也有生命周期,只会在需要的时候自动激活运行,随后自动休眠。同时在cloudflare的设计中,每个Durable Objects都会自动分配一份独立的存储空间,因此只需要保证每次休眠前完成所有数据保存,即可在下次唤醒时,继承上次的工作数据。
啥是PartyKit:
- 那既然知道了啥是Durable Objects,那接下来的流程,正常来说肯定是看怎么用Durable Objects咯。诶嘿,但我偏不🤪。作为一个实践派,下一步自然是直接打开官方样例,没有什么比看代码来的更实际了。结果吧,这不看不知道,一看更加不得了,我明明是来学习Durable Objects的,咋凭空冒出来了一个PartyKit,这又是谁的部将(曹操脸)?于是秉承着来都来了的原则,又花了10分钟,大致了解了一下PartyKit。
- 简单来说,PartyKit就是一个励志于发挥Durable Objects所有作用的组件,通过封装Durable Objects的接口,给用户提供包含客户端和服务器库的统一解决方案。也就是说,其实本质上还是Durable Objects,但为了使用起来更加便捷,进一步统一封装了接口。然后估计是因为确实做的不错,去年cloudflare顺便就把他给收编了,因此现在最新的样例,很多直接就是使用PartyKit进行开发,而不是原生的Durable Objects。
- 后来也简单实际上手体验了一下,确实要比原生的Durable Objects,使用起来更加统一一些。正好也非常适合咱们这次的使用场景,所以后续就决定,直接基于PartyKit进行开发了😎。
开始整活:
- 首先根据前车之鉴,如果是直接在网站嵌入一个聊天室组件,割裂感会非常强,而且对本网站的风格破坏性有点大,俺并不是非常喜欢。所以既然是自己整,那一定要整点接地气的。那有什么设计,能在不影响正常网页浏览的前提下,又能实现交流对话的功能呢?诶,对咯,那就是弹幕系统!所以本次整活的目标已经非常明确了,就是用PartyKit,给网站加个实时的弹幕系统💪。
- 首先是服务器部分,作为一个弹幕系统,服务器的主要使命,其实就是作为信息枢纽,把大伙发送的消息,实时的转发给其他在线的小伙伴。然后因为是基于cloudflare的worker系统进行开发,所以使用的PartyKit服务器库和官方原生的还有点区别。不过好在cloudflare官方提供了单独的api文档和源码,真要遇到问题了也可以直接看源码找解决方案。
- 简单来说,就是官方提供了一个Server类,这个类其实就是基于Durable Objects封装的。然后咱们需要做的,就是继承这个类,根据需要实现对应的初始化、消息收发、数据存储的功能。初始化基本没啥特别的,就是PartyKit原生的一些参数配置。对咱们弹幕系统来说,重点还是在消息收发上。不过贴心的cloudflare,已经帮咱封装好了所有必要的接口,包括消息的接收、发送、广播等,基本上需要咱们处理的,无非就只剩下数据结构的设计和存储。数据存储主要使用的,还是官方推荐的sql,虽然写sql有点麻烦,但好在量不大,而且再不济也可以让ai代工😆。
- 建立好了Server类,基本就完成了90%的功能,剩下的需要处理的就是worker的路由转发。结果没想到的是,哪怕是这最后的10%,cloudflare也不需要咱们自己写。官方直接提供了一个routePartykitRequest接口,只需要在fetch的时候,调用对应接口,即可帮你处理好所有的和Server类之间的路由分发。得,看样子这块也没啥需要咱们的地方😆。
- 搭建完服务器,剩下的就是客户端的接入了。到这里其实就跟Durable Objects没啥关系了,需要处理的无非就是和服务器的消息收发。PartyKit官方也为此提供了一个,专门给客户端使用的partysocket库,因此咱们直接按照官方文档接入即可。
- 接入方式尤其简单,官方提供的库中有一个PartySocket类。使用的时候只需要构造一个该类的对象,并且完成初始化,剩下的就是消息收发的纯业务逻辑了。
- 因为本次制作的弹幕系统只是个点缀,不想影响阅读喧宾夺主。所以客户端目前只打算做一个,弹幕从右往左飘过的简单效果即可,等以后啥时候有新的灵感了,想加新功能了再说😆。
- 但要想有弹幕飘过去,也得有地方让大伙发弹幕才行。可是如果是直接把输入框嵌入到网页里面,就又变回原来聊天室那种突兀的表现形式了。所以还需要加个入口,能够隐藏弹幕的输入框,让大伙只在需要的时候点开发送即可。
- 诶,正好前段时间,还偷摸着和ai合(tou)作(lang)了一下,整了一个类似sakana立牌那样,充满弹性的装饰组件。只不过不一样的地方是,这个组件我想做成挂饰的样式,正好挂在导航栏下面。但后来做完以后发现,好像没啥东西能用到这个挂牌🤣,所以就有点生不逢时,先搁置在一旁了。
- 而现在这不机会来了嘛,一个看着平平无奇的挂饰,点开居然是个弹幕发送系统,想想就很酷😎。而挂牌本身,正好还可以用来显示在线人数,简直就是为此而生的🎉。同时,为了让挂饰更有活力一点,顺便还整了一个小功能,如果在线人数发生变化了,就让这个挂饰跳动一下。这样一来既不喧宾夺主,也不至于太不起眼😆。

总结:
- 因为考虑到大伙不一定都喜欢纯聊代码,所以本文主要篇幅还是以记录心路历程为主,如果对具体实现感兴趣,或者某块还存疑的话,可以看看官方的样例,基本差不了太多内容。当然也可以直接评论提问,我如果看到了也会回复。
- 这次整活主要起因还是因为Durable Objects拥有了免费额度,再加上本来也想给网站加点不一样的功能上去,所以阴差阳错的整了份弹幕系统。同时又得益于PartyKit组件的强大,帮咱们省去了大量的中间逻辑。之后如果还有想整一些大活,比如多人游戏啥的,说不定也可以考虑用PartyKit整个。嘛,虽然大多数情况还是在挖坑不填吧😆。