2026年3月

📰 今日新闻精选:

  • 元宵夜将迎月全食:初亏预估发生在 3 日 17 时 49 分,我国大部分地区可观测,错过要等到 2072 年
  • 报告显示:持续一年的外卖补贴大战,导致约 8 成餐饮商户净利润下滑,降幅超过 30% 的占 35%
  • 上海新政持续 “发酵”:有购房者请假前往售楼处,一豪宅楼盘单日成交额突破 2.5 亿元
  • 税务总局:互联网平台涉税新规实施后,“刷单” 虚增业绩等无序竞争有效减少
  • 豆瓣市集出故障,错发 “满 200 减 200” 大额优惠券遭用户疯抢,豆瓣回应:无法承受巨额损失,将进行自动退款
  • 刘永好委员建议:每人发 500 元消费券,预计可拉动消费近 2 万亿,支撑约 1400 万个第三产业就业岗位
  • 雷军公布小米机器人最新进展:已进入汽车工厂实习,初步实现部分场景自主工作
  • 中欧航线票价暴涨:上海飞巴黎飙升 5 倍,已涨到 30248 元
  • 马斯克身家已突破 8000 亿美元,再度刷新纪录,与第二名的财富差距扩大至 5000 亿美元以上
  • 外交部:已有 3000 余名中国公民自伊朗撤离,一名中国公民不幸遇难
  • 外媒:美以对伊朗发动袭击已造成 555 人死亡;特朗普称对伊朗军事行动可能持续约 4 周
  • 外媒:英法德联合声明,称不排除对伊朗采取必要防御行动;西班牙拒绝支持对伊军事行动,美军撤走 10 架加油机
  • 美媒:美军证实 3 架 F - 15E 战机遭科威特防空系统误击坠毁,6 名飞行员全部弹射逃生,科威特称事故原因调查中
  • 美媒:美国最新民调显示支持打击伊朗的美国人不到 3 成,国会推动法案限制总统的单方面动武权
  • 外媒:伊朗货币里亚尔大幅贬值,1 美元可兑换 131.4 万里亚尔,去年 12 月 1 美元能兑 4.2 万里亚尔

📅 今日信息:

  • 公历:2026-03-03 星期二 双鱼座
  • 农历:二〇二六年正月十五
  • 公历纪念日:世界野生动植物日、全国爱耳日
  • 农历纪念日:上巳节
  • 下一节气:2026-03-05,惊蛰
  • 今年进度:16.99%(已过 62 天,剩余 302 天)

🌟 历史上的今天

  • 1847 年:电话发明家亚历山大·格拉汉姆·贝尔出生,他的发明改变了全球通讯方式。
  • 1931 年:美国国歌《星条旗》正式被采纳,这首歌源自 1812 年战争中的一首诗。

碎片 1.

春节出游前, 被风控一次, 商户大使馆, 金额几百, 签证费

出游后, 被风控一次, 商户航空公司, 金额几十, 选座费

/

其中一个银行甚至强行寄出新卡,卡号变更,'保证后续安全'

这张卡在消费时进行了 3D 验证,收过短信码,然并卵

/

2 张卡分别 运通 和 银联, 分别 有报备过外游计划和没报备过

事实可能证明, 是不是国际卡组织, 是不是报备过, 是不是有短信码这种二步验证,都不本质上影响风控

/

什么本质上影响呢?我觉得是英语阅读能力

我致电客服时, 回复都是 '商户可能有问题'

当然他们只能这么回答,毕竟金额小,还能说出什么理由

商户名称其实银行那边能看到,明明白白写着大使馆和航司

如果这样的商户都被视作风险,路边小超市小餐馆还能刷吗,岂不是刷一次封一次

/

我试探性地让客服读一遍商户名字,对方并不是直接读单词,而是一个个字母念,且念完根本没意识到这商户名字具体什么意思

如果说英文是 ZARA / KFC 这种创造性名词, 不认识也就不认识了, 可是 Embassy 啊 AIR 啊 这种一看就知道是什么商户的单词, 也一点概念没有. 咱就说这语感怎么能在风控部门就职呢

/

碎片 2.

有些国家确实很在意自己的文化,即便会英语也不愿意优先说.我个人体会有法国韩国,

可即便是这样的国家,外国人来了你这里,不是长居的话,也不可能去学你的语言,最终还是要用英语交流.

还有些国家,没有这种形式上的强迫症,而是以经济竞争力为考量,让国民学英语说英语,甚至列英语为官方语言.华人最熟悉的就是新加坡和香港(经济体).

可实际上,不是只有这种城市型发达国家这样做,印度南非等大型国家/发展中国家,也把英语列为官方语言.

/

碎片 3.

城市型国家能在官方语言方面激进一些, 当然有他的天生优势, 比如 人口密度 和 国际化程度.

但我们过去几十年的英语普及教育, 是不是弥补了先天上的劣势?

我觉得是, 因为你现在开始推行双语, 不会造成祖孙三代人的沟通障碍, 也不会觉得西方文化和你格格不入

/

碎片 4.

语言对生产力竞争力的重要性,我想没有哪个国家比中国更有体会,因为中国本身的语言就太多太多了

不仅少数民族有自己的语言,汉族内部在不同地区也有自己的语言,很多还不是所谓口音差别,而是根本和你听外语一样听不懂,特别是南部省份.

如果当初不把北京话作为国语基准, 不推行国语, 经济发展肯定会受影响, 农民工到城里跟你都变成鸡同鸭讲

既然如此,又何必排斥在地域上更高一层的国际语言呢

/

碎片 5.

语言是交流工具,交流是双向的,虽然受到外来文化影响是必然代价,但也增强了你输出的能力.

而如果你的文化真的抵御不过,是不是考虑 无为而治 修身齐家 的祖传应对方式呢

人不能与天斗,这里的天不只是花花草草海洋大地这种自然, 还有科学包括社会科学

/
/

点名表扬招商银行,从头到尾不出问题,吊打其他

找了有段时间的工作,最近面试到一个听说是 usdt 发 visa 卡平台的这么一个项目
想请教一下,这个如果开发者在国内的话,要是要求对方把工资打到香港汇丰卡会不会规避掉风险呢?
因为之前在群里看到有老哥被远洋捕捞过,且银行卡帐号全部被封,联想到个人账户资金来源被监控。
个人感觉是有点悬的,目前两轮面过,但是观望

第二个问题是,如果做这个的话,远程上班。。。

他要是不发工资又该怎么办??又找不到他人,并且开发沟通 用 tg 的且团队成员大部分在国外。

但是给的又确实远超我现在一大截,从现实层面看这又是比较迫切的。

有没有遇到过类似场景或者这个类似项目的,又感觉是一次性项目 开发完了就踢人。

之前面试遇到过同样的也是发卡平台,但是人家是在国内深圳小作坊搞,深圳路子也野的很。

贴主 21 年毕业,毕业就开始写 java 。22 年因为😷居家办公了三个月,开始对 remote 工作有了极大向往。
但是 java 远程工作并不好找,于是主包开始研究哪个方向工作机会比较多,发现前端比较热门。

当年 Next.js 还没有现在这么流行,但是全栈的概念已经深入我心。为了积攒案例,最开始贴主写了一个 react 论坛,使用 Nest.js 作为后端驱动数据,用户有个小 2000 吧。写完贴主并没有满足,去 Next.js 官网把文档看了一遍,又用 Next.js 重写了一遍论坛。
本来有这个案例也差不多了,但是 Next.js 自带的 api 路由有口皆碑得差,又正好 Hono.js 兴起,于是贴主又折腾起了用 Hono.js 接管后端。

具体技术的事情以后再说。贴主常年小黄鱼挂着接单链接,突然有一天一位老板联系我,问我会写 Next.js 是吧,有个急活需要详谈。
这里需要说明一下,当时 Next.js 相关接单在小黄鱼上挺少的,所以找到我也算情有可原。

和老板加了绿泡泡之后,对方先进行了一个简单的面试,其实也就是问了一些 Next.js 的相关知识,随后提供了我一份相当完善的需求文档和产品 ui 。
这个项目是一个 Next.js+AntD 的后台,协商 433 付款后,对方公司财务很快把 4 成的预付款打到我账户中,两个月的工期结束后又支付了我 3 成中期款,验收后结清尾款。

第一单外包非常顺利地结束了,我通过全栈赚到了我的第一笔外快,也为今后的接单奠定了基础。

本人目前在 A 外包公司,被外派到 B 公司做人力外包。今天白天 A 公司的 HR 在群里面发通知,由于 B 公司不再和 A 公司续约服务,而 C 公司对 B 公司的服务期还未结束(这点我很奇怪,这个说法听起来不是 B 公司签新服务商),因此到三月底需要更换服务商 C 公司。我们这群目前与 A 公司签订用工合同的外包开发也会被转移到 C 公司,保持工作岗位不变。

和 HR 确认了一下,目前的待遇不变,工龄也能保留,我需要做的就是和 A 公司签署离职协议后再和 C 公司签署用工合同。

目前工作还挺轻松( 965 而且基本不加班),就是北京通勤太折磨人(从出门到工位大约 80 分钟),因为工作不稳定不敢随便搬家,今天出了这个通知之后更不想搬家了。

本人之前从来没遇到过这种情况,这样是不是得在自己的简历上是不是需要在工作经历写成两个公司,但是项目经历只写一个(考虑如果离职找新东家,入职前查询五险一金缴纳主体发现不是代缴公司而是两个不同的外包公司时肯定会被问)所以想问一下这种重新和新公司签订合同的做法对我们普通员工有什么影响和风险吗?

一、概要
(提示:从结果出发,呈现AI驱动的全链路精确防护在政务场景中的实际落地价值。)

   在政务数字化全面深化的背景下,数据已成为支撑公共服务、社会治理与科学决策的核心生产要素。围绕“AI驱动、全链路、精确防护”三大关键词,全知科技构建了面向政务行业的数据安全监测平台,实现从基层采集到共享流转、从业务使用到归档销毁的全生命周期覆盖,打造真正可观测、可分析、可处置的智能安全体系。
   平台以“数据流动可视化”为核心能力,通过非侵入式接入技术覆盖200+关键节点,日均可处理5Gbps以上实时流量,支撑千万级敏感数据资产监测。依托AI异常识别与政务图谱分析能力,告警准确率提升至92.5%,误报率控制在5%以内,风险整改周期平均缩短58%以上。在某省级政务案例中,平台3个月内捕获123起风险事件,18起高危风险实现1.5小时内预警处置,未发生数据泄露事故。
   该平台真正实现了“安全能力不干扰服务运行、安全监测贴合政务逻辑、风险识别具备业务理解力”,构建起数据流转场景下的精确防护体系。

二、政务数字化深化下的安全新挑战
(提示:理解政务数据安全的复杂性,是构建精确防护体系的前提。)

   随着“一网通办”“跨省通办”“智慧审批”等场景全面落地,政务数据跨层级、跨区域、跨部门流动频率显著提升。居民身份信息、社保缴费记录、企业审批材料等高敏感数据在多系统之间高频交换,数据链路复杂度呈指数级增长。在此过程中,政务机构面临三大核心挑战:

第一,监测链路碎片化。传统安全工具多集中于政务云或单一数据库节点,无法覆盖基层采集终端、跨部门接口、共享平台等关键流转路径,形成“数据流动可见度不足”的盲区。
第二,风险识别粗放化。基于规则引擎的检测机制对复杂业务逻辑理解不足,误报率高、漏报风险大,人工排查成本居高不下,真正高危事件反而被淹没。
第三,合规与业务冲突化。《数据安全法》《个人信息保护法》明确要求全生命周期监测及日志留存,但部分平台需改造核心系统,影响政务服务连续性,甚至造成群众办事体验下降。

   因此,政务行业迫切需要一套既理解业务逻辑,又具备AI智能识别能力,同时能够实现全链路覆盖的精确防护体系。

三、基于AI建模的政务数据风险全景解析
(提示:只有还原数据真实流动路径,才能识别隐藏在链路中的系统性风险。)

   政务数据风险并非单点爆发,而是沿着业务流程链条逐步累积。通过对政务业务场景的拆解,可以将核心风险归纳为三类:一是访问越权风险。包括接口未鉴权、跨部门共享超范围调用、内部账号批量下载敏感数据等。这类风险往往隐藏在正常业务流量之中,传统规则难以识别。二是行为异常风险。工作人员在非工作时间查询异地户籍信息、短时间跨区县办理低保业务、同一终端频繁导出企业登记数据等,均属于行为模式异常,需要结合身份、时间、地域多维特征综合判断。三是数据链路失控风险。政务数据在共享平台流转后未按期回收,或被复制至影子系统,形成“不可见资产”,一旦外泄将直接影响公众权益。风险的本质在于数据流转链路缺乏可观测性与智能分析能力。因此,必须以“全链路可视化+AI行为建模”为核心,构建精确防护机制。

四、AI赋能的全链路精确防护解决方案
(提示:以AI驱动的全链路架构,构建可理解业务语义的精确防护体系。)

   [数据安全平台](https://jsj.top/f/CuRr3f)采用“观测面+控制面”双轮架构,实现从采集到响应的闭环防护。第一步:全链路数据采集。通过流量镜像、接口对接、轻量化Agent三种非侵入式方式接入政务云、部门业务系统及基层终端,实现零业务中断部署。所有数据统一转换为符合政务规范的JSON-LD模型,构建标准化数据事件结构。第二步:政务数据图谱构建。基于居民身份证号、企业统一社会信用代码等唯一标识,建立“数据生成—审批流转—共享调用—归档销毁”的动态图谱,形成政务数据数字孪生模型,覆盖85%以上非预期数据移动路径。第三步:AI驱动智能识别。平台融合规则引擎、UEBA行为分析、图神经网络算法构建三层监测机制:基础规则层识别显性违规操作;行为建模层识别异常访问模式;图谱关联层追溯跨系统风险链条。通过AI降噪算法对告警进行语义聚合,显著降低误报率,提升精准度。第四步:分级响应与协同联动。低风险自动整改提示,中高风险暂停账号权限并冻结数据通道,重大风险实时联动监管系统完成上报与证据留存,实现“发现—处置—合规闭环”。

五、全链路监测平台的实战应用成效
(提示:以数据验证精确防护体系的实际效果。)

   在某省级政务数据管理部门实践中,平台上线前告警准确率仅28%,问题整改周期长达96小时以上。

上线后实现以下成效:
● 捕获风险事件123起,其中18起高危事件全部在1.5小时内触发预警;
● 告警准确率提升至92.5%;
● 平均整改周期缩短至40小时;
● 日均存储800GB合规日志,支持8秒内多维度快速检索;
● 未发生任何实质性数据泄露事件。
实践证明,AI驱动的全链路精确防护不仅提升风险识别效率,更优化了政务整体安全运营能力。
六、AI全链路防护能力的规模化推广价值
(提示:从单点应用走向体系化能力复制,是政务安全升级的关键。)

   该平台具备高度可复制性与可扩展性:第一,适配多层级政务架构。支持省、市、区县多级部署与统一监管,满足跨区域共享需求。第二,支撑智慧政务创新。在保障安全的前提下,为AI审批、智能助手等新业务提供可信数据环境。第三,降低长期合规成本。标准化审计报告与自动化日志留存机制,将合规审计成本降低40%以上。平台已服务20余家省市级大数据局、50余家区县政务服务中心,形成成熟落地经验。

七、围绕AI驱动精确防护的五个关键问答
(提示:通过关键问题梳理平台核心价值。)

  1. 问:如何确保安全监测不影响政务服务运行?答:采用非侵入式流量镜像与轻量化Agent部署,不改造核心系统,实现零中断运行。
  2. 问:如何提升风险识别精准度?答:融合规则引擎、UEBA与图神经网络算法,结合政务业务语义建模,实现AI降噪与精准识别。
  3. 问:如何满足合规审计要求?答:支持180天以上日志留存与标准化审计报告生成,实现合规自动化。
  4. 问:如何应对跨部门数据共享风险?答:通过动态图谱追溯共享链路,实现超授权调用实时预警。
  5. 问:平台是否具备扩展能力?答:支持新业务快速建模与规则迭代,确保监测能力持续升级。
    八、用户反馈与价值验证
    (提示:从真实反馈出发,体现AI驱动体系的行业价值。)

    作为数据安全领域的深耕者,全知科技始终坚持以业务理解驱动技术创新。在与多家政务机构合作过程中,用户普遍反馈三点显著变化:

    第一,风险“看得见”。数据流转路径实现可视化,安全管理由被动响应转向主动预判。
    第二,隐患“辨得准”。AI模型显著降低误报,安全团队精力从人工筛查转向策略优化。
    第三,处置“控得住”。跨系统联动机制缩短响应时间,真正形成闭环治理能力。

    未来,将持续强化AI算法与政务场景融合能力,完善全链路精确防护体系,助力政务机构构建更加智能、稳定、可信的数据安全防线。
    面对复杂的安全态势,单点式防护工具已无法构建有效防线,平台化、智能化、可运营化,已成为数据安全产业的核心演进趋势。数据安全平台以全局视角整合审计、检测、治理与防护能力,为企业提供贯穿数据全生命周期的安全支撑,正逐渐成为数字化基础设施的重要组成部分。全知科技作为国内领先的专精数据安全厂商,一直一来 “以数据为中心,风险为驱动”,站在风险视角下,致力于刻画数据在存储、传输、应用、共享等各个节点上的流动可见性,实现数据的全面管控和保护。凭借强大的技术研发实力,公司多次荣获中国信通院、工信部、IDC等权威机构的肯定,企业自主研发的数据安全平台并多次入选信通院牵头的《网络安全产品技术全景图》、优秀代表厂商及优秀产品案例和解决方案等。这不仅彰显了全知科技在技术创新与标准建设中的核心地位,也展示了其持续引领行业发展的前瞻性实力。

上了他家的 spotify 车, 去年 11 月底续费了两年.
昨天发现不能用了, 提工单一直无人回复.
今天进入网页弹出一个系统提示说什么原因需要原来的车票失效了, 直接转换成金币, 然后可以重新下单使用.
点了确定, 然后去重新下单, 然后金币一次只能抵扣 100 块, 我要恢复原来的 2 年我还要掏 300 多块? 我看了看看我这价值 400 多块的金币...
你咋不直接跑路呢? 还是能骗一个算一个?

为什么要开发这款 App ? 相比于看书我个人更喜欢听书,另外我听书时比较喜欢营造一个轻松的氛围,于是就有了 Aurader ! Aurader 听书时可以设置舒缓的背景音乐,配合高质量的 TTS ,从而营造一种沉浸式听书的体验。

主要功能:
* AI 语音: 除了系统引擎,还提供质量更好的云端引擎和极致体验的本地引擎(这个本地引擎只支持英文)。
* 沉浸式背景音乐: 语音层叠舒缓背景音,适合长时间专注。
* 全格式支持:EPUB / PDF / TXT 导入。
* 网页转音频: 支持解析网页链接,把长文章变成“播客”。
* 音频导出: 支持将带背景音乐的文档朗读导出为音频文件。
* 普通阅读:如果您不喜欢听书,拿来当普通阅读器也不错。

目前存在的问题:
1:高质量本地引擎有点耗电(仅支持英文)
2:云引擎在国内访问不太稳定,如果您有梯子或身处国外,听起来还是非常稳定的。

关于定价:目前由于项目刚上线,还在前期推广,所以终身会员是以美元定价自动换算过来的,后续限免活动结束会重新调整国内的定价。

给 V 友的福利: 目前 App 处于早期反馈阶段。为了感谢大家测试和提建议,即日起至 3 月 9 日,Lifetime Pro (永久专业版)限时免费(原价 $59.99 )。
大家下载后直接在 App 内点击内购即可,价格显示为 $0 (¥0)。

App Store 链接: https://apps.apple.com/us/app/aurader-immersive-ai-reader/id6758951184

非常希望得到你们的产品反馈!

https://www.apple.com/ipad-air/

没想到在内存暴涨的时代,库克还给 IPAD AIR M4 标配了 12G RAM ,比 IPAD PRO M4 给的都多。但你要说他良心吧,他还是那万年不变的 60HZ 屏幕。

这一代 IPAD AIR 抛开屏幕不谈,CPU M3 升 M4 是大提升,RAM 也有关键提升,提升幅度仅次于当年 AIR4->AIR5 。但是问题是很多时候没法抛开屏幕不谈。。。60HZ 实在是太难用了

平时都是使用手机浏览器访问 2libra,看到一些好的帖子,事后想去查看,却不记得具体网址了,只记得一些关键字,奈何没找到搜索的地方,找不到对应的帖子了。请问,能否提供相关入口?

在这儿很久了,看到无数的朋友都在讨论工作和发展。

作为过来人,其实还是给大家建议:尽早跳出“搞技术”的陷阱,尽早投身到“业务领域”,不要总是拿自己的“性格”“能力”“环境”“机会”这些做无聊的借口。

如果你不是钻研高精尖技术,或者不是掌握核心技术,最差最差你也要垄断一座重要的“代码屎山”,为了维护这套系统,而你确实无人可代替,那么,其他的,对搞技术的朋友而言,你们的天花板太低太低了。

就这儿,我们要不去扯技术迭代、不要去扯 AI 、不去要扯框架架构、不要去说 35 岁等等,就在这儿,就在这个论坛模块里面,我们能看到许许多多高中的、中专的、大专的朋友全部都在搞“技术研究”,都在搞“高科技”,在搞“核心迭代”,我这么说可能非常不礼貌,但,这个客观的现实是不是说明了“绝大多数人搞技术,天花板太低太低了”,结局也只有且唯有一个,对吧?

这个社会一直在教育我们“离钱近的地方,赚钱更快更容易”,同样的,其实这个社会也一直在教育我们“离业务越近的地方,则越有发展”,所谓的框架和 Code 其实就是埋葬自己的高山,所以,朋友们,打开格局吧,积极的走向“奔赴业务领域”的怀抱吧。

本文由网易云音乐技术团队入云分享,有修订和排版优化。

1、引言

说起 IM,大家应该都或多或少了解过一些,一般被熟知是在一些聊天场景里应用的比较多;而一般情况下我们常接触的业务中大多是做一些接口的查询提交之类的操作,用正常的 Ajax 请求就足以满足需求,比较难接触到 IM 这种方案。

但如果涉及到一些需要频繁更新数据的业务场景,使用常规接口查询难免会给服务端造成比较大的性能开销,并且数据更新的延迟也会很大;尝试使用 IM 则可以让我们在业务开发中更好地应对频繁的数据更新场景,以提升用户体验和业务价值。近期在做一个多人实时打怪兽的场景,即多名玩家同时攻击一个怪兽,任意一个玩家攻击怪兽,其它玩家需要实时感知到怪兽的状态更新,比如怪兽血量和玩家伤害排行等信息。
图片
本文将从H5游戏场景下的实时信息更新需求切入,探讨下在类似这种高并发、低延迟的业务需求中,如何使用 IM 方案来解决频繁的数据更新问题,也顺便介绍下 WebSocket 的基本运作流程等。
图片

2、数据更新方案选型

在谈论 IM 之前,对于数据的实时更新,除了使用 IM ,还有哪些可选用的方案,可能包括但不限于下面几种。

2.1 接口轮询

接口轮询这种方式相信大家都很熟悉,主要是使用通过定期发送 HTTP 请求来达到数据更新的方式,实现起来也比较简单。例如一些榜单数据的定时更新:// 请求榜单接口const refreshRank = (familyId) => {    getMonsterDamageRank({ familyId }).then((res) => {        setRank(res);    }).catch((err) => {        Toast.warn(err.message || '服务器繁忙');    });}; // 每3秒刷新一次接口setInterval(() => {    refreshRank(currentFamily.familyId);}, 3000);这里使用 setInterval 每隔3秒请求一次榜单数据,用来更新排行榜信息,通常用于实现一些要求数据更新相对频繁,但又允许有一定延迟的场景;同时轮询也是一种实现起来最简单的方案。但轮询也有几个比较大的缺点,比如:1)带宽浪费:轮询需要定期向服务器发送请求,即使服务端没有新数据可用,这将会造成大量的带宽和服务器资源浪费。2)延迟高:数据的更新频率受轮询间隔影响,如果轮询间隔时间过长,会导致数据更新的延迟较高。3)负载过高:要降低数据的延迟,就必须提高接口轮询的频率,但轮询的频率过高,将会导致服务器负载过高,从而影响其他用户的体验。
图片

2.2 接口长轮询

长轮询(Long Polling)是一种改进的轮询技术,它的主要思想是在客户端发送请求后,服务端保持连接打开,但并不立即响应,而是在有新数据可用时才响应给客户端。当客户端接收到响应后,再次发起请求,以保持连接打开。相比于传统的轮询:长轮询可以降低网络延迟和服务器压力;因为长轮询的响应是异步的,服务器不需要在每个固定时间间隔内返回响应,这样可以减少不必要的请求。同时,当服务器有新数据可用时,也可以立即返回响应,从而提高数据的实时性。
图片
 如上图,长轮询的实现通常分为下面几个阶段:1)客户端向服务器发起请求。2)服务器接收到请求后,如果没有新数据可用,则保持连接打开。3)服务器有新数据可用时,响应给客户端。4)客户端接收到响应后,再次向服务器发起请求。 ......下面是使用 Node.js 实现的一个简单的长轮询服务端示例:const http = require('http');const messages = []; // 开始每隔1秒检查下messages中是否有信息function waitForNewMessages(response) {  const intervalId = setInterval(() => {    if (messages.length > 0) { // message 中有消息之后返回响应      response.writeHead(200, { 'Content-Type': 'application/json' });      response.end(JSON.stringify(messages));      clearInterval(intervalId);    }  }, 1000);   setTimeout(() => { // 30秒无数据,返回一个空数组    clearInterval(intervalId);    response.writeHead(200, { 'Content-Type': 'application/json' });    response.end(JSON.stringify([]));  }, 30000);}function handleRequest(request, response) {  if (request.url === '/messages') {    /* 请求到“/messages”时,如果有新消息,则立即向客户端发送响应       否则,等待一段时间后再次检查是否有新消息      /    waitForNewMessages(response);  } else {    response.writeHead(404);    response.end();  }}const server = http.createServer(handleRequest);server.listen(3000);在上面的代码中:我们使用  setInterval  函数每秒检查一次是否有新消息。如果有新消息,我们立即向客户端发送响应,并清除定时器。为了防止一直 pending,如果在30秒内没有新的消息,我们会向客户端发送一个空数组作为响应。这样,客户端就可以在收到新消息时立即更新页面。对于长轮询的实现仍有许多细节需要注意,如连接保持、连接断开重连等问题。此外,长轮询仍然需要消耗大量的带宽和服务器资源,因为每个连接都需要保持打开状态,可以想象有很多个请求到达服务端,服务端需要开启多个异步来保持链接在 pending 的状态。

2.3 SSE(Server-Sent Events)

SSE 也是一种浏览器与服务器之间实现实时通信的技术。它允许服务器向浏览器发送数据。在 SSE 中,浏览器可通过 EventSource API 来建立与服务器的连接,并监听来自服务器的事件。服务器通过向客户端发送特定格式的数据(包括事件名称和数据),来触发浏览器的事件监听器。下面同样使用 Nodejs 来实现一个 Demo:// Server 端const http = require('http'); const server = http.createServer((req, res) => {  // 设置头部信息  res.writeHead(200, {    'Content-Type': 'text/event-stream', // 设置响应类型为SSE    'Cache-Control': 'no-cache',    'Connection': 'keep-alive',    'Access-Control-Allow-Origin': '*' // 允许跨域请求  });   // 发送数据到客户端  setInterval(() => {    res.write('data: ' + new Date().toISOString() + '\n\n'); // 发送SSE消息  }, 1000);}); server.listen(3000, () => {  console.log('Server started on port 3000');}); // Client端const sse = new EventSource('http://localhost:3000'); // 监听SSE消息sse.addEventListener('message', (event) => {  console.log(event.data);});在客户端使用 new EventSource 访问 “h t t p : // localhost:3000” 时,服务器会返回一个 SSE 流,这里注意需要将响应头中的 Content-Type 设置为 text/event-stream,表示该响应是 SSE 流;将  Cache-Control  设置为 no-cache,表示浏览器不缓存该响应, Connection  设置为 keep-alive,表示服务器与客户端之间的连接应该保持打开状态。在 SSE 流中,每一条消息都需要以 data: 开头,并以两个换行符(\n\n)结尾。在本例中,使用 setInterval() 函数每秒发送一条消息。但对于SSE而言,也具有下面几个缺点:1)单向传输:只能从服务器向客户端推送数据,无法实现双向通信;2)只支持纯文本:事件流只能传输一个简单的文本数据流, 并且文本只能使用 UTF-8 格式编码;3)SSE对于一些浏览器的支持不够完善:比如在 Safari 和 iOS 中,可能会对 SSE 连接的数量和连接时间等方面进行限制,从而影响 SSE 的稳定性和可靠性。

2.4 HTTP/2 Server Push

相对于 HTTP/1.1 而言,HTTP/2 其实也是支持了服务端主动推送的,不过目前 HTTP/2 的主动推送,主要是用于提升页面加载性能的,它允许服务器在响应请求时向客户端推送预先缓存的资源(例如,CSS、JavaScript 和图像),以减少请求次数和延迟,是一种页面加载的优化手段。但考虑到其相对于 WebSocket 而言,目前的安全性和稳定性还有待进一步提升,用于实现即时通信还不是特别成熟,所以这里就不再赘述了。对与如何实现提前推送静态文件,具体可以参考下《快速理解HTTP/2的服务器推送(Server Push)》。

2.5 WebSocket

上面介绍的几种方式,都是基于HTTP协议的,而 WebSocket 则是一种新的协议。WebSocket诞生于 2008 年 6 月,在 2011 年 12 月成为 RFC6455 国际标准,并且WebSocket协议是一种专门为实时通信而设计的协议。所以对于实现即时通信而言,WebSocket 可以说是最佳选择。相对于上面几种方式,它具有下面几个优点:1)低延迟:WebSocket 通过保持持久连接,避免了HTTP短连接频繁地建立和关闭连接的开销,从而降低了延迟。2)双向通信:WebSocket 协议支持双向通信,客户端和服务器都可以向对方发送数据,从而实现更加灵活的通信方式。3)跨域支持:WebSocket 协议支持跨域通信,可以在不同源之间传输数据,从而支持更多种场景下的应用。4)更少的数据传输:WebSocket 协议支持二进制数据传输和数据压缩,可以减少数据传输的延迟和带宽消耗。说到底,上面提到了好几种方案,其实都可以在不同程度上实现数据的实时更新,但是它们跟本次需求中使用到的 IM 方案有什么关系呢?或者说 IM 究竟是个什么样的方案呢?下面的章节我们将先明确下 IM 的概念。

2.6 延伸阅读

因篇幅有限,本章节涉及到的技术无法为你深入介绍,如有兴趣可进一步阅读以下资料,夯实基础:新手入门贴:史上最全Web端即时通讯技术原理详解Web端即时通讯技术盘点:短轮询、Comet、Websocket、SSE详解Web端通信方式的演进:从Ajax、JSONP 到 SSE、Websocket网页端IM通信技术快速入门:短轮询、长轮询、SSE、WebSocket搞懂现代Web端即时通讯技术一文就够:WebSocket、socket.io、SSE

3、认识IM

3.1 IM 具体是指什么

即时通信(Instant Messaging,简称IM)是一种透过网络进行实时通信的系统,允许两人或多人使用网络即时的传递文字消息、文件、语音与视频交流。通常以网站、电脑软件或移动应用程序的方式提供服务(来自百科)。换句话说:我们只要采用某种方式,能实现两人或多人之间可以通过网络实时的交换信息,就可以称之为是一种 IM 方案。那么上面所提到的几种实现数据更新方式,都可以用做实现 IM 方案的底层实现方案。PS:如您还有疑问,可进一步阅读以下资料:知识科普:IM聊天应用是如何将消息发送给对方的?(非技术篇)零基础IM开发入门(一):什么是IM系统?

3.2 Web 端 IM 的发展历程

对于 Web 端 IM 的发展历程,其实大致都囊括了上面提到的几种实现方式;这些技术经过不断优化,持续提升了用户体验。其演变过程可以大致概括为从早期的轮询技术到长轮询,再发展到现代的 WebSocket、Server Push 的实现方式。而 WebSocket 的出现,则实现了更高效、更实时的即时通信。

图片

本次要实现多人打怪兽同步信息的场景,对数据更新的实时性要求非常高,所以本次需求所依赖的 IM 方案,就是基于更稳定的 WebSocket 实现的。所以下面就详细介绍下 WebSocket 和HTTP的区别,以及 WebSocket 的运作流程。

4、WebSocket 与 HTTP 到底是什么关系?

WebSocket 虽然是一种新的协议,但同 HTTP 协议一样,WebSocket 协议也是运行在 TCP 协议之上的,与 HTTP 协议同属于应用层网络数据传输协议。那 WebSocket 和 HTTP 究竟有哪些不一样呢?HTTP 属于短连接,每发起一次请求都需要建立一次连接,请求结束后立即关闭连接,属于“请求-响应模式”,即客户端需要主动发送请求才能获取到服务器返回的数据。即便是我们上面介绍的“长轮询”,也是需要依赖服务端来“hold”住请求。HTTP 是一种无状态协议,每个请求都是独立的,服务器不会保存客户端的状态信息。所以每次客户端发送请求,都会在请求头里塞一些类似于 Cookie 这种信息用来标识当前请求属于哪个用户。不同于 HTTP,WebSocket 协议中客户端和服务端只需要完成一次握手,两者之间就可以建立持久性的连接,并可以进行双向的数据传输。

图片

 PS:关于HTTP和WebSocket的区别可进一步阅读《WebSocket详解(四):刨根问底HTTP与WebSocket的关系(上篇)》)。

5、快速入门WebSocket

5.1 建立连接

Demo 跑起来看着是挺简单的,但 WebSocket 长链接到底是怎么建立的呢?在介绍连接建立之前,我们先来了解下 HTTP 协议请求头中 Upgrade 这么一个字段。HTTP 协议是一种文本协议,虽然其灵活性很高,但在处理大量数据和多媒体内容时效率较低。将协议升级为 WebSocket 或 HTTP/2 可以支持更多数据格式的传输;所以为了支持将协议升级,在 HTTP/1.1 中新增了 Upgrade 请求头,它允许客户端请求将其连接升级到另一个协议:Upgrade: <protocol>其中,protocol 表示希望升级到的协议名称,例如 WebSocket、HTTP/2 等。另外,Upgrade 头部还可以与 Connection 头部一起使用,以指示客户端希望使用持久连接。这可以减少每个请求的开销,从而提高网络性能和效率,要将协议升级为 WebSocket,就需要将这两个字段结合起来:Connection: UpgradeUpgrade: WebSocket这里我们了解到 WebSocket 协议是通过 HTTP 协议升级而来的,那么具体的长链接的生命周期是怎样的呢?下面是一个大致的 WebSocket 流程图:
图片
如上图,可以简单的将 WebSocket 的生命周期大致分为三个阶段:1)通过一次HTTP握手建立 WebSocket 长链接(也就是协议升级的过程);2)使用 WebSocket 协议进行数据传输;3)任意一方发送关闭帧,对方响应关闭帧后,长链接关闭。

5.2 握手请求

WebSocket 的建立是通过一次 HTTP 请求握手来实现的,客服端通过发送一个 GET 请求,并在 Request Header 里携带一些协议升级所需的参数,告诉服务器对本次 HTTP 请求进行升级。GET ws://localhost:3000/ HTTP/1.1Host: localhost:3000Connection: UpgradePragma: no-cacheCache-Control: no-cacheUpgrade: websocketSec-WebSocket-Version: 13Sec-WebSocket-Key: nFPKUyeo5Ul58tbe7Dg5lA==上面是一个 WebSocket 的请求快照,对于 Upgrade 字段上面已经介绍过,这里看下剩下的几个关键的参数:Sec-WebSocket-Key:是由客户端生成的一次性随机值,该值与服务端响应首部的 Sec-WebSocket-Accept 是配套的,提供基本的防护,比如防止恶意或者无意的连接。Sec-WebSocket-Version:这里表明 WebSocket 协议的唯一可接受版本是13。

5.3 握手响应

一旦客户端发送了打开 WebSocket 连接的初始请求,它就会等待服务器的回复。该回复必须有一个 HTTP 101 切换协议的响应代码。HTTP 101 切换协议响应表明,服务器正在切换到客户端在其升级请求头中所指定的协议。同样的,在响应头里也会包括 Upgrade 字段,标识协议已被升级。HTTP/1.1 101 Switching ProtocolsUpgrade: websocketConnection: UpgradeSec-WebSocket-Accept: 89D1tEKizEJHFrVDhswIIpAf4ww=此外,响应头中的 Sec-WebSocket-Accept 是一个处理后的 base64 编码,是通过客户端请求头中的 Sec-WebSocket-Key 和 RFC6455 中定义的静态值 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 拼接来生成的。计算步骤为:将 Sec-WebSocket-Key 跟 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 拼接通过 SHA1 计算出摘要,并转成 base64 字符串:
图片
通过这样一个HTTP的请求和响应,就表明长链接的握手过程已经完成,并将协议升级成了 WebSocket 协议,后续双方就可以通过这个长链接通道传输数据了。那数据具体又是怎样传输的呢?

5.4 数据传输

WebSocket 在传输数据的过程中,实际上会将大块数据(消息)分成若干帧进行传输,RFC6455 中给出了帧的概述。这里大致介绍下一些重要字段:
图片
FIN (Final):表示当前帧是否为最后一个片段;1 表示是消息的最后一个片段,0 表示不是消息的最后一个片段RSV1,  RSV2,  RSV3 (Reserved):扩展字段,各占 1 比特,一般情况全为 0opcode:每个帧都有一个操作码,这个操作码决定如何来解释这个帧的有效载荷数据。opcode操作码具体分为以下几个类型:
图片

5.5 链接关闭

要关闭 WebSocket 连接,发送端需要发送一个关闭帧(opcode 0x8)。如果连接的任何一方收到一个关闭帧,它必须发送一个关闭帧作为响应,一旦双方都收到了关闭帧,WebSocket 连接将会断开。以上就是WebSocket连接从建立到断开的全过程,如果你还想深入学习,可以继续阅读以下资料:WebSocket从入门到精通,半小时就够!WebSocket详解(六):刨根问底WebSocket与Socket的关系Web端即时通讯实践干货:如何让你的WebSocket断网重连更快速?

6、WebSocket协议升级代码实践

根据上面的 WebSocket 的流程描述,我们可以使用 Nodejs 实现一个简单版的协议升级逻辑,并使用浏览器 Api 实现对应的客户端逻辑。

6.1 服务端逻辑

以下是一个使用Node.js原生模块实现 WebSocket 服务端的例子:// 导入所需的Node.js原生模块const http = require('http');const crypto = require('crypto');// 创建HTTP服务器const server = http.createServer(); // 解析WebSocket帧function parseFrame(buffer) {    // 这里获取操作码(opcode),表示数据帧的类型    const opcode = buffer[0] & 0x0f;    // 这行代码获取负载长度(payload length)。它表示数据帧的实际数据长度。这里仅考虑了较短的数据长度,实际上可能需要处理更长的数据长度    const payloadLength = buffer[1] & 0x7f;    // 数据帧的数据部分(payload)是以掩码的形式发送的,需要使用掩码来解码。    const mask = buffer.slice(2, 6);    // 这里获取帧中的实际数据    const payload = buffer.slice(6);    let decodedPayload = '';    if (opcode === 1) { // 文本数据帧        for (let i = 0; i < payloadLength; i++) {            // 这里使用异或操作对数据字节与相应的掩码字节进行解码:payload[i] ^ mask[i % 4]。这里使用模运算(i % 4)确保在掩码的 4 个字节之间循环。            // 使用 String.fromCharCode() 将解码后的字节转换为字符,并将解码后的字符添加到 decodedPayload 字符串中。            decodedPayload += String.fromCharCode(payload[i] ^ mask[i % 4]);        }    } else if (opcode === 8) { // 关闭帧        return { type: 'close' };    }     return { type: 'text', data: decodedPayload };} // 根据给定的文本消息创建一个文本数据帧function createTextFrame(message) {    // 根据消息长度分配一个缓冲区。这里仅处理较短的消息,因此分配 2 个额外字节用于帧头    const buffer = Buffer.alloc(2 + message.length);    // 设置帧头的第一个字节。0x81 表示一个最终帧(FIN = 1)且操作码为文本(opcode = 1)    buffer[0] = 0x81;    // 设置帧头的第二个字节。这里仅处理较短的消息,所以直接将消息长度设置为负载长度。这意味着没有掩码(mask = 0)    buffer[1] = message.length;    // 将消息写入缓冲区。对于每个字符,获取其字符编码(Unicode 编码)并将其添加到缓冲区。    for (let i = 0; i < message.length; i++) {        buffer[i + 2] = message.charCodeAt(i);    }    return buffer;} // 向客户端发送消息function sendTextMessage(socket, message) {    const frame = createTextFrame(message);    socket.write(frame);} // 监听服务器的upgrade事件server.on('upgrade', (req, socket, head) => {    // 检查WebSocket协议和版本    if (req.headers['upgrade'] !== 'websocket' || req.headers['sec-websocket-version'] !== '13') {        socket.destroy();        return;    }     // 获取客户端发送的Sec-WebSocket-Key    const key = req.headers['sec-websocket-key'];     // 计算Sec-WebSocket-Accept    const sha1 = crypto.createHash('sha1');    sha1.update(key + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11');    const accept = sha1.digest('base64');     // 构建响应头    const headers = [        'HTTP/1.1 101 Switching Protocols',        'Upgrade: websocket',        'Connection: Upgrade',        'Sec-WebSocket-Accept: ' + accept,        '\r\n'    ];     // 发送响应头    socket.write(headers.join('\r\n'));     // 监听数据    socket.on('data', (buffer) => {        const frame = parseFrame(buffer);         if (frame.type === 'text') {            console.log('Received message:', frame.data);            // 在此处实现处理收到的文本消息            // 向客户端发送消息            sendTextMessage(socket, 'Hello, client!');        } else if (frame.type === 'close') {            console.log('Client closed the connection.');            socket.destroy();        }    });     // 监听关闭    socket.on('close', () => {        console.log('Socket has been closed.');    });}); server.listen(3000, () => {    console.log('WebSocket server listening on port 3000');});这里创建了一个基于 HTTP 的 WebSocket 服务,并监听 3000 端口,其中细节部分已经在代码里注释。当客户端发起升级请求时,服务器将在握手过程中验证客户端的请求,并在成功升级到WebSocket连接后监听来自客户端的数据同时发送一个 'Hello, client!' 作为回复。6.2 客户端逻辑下面是对应客户端逻辑,使用浏览器原生 Api WebSocket 来实现长链接的建立:<!DOCTYPE html><html><head>  <meta charset="UTF-8">  <title>WebSocket demo</title></head><body>  <h1>WebSocket demo</h1>  <input type="text" id="message">  <button>Send</button>   <button>End</button>  <div id="output"></div>  <script>    // 创建 WebSocket 连接    const ws = new WebSocket('ws://localhost:3000/');     // 监听消息    ws.onmessage = (event) => {      const output = document.getElementById('output');      output.innerHTML += <p>${event.data}</p>;    };     // 长链接断开    ws.onclose = () => {        const output = document.getElementById('output');        output.innerHTML += <p>WebSocket closed</p>;    }     // 发送消息    function sendMessage() {      const message = document.getElementById('message').value;      ws.send(message);    }     // 关闭长链接    function handleEnd() {      ws.close();    }  </script></body></html>在客户端创建一个 WebSocket 并连接到ws://localhost:3000服务器,这里注册了长链接的 onmessage 和 onclose 事件;在输入框里输入信息点击发送,会向服务端发送一个消息,服务端在接收到客户端消息时,紧接着会向客户端发送一个文本消息,同时在页面中点击 end 可以将长链接关闭。客户端:
图片
服务端:
图片
对于浏览器 WebSocket Api 除了常用回调 onclose、onmessage、 onerror、onopen,WebSocket 实例本身还有一些属性可以判断长链接当前的状态(如下图),详细参数可参考 MDN 中的详细介绍「WebSocket」。
图片

7、基于IM即时通信方案的最终落地

7.1 概述

上面我们使用 Nodejs 和浏览器 WebSocket Api 实现了一个简单的即时通信,但这还远远达不到可以在生产环境中使用的标准,比如涉及到网络异常、掉线重连、较大数据量处理、兼容性处理等问题。当然 WebSocket 有很多成熟的库可以直接使用,比如 Socket.IO、Ws,这些库都是经过广泛使用和测试的开源项目,具有良好的稳定性和可靠性。对于生产环境使用这些成熟的库可以减少很多不必要的麻烦。作为本次需求的 IM 方案,我们则选择使用的是由 云信 提供的 Web IM 即时通讯能力;改方案提供了包括服务端和 Web 端一套完整的方案,可以快速集成到我们的工程中,实现即时通信的能力。云信 Web SDK 提供了多种常见聊天场景,例如单聊、群聊、聊天室等。本次需求主要涉及多人场景,并且战斗不要求持久性,一场战斗由多人同时在线参与,并且在战斗结束后就解散,所以这里选择使用的是聊天室场景。

对于消息的流转如下:
图片

7.2 客户端集成

SDK整体方案的集成可参考云信官方网站,这里仅介绍下客户端的集成过程,和所需要注意的问题。对于客户端这里选择通过 npm 集成 SDK:npm install @yxim/nim-web-sdk@latestSDK 所包含的三个文件的说明如下:dist/SDK├── NIM_Web_Chatroom.js       提供聊天室功能,浏览器适配版(UMD 格式)├── NIM_Web_NIM.js       提供 IM 功能,包括单聊、会话和群聊等,但不包含聊天室。浏览器适配版(UMD 格式)├── NIM_Web_SDK.js       提供 IM 功能和聊天室功能的集成包,浏览器适配版(UMD 格式)这里使用的是聊天室能力,可通过单例模式初始化登陆聊天室,如下:import Chatroom from '@yxim/nim-web-sdk/dist/SDK/NIM_Web_Chatroom';export class InitChatRoom {  static async getRoomInstance({ onChatMsg = () => {} }) {    if (!InitChatRoom.instance) {        InitChatRoom.instance = Chatroom.getInstance({            appKey: 'appKey', // 在云信管理后台查看应用的 appKey            account: 'account', // 帐号, 应用内唯一            token: 'token', // 帐号的 token, 用于建立连接            chatroomId: 'chatroomId', // 聊天室 id            chatroomAddresses: [ // 聊天室地址列表              'address1',              'address2'            ],            onconnect: () => {}, // 长链接建立成功回调            onmsgs: (data) => {}, // 消息触达回调            ondisconnect: () => {}, // 长链接断开回调            onwillreconnect: () => {} // 长链接即将重连        });    }    return InitChatRoom.instance;  }}

7.3 消息的过滤

在本次需求中,怪兽血量和状态的更新主要是依赖消息的推送。另外活动是每天定点开放,所以活动开始时会有大量用户同时涌入参与攻击怪兽,在这种情况可能会造成消息在服务端的堆积,导致消息触达到客户端时不能保证消息是按产生的先后时间到达的。举个例子,比如 20:01 产生的消息,由于消息堆积可能会在 20:02 产生的消息后面到达,这样就可能会导致怪兽的血量忽大忽小的跳动;或者是怪兽已经死了,而怪兽掉血的消息才刚刚到达,此时就需要将这些过时的消息抛弃掉。处理方式也比较简单,就是针对每一个消息体都会添加一个消息产生的时间戳,通过这个时间戳可以将延迟触达的消息过滤掉。onmsgs: (data) => {       // 延迟消息的过滤,判断掉血消息的时间是否大于之前的消息时间    const { msgTime } = data; // 当前消息产生时间    const preTime = monster?.msgTime || 0; // 上一条消息时间    if (msgTime > preTime) {      monster.remainingHp = remainHp; // 更新怪兽剩余血量      monster.damage = damage;      monster.msgTime = msgTime;    }}

8、本文小结

本次需求也是首次在日常活动需求中使用 IM 方案,整体看起来也没有预期的那么复杂,总的来讲相对于之前常用的接口轮询的方式,会减少很多对服务端的压力,同时 IM 方案更新数据的及时性,也大幅提升了用户体验。项目稳定运行一年多,也验证了 IM 方案在日常需求中的可行性。

9、参考资料

[1] RFC6455 协议文档、WebSocket API文档、SSE API文档
[2] 新手入门贴:史上最全Web端即时通讯技术原理详解
[3] Web端即时通讯技术盘点:短轮询、Comet、Websocket、SSE
[4] 详解Web端通信方式的演进:从Ajax、JSONP 到 SSE、Websocket
[5] 网页端IM通信技术快速入门:短轮询、长轮询、SSE、WebSocket
[6] 搞懂现代Web端即时通讯技术一文就够:WebSocket、socket.io、SSE
[7] AI大模型爆火的SSE技术到底是什么?万字长文,一篇读懂SSE!
[8] WebSocket详解(四):刨根问底HTTP与WebSocket的关系(上篇)
[9] WebSocket详解(六):刨根问底WebSocket与Socket的关系
[10] Web端即时通讯实践干货:如何让你的WebSocket断网重连更快速?
[11] WebSocket从入门到精通,半小时就够!
[12] 理论联系实际:从零理解WebSocket的通信原理、协议格式、安全性
[13] 微信团队分享:来看看微信十年前的IM消息收发架构,你做到了吗
[14] 零基础IM开发入门(一):什么是IM系统?
[15] 转转客服IM系统的WebSocket集群架构设计和部署方案
[16] 转转客服IM聊天系统背后的技术挑战和实践分享
[17] 一套亿级用户的IM架构技术干货(上篇):整体架构、服务拆分等
[18] 一套亿级用户的IM架构技术干货(下篇):可靠性、有序性、弱网优化等
[19] 转转平台IM系统架构设计与实践(一):整体架构设计
[20] 如何保障分布式IM聊天系统的消息有序性(即消息不乱)
[21] 脑残式网络编程入门(四):快速理解HTTP/2的服务器推送(Server Push)

即时通讯技术学习:

(本文已同步发布于:http://www.52im.net/thread-4896-1-1.html

📘论文标题:
Thermodynamic Simulation-assisted Random Forest: Towards explainable fault diagnosis of combustion chamber components of marine diesel engines

🔗论文链接ScienceDirect

💡原作者Blog(包含代码、数据集)

一、高可靠性系统对透明决策的需求

在轨道交通、航行安全等关键工业领域,现代系统正向复杂化与集成化演进,技术人员难以采信缺乏物理依据的诊断结果。船用柴油机作为核心动力设备,其设计具有极高的可靠性,导致实际运行中重大故障数据极度匮乏。此外,传统诊断方法在融合样本数据与物理模型,并合理解释特征决策过程方面存在显著局限。2025年《Measurement》期刊发表的研究提出了一种热力学仿真辅助随机森林(ThermoRF)方法。该方法在获取故障样本与实现结果可解释性之间寻求平衡,为复杂系统的智能运维提供了备选路径。

二、ThermoRF 架构:物理模型与数据驱动的融合

该研究构建了一个具备“模型数据协同”特点的诊断框架,主要包含以下核心阶段:

1.热力学建模与校准

构建柴油机一维热力学模型,用于模拟故障状态并生成训练数据。通过与真实航行数据校准,该模型参数偏差小于 5%,确保了仿真环境的可靠性。下图为柴油机的一维热力学模型。

图1 柴油机的一维热力学模型

2.高保真故障数据集生成

通过微调物理参数,模拟出包括气缸盖开裂(F1)、活塞烧蚀(F2)、缸套磨损(F3)、活塞环磨损(F4)及活塞环粘着(F5)在内的五种典型故障,解决了实际运维中故障数据匮乏的难题。下表为各故障状态细节。

3.基于 SHAP 理论的特征筛选

利用 SHAP(Shapley Additive Explanations)值量化 14 个热力学参数的重要性。最终精选出涡轮后排气温度(P14)、缸套壁热流(P05)等 8 个核心参数,组成优化特征子集以提升诊断效率。下图为基于SHAP的参数选择过程。

4.智能故障识别

将优化后的子集输入随机森林(RF)分类器。实验证明,RF 在该数据集上的平均准确率高达 99.07%,其表现优于 KNN 与 SVM 等分类算法。下图为 KNN、SVM 和 RF 的精度-召回率曲线图。

三、双尺度可解释故障诊断分析

该研究的核心价值在于使故障判定的逻辑透明化,实现了两个层面的可解释性分析:

1.局部尺度解释

采用瀑布图直观展示模型对单个样本的决策逻辑。例如,通过捕捉窜气热流(P06)与质量流量(P07)的特定异常,揭示模型如何根据物理规律判定特定故障。

2.全局尺度解释

利用蜂群图、交互图及依赖图从整体层面提炼核心指标。分析揭示了“窜气导致涡轮前排气压力(P11)降低”等深层物理联系,证明了数据特征与内燃机热力学机制的一致性。

下图为基于 SHAP 值的双尺度故障分析:(a)瀑布图;(b)蜂群图;(c)交互图;(d)依赖图。

四、结论与展望

ThermoRF 方法成功发挥了物理建模与数据驱动的互补优势,不仅提升了故障诊断的精度,更通过双尺度分析为诊断结果提供了物理支撑。这种可解释故障诊断模式,对于提升重大装备运维的安全感与科学性具有重要意义。

原始文献
C. Luo, M. Zhao, X. Fu, S. Zhong, S. Fu, K. Zhang, X. Yu. Thermodynamic simulation-assisted random forest: Towards explainable fault diagnosis of combustion chamber components of marine diesel engines[J]. Measurement, 2025, 251: 117252.

做过的项目类型如下

  • 企业官网系统
  • 电商网站系统
  • 后台管理系统
  • 数据管理平台
  • 小程序 API 后端
  • 自动化数据处理系统
    联系方式 ejE0MzAzMTc3NDk=

零、前言

各位 V 友,分享一款本人开发的 24 点解谜 APP——《 24 点 - 解得出的谜题》,它在 IOS 某付费榜中排第 9 名。
该 app 体验极佳,核心亮点很突出,适合碎片时间消遣、锻炼逻辑,附上 20 枚免费兑换码,先到先得~

一、全平台,全兼容

目前可在 App Store 、鸿蒙(后续将上架至安卓、MacOs 、Win 等)等平台上下载、使用。欢迎各位大佬支持&交流、提出建议或意见~

二、整体概览图

整体概览图

三、核心功能(不冗余,直击重点)

  1. 题库丰富:数千道题目,覆盖不同难度,从新手到高手都能找到适配的题目,无需额外付费解锁题库。
    题库数千:主打 [乐在其中,无法自拔]

  2. 模式多样:包含竞速、随机、收藏三种核心模式,可按需选择,兼顾趣味性和挑战性。
    多种模式,趣味无穷:竞速、随机、收藏,应有尽有

  3. 功能灵活:支持高度自定义,可根据个人习惯调整游戏设置,无强制引导,体验流畅。
    功能丰富:你的游戏,你做主

  4. 求解便捷:内置智能求解模式,遇到卡壳的题目可快速获取灵感,不影响解题体验,无卡顿。
    求解模式:灵感,不再卡顿

四、适合场景

通勤、摸鱼、睡前碎片化时间,无需复杂操作,打开就能玩,既能解压,也能悄悄锻炼数学逻辑。

五、兑换码

兑完请在评论区告知,方便其他 V 友:

LHRAPWRJRA6X

K7WH9E4MH7RW

WA63YP637PTA

N7HE76XYMRFR

AFT9LL3FYM4W

YJ7TM7PKJ9YW

HHF4HPNRF4XK

APAWWL4FFNR3

34Y64WMXR6XP

RP4YFFTJ4FWE

我之前开了一个 Pro Plan ,然后那个 Claude Opus 4.6 出来的时候送了 50 刀的免费额度。使用了一半还剩一半没用完

我第二个月是在 Pro Plan 过期了两天才续费的,结果续费之后发现额度没了。

何意为呀,大家有这种情况吗