聊天系统设计

本文探讨游戏聊天系统的特殊性及核心需求,如消息分发、历史记录保存等,并提出针对世界聊天场景下的带宽优化方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

聊点啥天

提到聊天,我们会联想到QQ,微信,那么游戏中的聊天系统和它们有什么不同?本质上其实是一样的,都是分发聊天消息。很简单嘛,对每个需要通知到的玩家,挨个发消息不就得了。

核心业务需求

收到策划的通知,我们游戏要加个聊天功能,需求很简单,明天就要,应该没问题吧?

  1. 支持玩家与玩家私聊 保存所有历史记录
  2. 支持队伍内聊天 队伍未解散前保留所有历史记录
  3. 支持公会内聊天 保留最新的100条发言
  4. 支持世界聊天 百万在线级别
  5. 支持频道世界聊天 每个频道限制人数2k,支持999个频道
  6. 敏感词过滤
  7. 广告过滤
  8. 玩家举报功能,后台支持查看玩家被举报次数,实施举报行为玩家信息,防止恶意举报
  9. 后台支持玩家历史发言记录查询
  10. 后台支持禁言操作
  11. 支持查看游戏道具链接
  12. 支持在聊天界面选中查看其他发言玩家主要信息

好家伙,我就聊个天,搞这么多需求是要闹哪样?
作为一个业务实力过硬的后端程序员,我们不能慌,将需求逐一分析,总结归纳。

  • 我们总结出核心需求: 发消息。我们可以把队伍,工会,世界也看做一个一个的频道,相应的玩家订阅合适的频道,根据订阅者逐一发消息。对应观察者模式。
  • 世界聊天比较特殊,百万在线玩家全部转发消息,对于带宽压力很大,先做一个估算,通过设置聊天冷却,平均每秒有0.1%的玩家发世界聊天消息,每条消息平均100字节,广播放大1000000倍,那就是800Gb带宽。(⊙o⊙)…这么多带宽,得多少钱?一台机器200Mb带宽,需要4000台!!!太贵了,不行,我得想想办法,把带宽降下来。办法1: 世界聊天成本这么高,可以通过消耗道具或者加大聊天冷却的方式,降低平均消息频率,降到0.01%,平均每秒控制在100条左右。办法2: 聊天消息集中在一起时,可以通过合并消息->压缩 来降低包体的体积,把每秒收集的100条消息合并压缩后变成一条消息,压缩率平均为50%,那么这一条消息大小为5KB,广播放大后为40Gb带宽,需要200台机器。哈哈,一下子省了20倍。办法3: 在线玩家数量也不是一下子到100万,可以灵活伸缩,10万在线时,需要带宽为400Mb,只需要2台机器就够了,在线数量往上涨后,自动扩容用于聊天的服务器。
  • 敏感词过滤,广告过滤,道具链接等等都可以归纳为对聊天文本的处理,而且处理一次即可
  • 后台需要支持一些聊天的功能,我们需要存储数据并预留接口。禁言功能需要预留禁言接口,查询历史发言记录,需要将玩家的发言都记录下来。举报相关信息也要记下来。这些记录都是存储一次,可被查询多次。
  • 玩家对其他玩家的发言可以查看 道具,查看玩家基本信息等功能。这些基本信息都可以存储到缓存中,设置一个合理的过期时间。
  • 玩家的私聊可以直接存储到个人聊天的表记录中。

归纳完毕之后,是不是没有那么复杂了呢?后台的功能我们可以先放一放,先实现优先级更高的消息分发,消息订阅。找策划沟通世界聊天的成本问题。

具体的实现因为不同类型的后端框架也不一样,就不详细展开了。

说点别的

我认为游戏中的聊天有一些特殊性。首先它自带游戏话题属性,游戏中总是有的聊,队伍聊天自带组队下副本话题,工会聊天自带工会事务话题;然后,很多聊天都是临时性的,在游戏玩法结束后失效;其次,游戏中聊天玩家都是以游戏虚拟身份进行,除了某些重度社交游戏,大部分都是代入虚拟身份;再其次,聊天也是游戏官方给所有玩家发消息的单向通道,比如很多游戏都有的跑马灯公告。最后,游戏要展示其核心功能,聊天作为非核心功能,占据的屏幕尺寸会受到限制,和纯聊天软件相比,并不是特别友好。因此很多玩家都会在游戏之外,QQ微信上创建自己的游戏群,方便更多的交流,作为游戏聊天的补充。

摘 要 随着互联网的快速发展,网络聊天工具已经作为一种重要的信息交流工具,受到越来越多的网民的青睐。目前,出现了很多非常不错的聊天工具,其中应用比较广泛的有Netmeeting、腾讯QQ、MSN-Messager等等。该系统开发主要包括一个网络聊天服务器程序和一个网络聊天客户程序两个方面。前者通过Socket套接字建立服务器,服务器能读取、转发客户端发来信息,并能刷新用户列表。后者通过与服务器建立连接,来进行客户端与客户端的信息交流。其中用到了局域网通信机制的原理,通过直接继承Thread类来建立多线程。开发中利用了计算机网络编程的基本理论知识,如TCP/IP协议、客户端/服务器端模式(Client/Server模式)、网络编程的设计方法等。在网络编程中对信息的读取、发送,是利用流来实现信息的交换,其中介绍了对实现一个系统的信息流的分析,包含了一些基本的软件工程的方法。经过分析这些情况,该局域网聊天工具采用Eclipse为基本开发环境和java语言进行编写,首先可在短时间内建立系统应用原型,然后,对初始原型系统进行不断修正和改进,直到形成可行系统 关键词:局域网 聊天 socket java 聊天系统各功能模块 (1)服务器程序模块 服务器与客户间通过套接口Socket(TCP)连接。在java中使用套接口相当简单,Java API为处理套接口的通信提供了一个类java.net.Socket,使得编写网络应用程序相对容易。服务器采用多线程以满足多用户的请求,并通过创建一个ServerSocket对象来监听来自客户的连接请求,默认端口为9527,然后无限循环调用accept()方法接受客户程序的连接。 服务器线程源码: package qq.server; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.Socket; import java.util.*; import qq.dao.hibernate.IServiceDao; import qq.entity.*; public class ServerController { private User user; private Socket s; private IServiceDao dao; private ObjectInputStream ois; private ObjectOutputStream oos; private OnlineUser onlineUser; www.bylw120.com public ServerController(Socket s) { super(); dao=ServerMainClass.userDao; this.s = s; } public void handle() throws Exception { ois=new ObjectInputStream(s.getInputStream()); oos=new ObjectOutputStream(s.getOutputStream()); onlineUser=new OnlineUser(ois,oos); while(true){ Request req=(Request)ois.readObject(); ois.read(); RequestType type=req.getType(); if(type.equals(RequestType.exit)){ exitHandle(); break; }else if(type.equals(RequestType.login)){ loginHandle(req); }else if(type.equals(RequestType.register)){ registerHandle(); }else if(type.equals(RequestType.offline)){ offlineHandle(); break; }else if(type.equals(RequestType.changeInformation)){ changeInformationHandle(); }else if(type.equals(RequestType.modifypasswd)){ modifypasswdHandle(req); }else if(type.equals(RequestType.sendMessage)){ sendMessageHandle(req); }else if(type.equals(RequestType.receiveFile)){ receiveFileHandle(req); }else if(type.equals(RequestType.sendFile)){ sendFileHandle(req); } } } private void modifypasswdHandle(Request req) { Long id=Long.parseLong(req.getData("id")); String oldpwd=req.getData("oldpwd"); String newpwd=req.getData("newpwd"); Response res=new Response(RequestType.modifypasswd); try { dao.updatePwd(id, oldpwd, newpwd); res.setData(1); try { oos.writeObject(res); } catch (IOException e) { e.printStackTrace(); } } catch (RuntimeException e) { try { oos.writeObject(res); } catch (IOException e1) { e1.printStackTrace(); } } } private void changeInformationHandle() { try { User user=(User)ois.readObject(); Response res=new Response(RequestType.changeInformation); try { dao.updateUser(user); res.setData(1);//修改成功返回值带一个整形值 oos.writeObject(res); oos.flush(); } catch (RuntimeException e) { oos.writeObject(res);//失败则返回值不带参数 oos.flush(); e.printStackTrace(); } } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } private void exitHandle() { try { s.close(); } catch (IOException e) { e.printStackTrace(); } } //发送文件 private void sendFileHandle(Request req) { // try { // User u=(User)ois.readObject(); // // } catch (Exception e) { // e.printStackTrace(); // } } //接受文件 private void receiveFileHandle(Request req) {
一个用于Web游戏中的即时聊天代码 使用内存进行消息投递 支持私聊和供聊 支持统计在线人数 可开多个房间 注意:有人反映这个不能直接使用,在这里特做一下说明 =============================================== 这个程序是从游戏中拿出来的,并不是一个独立的应用程序 发上去的部分是不能直接运行的,发出来的目的只是想给有这方面兴趣的朋友做个参考,因为我自己才做这块的时候确实走了不少弯路 里面有类设计图,类设计图是用powerdesign 12.5设计的 可以通过类设计图看服务端的设计 客户端是一个demo html文件 要运行还需要配数据库,还需要微软的企业库开发包 不了解企业库的可以去这里看看 http://www.codeplex.com/entlib 你也可以修改一下代码让程序不需要访问数据库 访问数据库主要是加载房间信息,你可以在代码里弄几个模拟的房间信息 聊天消息的中专是不依赖数据库的 ====================================== 再次补充说明 这个代码的开发环境为:vs2008+sqlserver2005+微软企业库+net fwk3.5 其实用vs2005+2.0框架也可以,虽然使用的是3.5的框架,但是并没有使用3.5框架的新特性 经检查发现里面确实没有类设计图,也没有服务器端的源代码 现在传上去的这部分只是一个demo,包含客户端和编译过的服务器端代码 非常的抱歉,我将不上源代码和相关设计文件 =========================================================== 目录结构说明 ChatDemo-包含客户端和编译过的服务器端 ChatDemo/ChatDemo.HttpHandler-客户端http处理器(客户端和服务器端的交互就靠这些文件了) ChatDemo/ChatWebDemo-客户端的实现代码 ChatDemo/ChatWebDemo/ServerManager.aspx-此文件可控制服务器的启动和关闭(客户端和服务器端是存在于同一台电脑上测试的,所以在一个工程里) ChatDemo/ChatWebDemo/SelectChatRoom.aspx-可选择进入哪一个聊天室 ChatDemo/ChatWebDemo/Chat.aspx-聊天客户端界面 DinosaurEmpery-包含服务器端的源代码和相关设计文档-数据库文档等 DinosaurEmpery/src-服务端源代码和单元测试相关资料 DinosaurEmpery/src/Chat DinosaurEmpery/src/IChat 这两个才是聊天部分的代码,其它目录为游戏其它部分的代码(只是部分代码,是不能运行的) DinosaurEmpery/using-程序中用引用到到第3方dll(微软企业库)(由于压缩后的结果代码太大,所以删除了里面的内容)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值