聊天系统通常使用 websocket 协议进行对话websocket介绍WebSocket 是一种协议用于在 Web 应用程序和服务器之间建立实时、双向的通信连接。WebSocket 的优势包括实时性 由于 WebSocket 的持久化连接它可以实现实时的数据传输避免了 Web 应用程序需要不断地发送请求以获取最新数据的情况。双向通信 WebSocket 协议支持双向通信这意味着服务器可以主动向客户端发送数据而不需要客户端发送请求。减少网络负载 由于 WebSocket 的持久化连接它可以减少 HTTP 请求的数量从而减少了网络负载。由于这些特性websocket 一般用于聊天系统、在线游戏等需要实时推送信息对延迟低容忍的场景http 协议和 websocket 协议对比httpwebsocket连接方式短链接返回后链接就断开了长链接在主动结束前会一直保持链接通信模式单向客户端对服务端双向服务端可以主动推数据例如消息提醒性能每次请求都要重新建立 TCP 连接开销大连接建立后可持续通信减少握手开销提高效率适用场景文件下载、网页浏览等需要实时通信的场景例如聊天心跳机制websocket 存在一个独特的机制心跳探活。这种机制通过定时向服务端/客户端发送一个数据包来检测链接是否还存活。如果发送了心跳包后没有收到返回说明链接大概率已经断开。客户端定时发送心跳包可以防止长时间无数据被服务端断开链接。服务端也可以清理链接节省资源开销websocket请求查看方法路径开发者工具 - Network - WS - Message。注意要在建立 websocket 链接的时候就打开开发者工具才能看到如果在建立完 websocket 链接后才打开是看不到的websocket数据流向简单理解所有的用户都是客户端包括 B 端商家服务端只有一台websocket 服务。所有的人建立连接后消息都先走到服务端由服务端进行处理推送到正确的房间中websocket协议接口测试postman1.添加 websocket 协议请求输入 websocket 链接点击 connect 进行链接2.输入消息体消息体可以从开发者工具中复制。然后选择对应的消息体数据类型点击发送python代码如下websocket 需要使用协程去写不能用线性的方式执行。可以参考文档https://blog.csdn.net/qq_40978256/article/details/143016874。import asyncio import websockets class ws: def __init__(self, url, attr): self.url url self.websocket None self.loop asyncio.get_event_loop() self.client_id self.attr attr async def get_client_id(self): if not self.websocket: self.websocket await websockets.connect(self.url,open_timeout60) enter_res json.loads(await self.websocket.recv()) if enter_res.get(action): if enter_res[action] in [readMsg, tipmsg]: self.client_id enter_res[data][clientId] elif enter_res[action] sendmsg: self.client_id enter_res[data][response][clientId] else: # action是heartbeat的情况 self.client_id enter_res[data][cliend] else: # action是enter的情况 self.client_id enter_res[data][clientId] setattr(Global,self.attr_clientId,self.client_id) async def connect(self): try: self.websocket await websockets.connect(self.url) await self.get_client_id() # print(fConnected to {self.url}) except websockets.ConnectionClosed as e: await self.close() async def send_message(self, message): if self.websocket and self.websocket.open: try: await self.websocket.send(message) time.sleep(0.5) except websockets.ConnectionClosed as e: await self.close() except Exception as e: print(error:,e) else: await self.connect() await self.send_message(message) async def receive_message(self): if self.websocket and self.websocket.open: try: message await self.websocket.recv() return message except websockets.ConnectionClosed as e: await self.close() except NameError: return message except Exception as e: print(e) else: await self.connect() return await self.receive_message() async def close(self): if self.websocket: await self.websocket.close() self.websocket None print(WebSocket connection closed) websocket_handler.ws websocket_handler.ws( urlfwss://test.com)测试点消息格式聊天系统通常至少要兼容以下几种格式的数据。1、普通文本2、超链接3、图片/视频/gif/音频4、emoji 表情5、文件6、富文本7、系统通知8、功能自定义数据除了以上的几种数据以外通常还会根据系统的应用场景开发一些自定义的消息比如微信中就有红包、转账、小程序卡片、公众号文章、定位等。Tidio这类为 shopify 卖家提供服务的应用也通常会兼容 shopify 商品、优惠券、订单的显示。那么总结下来比较特殊的数据格式为以下内容在测试时要根据系统的功能考虑1、跟交易相关的数据红包/转账/群收款2、与应用的交互小程序卡片/公众号推文/视频号链接/shopify 商品等3、地图定位4、交互消息语音消息、语音/视频通话5、消息转发/消息引用与其他应用的集成目前的聊天系统可以大致分为几种面向 C 端用户、面对 B 端商家、特殊场景G 端/内部通信系统。那么对 B 端商家来说客户可能来自许多不同的渠道比如 Email/Facebook/ins/WhatsApp 等等。这种时候就需要考虑自身聊天系统和其他应用的集成。在做集成的时候有一些问题是需要注意的1、集成是否需要付费不同的应用对第三方集成的做法是不同的Facebook 和 ins 是不收费的只要开发人员进行对接就可以而 WhatsApp business api 则是付费的每一个房间都需要收取一定的费用。这个时候就需要测试扣费的逻辑是否正常。而这里是有两段逻辑要测试的对用户的收费和对第三方应用的付费。第三方应用的付费可能会简单一些只要 API 的对接正常通常不会有扣错费的情况。而在对用户的收费上则需要多注意一些。要避免多扣费/漏扣费的情况还要注意用户如果没有付费界面对用户的引导以及接口层面的限制。其他的还有续费、退费等情况则根据需求测试2、集成后消息的兼容就像刚才说的不同的聊天软件会有不同的消息格式集成的时候要考虑不同消息的兼容问题。例如 WhatsApp business api有一种叫模板的数据又比如 ins 的账单等等。在接收到这种数据的时候如果能显示要兼容格式如果无法显示也要做兜底的处理。除此之外就算是普通的文本也要考虑兼容的问题例如在 Email 中文本可能是被包在 html 中发送过来的那就不能把它当普通的文本进行处理而是要考虑 html 文本会有哪些问题。比较常见的问题是 html 样式的显示。还可以进一步的进行测试通常有 html 的地方都可能存在 xss 漏洞要考虑安全方面的问题。3、跟第三方的交互由于是跟第三方集成所以要考虑到第三方应用的一些功能和限制1、是否需要根据第三方渠道特殊兼容例如 WhatsApp business api在 C 端用户没有回复商家之前是无法发送自定义文本的只能发送模板消息那么跟 WhatsApp business api 集成时也要兼容这一点。又比如 Email让用户选择是否要拉取垃圾邮件2、消息频率的限制毕竟是调用第三方的 API那么 API 的调用频率通常都会存在限制在测试时可以考虑这一点。3、兜底逻辑例如消息如果由于 API 更新/API 错误的原因发送失败应该怎么兜底4、第三方渠道用户数据的获取比如基础的用户名、头像、签名等内容根据需求测试5、消息的同步与兼容不仅要考虑兼容第三方的数据格式。也要考虑第三方能否兼容自身应用系统的数据格式如果不能又该怎么处理要让第三方过来的消息能够正确显示在聊天系统中也要让聊天系统发出去的消息能够正常的显示在第三方应用中。聊天功能1、实时性发送的消息能否立马被收到能否通知到应该通知的人状态能否立马变化2、准确性发送人、接收人信息是否正确消息类型是否正确能否正常展示3、易用性各种快捷键enter 换行正在输入中的提示等功能4、安全性越权测试、DDOS 攻击、消息隐私5、性能测试发送庞大的数据包/大量请求进行压测查看是否满足性能压力6、兜底机制在断网等异常情况下websocket 连接可能会断开。在恢复正常后要自动重连并把发送失败的信息重新发送避免漏发的情况。不同聊天软件的侧重点前面有说到目前的聊天软件可以大致分为几种面向 C 端用户、面对 B 端商家、特殊场景G 端/内部通信系统。那么不同的聊天软件的侧重点也是会有所不同的。B端软件面向 B 端商家的聊天软件通常是客服系统。以客服系统为例一个账号需要支持多个客服同时在线操作。那么对于消息之间的协作以及性能是有很高的要求的。1、在操作一个会话后需要快速通知到其他的客服账号在回复了用户后也需要快速的显示出会话。避免出现同一时间有多个人介入会话的情况。2、权限的管理比较严格由于有多个客服那么客服之间的权限管理就比较复杂需要通过多个角色来区分权限或者单独设计权限系统。既要考虑横向越权又要考虑纵向越权的问题。3、消息格式的兼容B 端的系统通常都需要兼容各种第三方渠道的数据除了消息格式还需要考虑授权的问题系统的处理会很复杂。4、B 端的软件的目的是解决问题提高效率。追求稳定、高效以工作协作、业务需求为核心。需要考虑一个功能有多个人同时参与使用之类的边界情况。在测试需求时可以想象自己如果是客服或者工作人员会不会满意对功能的使用能否帮自己解决问题。5、B 端软件的盈利通常是依靠用户进行订阅在订阅套餐的基础上进行其他的增值收费例如会话的额度又比如针对不同数量的客席需要额外进行不同的收费又或者某个高级功能需要单独订阅收费6、通常搭配有工作流、FAQ、AI 修正/AI 写稿等提升效率的功能对数据的保存看的较重不能接收数据的丢失或者错乱代表产品企业微信、钉钉、slack目标客户通常都是团队/企业C端软件1、由于面向 C 端用户的聊天软件通常是一人一号因此在越权问题上不用像 B 端软件那么复杂。只需要保证自己的信息不会被别的账号的人看到就好通常只关注横向越权的问题。2、由于是一人一号对于消息的协作也没有那么高的要求不像 B 端在操作信息后需要马上同步给其他的客服成员。C 端只要保证用户一个人的使用体验即可。3、对消息格式的兼容比较少一般是通过内嵌 url 的形式调用外部应用例如发邮件。又或者只是打开其他 app 的跳转链接不会像 B 端的软件需要直接兼容消息的收发4、C 端的软件的核心一般都是围绕社交、娱乐展开除此之外像微信这类有海量用户的软件会和生活挂上钩。在测试时需要更注重用户的使用体验看能不能给用户带来情绪上的价值能否帮用户解决社交需求。5、C 端软件的盈利模式要根据场景来区分一部分的软件是不直接对用户进行收费的例如微信。一般不直接对用户收费的产品盈利会放在广告、虚拟产品QQ 秀等像微信甚至依靠庞大的用户流量通过小程序/小游戏来盈利。让企业和用户双赢。而直接对用户进行收费的可能会通过订阅增值服务或者会员制6、通常搭配朋友圈、个人主页、好友推荐、群聊、好友/群搜索等社交属性较重的功能。能够容忍部分不重要的消息丢失。代表产品微信、Ins、Soul、陌陌目标客户通常都是个人