缓存的公告

Bulletin#ADFA980C0575E0A217CC799948637A93

o5rdqyAP36HG6HTCHbiTNh1GJ7kvKk4Z5m #11

发布@2020-10-05 18:16:40

上一篇


前几篇介绍了使用区块链技术设计非中心型的【公告】、【私聊】业务消息
本篇开始介绍非中心型的【群聊】业务

什么?非中心型的【群聊】?
没有中心,用户如何建群、加入、踢人,消息如何同步?
其实并没有那么难,无非就是根据需要多设计几条业务消息而已。

1、要创建群/解散群,其实就是声明一个群的唯一标识。
创建群/解散群消息(【群管理消息】GroupManage的一种,【群管理消息】全部由群主签发)
{
"ObjectType":301, //由于该消息没有特定发送对象,所以没有Action、To属性,而实ObjectType属性,301为GroupManage消息
"GroupHash":, //随机生成的哈希值
"Sequence":,
"PreHash":,
"GroupManageAction":1/0, //1为创建群组,0为解散群
"Request":{}, //创建群/解散群不需要申请,在处理申请、踢人时会用到
"Timestamp":,
"PublicKey":, //从PublicKey可以算出群主账号GroupFounderAccount
"Signature":
}

该消息设定了群组的唯一标识二元组(GroupFounderAccount,GroupHash)

2、要加入/离开群,需要加入/离开【申请消息】GroupRequest
{
"Action":401, //这是一条群【申请消息】
"GroupHash":, //唯一标识二元组的第二元
"GroupManageAction":1/2, //1是加入,2是离开
"To":, //唯一标识二元组的第一元,群主的账号
"Timestamp":,
"PublicKey":,
"Signature":
}

3、对于加入申请需要群主手动确认,生成确认允许加入【群管理消息】,拒绝加入申请无需任何操作
对于离开申请群主客户端自动生成确认(允许)离开【群管理消息】,离开申请无法被拒绝
同时需要引用【申请消息】
{
"ObjectType":301, //301为GroupManage消息
"GroupHash":, //唯一标识二元组的第二元
"Sequence":,
"PreHash":,
"GroupManageAction":2/4, //2为允许加入,4为允许离开
"Request":, //引用允许的【申请消息】
"Timestamp":,
"PublicKey":,
"Signature":
}

4、踢人(将账号【X】从群中移除),生成踢人【群管理消息】
{
"ObjectType":301, //301为GroupManage消息
"GroupHash":, //唯一标识二元组的第二元
"Sequence":,
"PreHash":,
"GroupManageAction":2/4, //2为允许加入,4为允许离开
"Request":{"Address":【X】}, //踢掉【X】
"Timestamp":,
"PublicKey":,
"Signature":
}

现在群主可以创建/解散群(生成301的【群管理消息】),接收加入和离开申请,并手动允许的加入和自动批准的离开(生成301的【群管理消息】),踢人(生成301的【群管理消息】)。
【群管理消息】全部由群主签发,形成一条【单链】。
群成员上线后需同步【群管理消息】消息,向群主或其他群成员,然后在本地维护群成员列表。
【群管理单链同步消息】GroupManageSync
{
"Action":402, //这是一条【群管理单链同步消息】
"GroupHash":, //唯一标识二元组的第二元
"CurrentSequence":, //本地【群管理单链】最大序号
"To":, //群成员账号
"Timestamp":,
"PublicKey":,
"Signature":
}

至此,在非固定中心环境(服务器不存储业务数据)下,利用区块链完成了群管理(维护可信可校验的群成员列表)的设计。
现在群有了,如何聊天,如何同步聊天消息?
群聊与私聊在消息上的区别是:群聊消息的接收对象是群成员(多个),而私聊消息的接收对象是确定的1个账号。
向多个账号发送的消息,同时还要保持机密性,导致其在发出之前不能是密文。
【群聊消息】GroupMessage
{
"GroupHash":, //唯一标识二元组的第二元
"Sequence":,
"PreHash":,
"Confirm":{}, //三元组("Address", "Sequence", "Hash"),用于确认本地已经收到的最新一条群消息
"Content":, //明文!
"Timestamp":,
"PublicKey":,
"Signature":
}

生成【群聊消息】后,通过服务器中继,所有群成员发送,使用【对象消息】。
{
"Action":101, //表明这条消息是反馈1个对象
"Object":,
"To":,
"Timestamp":,
"PublicKey":,
"Signature":
}

其中Object为:
{
"ObjectType":302, //表明对象是一个【群聊消息】
"GroupHash":,
"PublicKey":,
"Message": 加密【群聊消息 - GroupHash - PublicKey】
}

群聊与私聊的消息加密方式雷同,任意两个群成员进行DH握手协商出对称加密密钥。
不同之处是暂定,一个群组的两个成员使用的对称加密密钥永久有效,未设计对称加密密钥更新机制。

【群聊消息】与【群管理消息】、【公告】的同步方式雷同,这里就不赘述了。

群组聊天总共用到了3个消息范式:
"GroupRequest": 401
"GroupManageSync": 402
"GroupDH": 403
"GroupMessageSync": 404

2个对象:
"GroupManage": 301
"GroupMessage": 302