{"ObjectType":101,"Sequence":11,"PreHash":"F5CA8A3D915C4407ACF527AFA0AF5973","Content":"前几篇介绍了使用区块链技术设计非中心型的【公告】、【私聊】业务消息\n本篇开始介绍非中心型的【群聊】业务\n\n什么?非中心型的【群聊】?\n没有中心,用户如何建群、加入、踢人,消息如何同步?\n其实并没有那么难,无非就是根据需要多设计几条业务消息而已。\n\n1、要创建群/解散群,其实就是声明一个群的唯一标识。\n创建群/解散群消息(【群管理消息】GroupManage的一种,【群管理消息】全部由群主签发)\n{\n\"ObjectType\":301, //由于该消息没有特定发送对象,所以没有Action、To属性,而实ObjectType属性,301为GroupManage消息\n\"GroupHash\":, //随机生成的哈希值\n\"Sequence\":, \n\"PreHash\":,\n\"GroupManageAction\":1/0, //1为创建群组,0为解散群\n\"Request\":{}, //创建群/解散群不需要申请,在处理申请、踢人时会用到\n\"Timestamp\":,\n\"PublicKey\":, //从PublicKey可以算出群主账号GroupFounderAccount\n\"Signature\":\n}\n\n该消息设定了群组的唯一标识二元组(GroupFounderAccount,GroupHash)\n\n2、要加入/离开群,需要加入/离开【申请消息】GroupRequest\n{\n\"Action\":401, //这是一条群【申请消息】\n\"GroupHash\":, //唯一标识二元组的第二元\n\"GroupManageAction\":1/2, //1是加入,2是离开\n\"To\":, //唯一标识二元组的第一元,群主的账号\n\"Timestamp\":,\n\"PublicKey\":,\n\"Signature\":\n}\n\n3、对于加入申请需要群主手动确认,生成确认允许加入【群管理消息】,拒绝加入申请无需任何操作\n对于离开申请群主客户端自动生成确认(允许)离开【群管理消息】,离开申请无法被拒绝\n同时需要引用【申请消息】\n{\n\"ObjectType\":301, //301为GroupManage消息\n\"GroupHash\":, //唯一标识二元组的第二元\n\"Sequence\":, \n\"PreHash\":,\n\"GroupManageAction\":2/4, //2为允许加入,4为允许离开\n\"Request\":, //引用允许的【申请消息】\n\"Timestamp\":,\n\"PublicKey\":,\n\"Signature\":\n}\n\n4、踢人(将账号【X】从群中移除),生成踢人【群管理消息】\n{\n\"ObjectType\":301, //301为GroupManage消息\n\"GroupHash\":, //唯一标识二元组的第二元\n\"Sequence\":, \n\"PreHash\":,\n\"GroupManageAction\":2/4, //2为允许加入,4为允许离开\n\"Request\":{\"Address\":【X】}, //踢掉【X】\n\"Timestamp\":,\n\"PublicKey\":,\n\"Signature\":\n}\n\n现在群主可以创建/解散群(生成301的【群管理消息】),接收加入和离开申请,并手动允许的加入和自动批准的离开(生成301的【群管理消息】),踢人(生成301的【群管理消息】)。\n【群管理消息】全部由群主签发,形成一条【单链】。\n群成员上线后需同步【群管理消息】消息,向群主或其他群成员,然后在本地维护群成员列表。\n【群管理单链同步消息】GroupManageSync\n{\n\"Action\":402, //这是一条【群管理单链同步消息】\n\"GroupHash\":, //唯一标识二元组的第二元\n\"CurrentSequence\":, //本地【群管理单链】最大序号\n\"To\":, //群成员账号\n\"Timestamp\":,\n\"PublicKey\":,\n\"Signature\":\n}\n\n至此,在非固定中心环境(服务器不存储业务数据)下,利用区块链完成了群管理(维护可信可校验的群成员列表)的设计。\n现在群有了,如何聊天,如何同步聊天消息?\n群聊与私聊在消息上的区别是:群聊消息的接收对象是群成员(多个),而私聊消息的接收对象是确定的1个账号。\n向多个账号发送的消息,同时还要保持机密性,导致其在发出之前不能是密文。\n【群聊消息】GroupMessage\n{\n\"GroupHash\":, //唯一标识二元组的第二元\n\"Sequence\":,\n\"PreHash\":,\n\"Confirm\":{}, //三元组(\"Address\", \"Sequence\", \"Hash\"),用于确认本地已经收到的最新一条群消息\n\"Content\":, //明文!\n\"Timestamp\":,\n\"PublicKey\":,\n\"Signature\":\n}\n\n生成【群聊消息】后,通过服务器中继,所有群成员发送,使用【对象消息】。\n{\n\"Action\":101, //表明这条消息是反馈1个对象\n\"Object\":,\n\"To\":,\n\"Timestamp\":,\n\"PublicKey\":,\n\"Signature\":\n}\n\n其中Object为:\n{\n\"ObjectType\":302, //表明对象是一个【群聊消息】\n\"GroupHash\":,\n\"PublicKey\":,\n\"Message\": 加密【群聊消息 - GroupHash - PublicKey】\n}\n\n群聊与私聊的消息加密方式雷同,任意两个群成员进行DH握手协商出对称加密密钥。\n不同之处是暂定,一个群组的两个成员使用的对称加密密钥永久有效,未设计对称加密密钥更新机制。\n\n【群聊消息】与【群管理消息】、【公告】的同步方式雷同,这里就不赘述了。\n\n群组聊天总共用到了3个消息范式:\n\"GroupRequest\": 401\n\"GroupManageSync\": 402\n\"GroupDH\": 403\n\"GroupMessageSync\": 404\n\n2个对象:\n\"GroupManage\": 301\n\"GroupMessage\": 302","Timestamp":1601911000624,"PublicKey":"0216B8875FE7513978CF2167C7AB7A3A6BC1F95E7DE20498980CACB70E51EA207A","Signature":"30440220103F636DB96BA9FDA2B7C9A61EDE7BF17F7FEC1CB49214806B17960B2D29D18C02203E0C2466626CC9C77CAF7CA1892CA5D79237FC0E51D4F5D26233C6854750A450"}
oxo