我正在尝试使用Qt5开发自己的简单聊天应用。
某些情境
我到目前为止所拥有的是一个简单的服务器,它将接收来自用户(使用相应客户端)的任何消息并将它们存储在数据库中,同时还有从,到和 iseRead 字段。
然后客户经常要求服务器更新消息(我知道这可能不是一个好主意,但我不知道如何找到谁在线使用Qt所以请忽略它)并接收那些意味着的消息对他们来说
我现在要做的是为用户增加一种能力,使其无需从列表中专门选择其他人来发送信息,而是向所有人广播。将 ALL 值添加到到列将无济于事,因为我不知道何时标记该消息的 isRead 字段,此结果为用户在每次客户请求时不断收到它。
如果我想添加向一群人发送消息的能力,事情也变得更加复杂。
真实问题
如何构建我的服务器端数据库以有效地存储和检索我上面描述的用户事务(向个人发送消息,向所有人发送消息,向群组广播等)?
答案 0 :(得分:2)
我会做这样的事情,从头到尾。
Users Table
unique_user_id, user_specific_info1, user_specific_info2, so on..
Messages Table
message, target_user_id, sender_id, message_status
现在我甚至不打算在数据库中存储会话或分组消息等等。这是无缘无故的额外开销。拥有最小的服务器端代码,允许用户在聊天中添加彼此,并让客户端软件处理被邀请进入房间的人。然后让客户端发送带有相关数据的消息:target_user_ids,消息,发件人ID。
在服务器端逻辑中,获取消息,解析目标user_ids,在每个目标user_id的messages表中创建一个新条目,并将状态设置为UNREAD,一旦服务器软件具有状态,将状态翻转为READ成功将消息数据传输到目标用户ID。
简单。这解决了您对群聊信息的所有问题,向绝对所有人广播等等。
<强>更新强>
现在显然你想要优化它。例如,您可能真的不希望将每条消息的数据复制并存储到广播中的每个用户,因此您可以在此创建一个独立的Messages
表来保存原始消息内容。一个自动递增的唯一索引,然后可能有另一个类似的消息状态表:
Messages Status Table
message_id, target_user_id, sender_id, message_status
现在,您可以让10000000人获得相同的消息,但您只存储对消息ID的引用10000000次,而不是整个消息数据。然后,您可以在服务器上运行一个cron作业,然后每天运行一次,或清除系统中状态为READ的所有消息,以避免膨胀。
答案 1 :(得分:1)
我认为您必须注册所有在线用户。也就是说,当客户端首次连接并进行身份验证时,您将向客户添加条目,例如,表格[pk,user_nick]的表格 online 。当客户离开时你会做的反向(从网上删除)。 然后,当从客户端发送ALL消息时,您检查 online 中的内容,并将 online 表中所有客户端缺刻的条目添加到您存储消息的表中[来自[来自] ,to,isRead]。
您的案例中的群组功能 - 添加表群组 [pk,id_group,nick]。您必须为客户端实现逻辑,以了解id_group标识的可能组。然后客户端会向id_group写一条消息,服务器会检查该组中的用户(选择..其中id_group = x)并将消息重复到您的消息表(带有from,to,isRead的那个)
你说你不知道如何找出谁在线 - 通常你实施一些登录机制 - 当客户第一次连接你存储他的IP,源端口或任何东西以识别他和他的昵称..这样你知道谁在线..当然你必须实现注销和可选的一些超时机制,如果客户端处于非活动状态然后将其注销。 通过这种方式,您将拥有一些打开的连接数组,当客户端A向客户端B写入消息时,您只需将消息代理到B ..这样就可以更容易地实现其他功能。
更新 - 添加示例
我会将逻辑从在线表格移动到新表格用户存储有关用户的详细信息并简化身份验证过程等。
聊天[pk,(fk)fromU,(fk)toU,isRead] #the fk =用户pk的外键
用户[pk,Nick,Logged]
组[pk,group_id,(fk)user_id] #little bit nasty,但很简单我们会重复group_id ..
我们在用户中有这个:
1,约翰,真的
2,伊娃,真的
3,Jana,真的
然后当Eva发送所有消息“hello”时,我们会在Chat表中添加三个条目:
54,2,1,“你好”
55,2,2,“你好”#这是可选的,这样Eva也可以看到她自己的聊天,有时候没问题,你不需要在你的应用程序中处理这个额外的...
56,2,3,“你好”
然后当John检查他会做的信息时: 从聊天中选择*到U = 1;
我们会非常类似地进行群组功能。