2.经典项目-海量用户即使通讯系统

1.实现功能-完成注册用户

完成用户注册的步骤(客户端)
1.将User移动到common/message文件夹下
2.在message中新增注册用户的结构体

const (LoginMesType       = "LoginMes"LoginResMesType    = "LoginResMes"RegisterMesType    = "RegisterMes"RegisterResMesType = "RegisterResMes"
)type RegisterMes struct {User User `json:"user"` //类型就是User机构体
}
type RegisterResMes struct {Code  int    `json:"code"`  //返回状态码 400表示该用户已存在 200表示注册成功Error string `json:"error"` //返回错误信息
}

3.在client/process/userProcess.go中添加注册函数


func (this *UserProcess) Register(userId int, userPwd, userName string) (err error) {conn, err := net.Dial("tcp", "localhost:8889")if err != nil {fmt.Println("net.Dial err = ", err)return}defer conn.Close()var mes = message.Message{}mes.Type = message.RegisterMesTyperegisterMes := message.RegisterMes{}registerMes.User.UserId = userIdregisterMes.User.UserPwd = userPwdregisterMes.User.UserName = userNamedata, err := json.Marshal(registerMes)if err != nil {fmt.Println("json.Marshal err = ", err)return}mes.Data = string(data)data, err = json.Marshal(mes)if err != nil {fmt.Println("json.Marshal err = ", err)return}tf := &utils.Transfer{Conn: conn,}err = tf.WritePkg(data)if err != nil {fmt.Println("注册发送信息错误 err = ", err)return}//处理服务器端返回的消息mes, err = tf.ReadPkg() //mes就是 RegisterResMesif err != nil {fmt.Println("utils.ReadPkg(conn) err = ", err)return}var registerResMes message.RegisterResMeserr = json.Unmarshal([]byte(mes.Data), &registerResMes)if registerResMes.Code == 200 {fmt.Println("注册成功,请重新登录")} else {fmt.Println(registerResMes.Error)}return
}

4.在client/main/main.go中修改注册相关代码

		case 2:fmt.Println("注册用户")fmt.Println("请输入用户id:")fmt.Scanf("%d\n", &userId)fmt.Println("请输入用户密码:")fmt.Scanf("%s\n", &userPwd)fmt.Println("请输入用户名称:")fmt.Scanf("%s", &userName)up := &process2.UserProcess{}up.Register(userId, userPwd, userName)

完成用户注册的步骤(服务器端)
1.在model/userDao.go中添加

func (this *UserDao) Register(user *message.User) (err error) {conn := this.pool.Get()defer conn.Close()_, err = this.getUserById(conn, user.UserId)if err == nil {err = ERROR_USER_EXISTSreturn}//账户不存在,则可以正常注册data, err := json.Marshal(user) //序列化if err != nil {return}//入库_, err = conn.Do("HSet", "users", user.UserId, string(data))if err != nil {fmt.Println("保存注册用户错误 err = ", err)return}return
}

2.在process/userProcess.go中添加

func (this *UserProcess) ServerProcessRegister(mes *message.Message) (err error) {var registerMes message.RegisterMeserr = json.Unmarshal([]byte(mes.Data), &registerMes)if err != nil {fmt.Println("json.Marshal err = ", err)return}var resMes message.MessageresMes.Type = message.RegisterResMesTypevar registerResMes message.RegisterResMeserr = model.MyUserDao.Register(&registerMes.User)if err != nil {if err == model.ERROR_USER_EXISTS {registerResMes.Code = 505registerResMes.Error = err.Error()} else {registerResMes.Code = 506registerResMes.Error = "注册发生未知错误"}} else {registerResMes.Code = 200fmt.Println("用户注册成功")}data, err := json.Marshal(registerResMes)if err != nil {fmt.Println("json.Marshal err = ", err)return}resMes.Data = string(data)data, err = json.Marshal(resMes)if err != nil {fmt.Println("json.Marshal err = ", err)return}// 发送data,将其封装到writePkg函数//因为使用分层模式(mvc)需要先创建一个Transfer实例,然后读取tf := &utils.Transfer{Conn: this.Conn,}err = tf.WritePkg(data)return
}

3.修改main/processor.go

func (this *Processor) ServerProcessMes(mes *message.Message) (err error) {switch mes.Type {case message.LoginMesType://处理登录//创建UserPorcess实例up := &process2.UserProcess{Conn: this.Conn,}err = up.ServerProcessLogin(mes)case message.RegisterMesType:up := &process2.UserProcess{Conn: this.Conn,}err = up.ServerProcessRegister(mes)default:fmt.Println("消息类型不存在,无法处理...")}return
}

2.实现功能-完成登录时能返回当前在线用户

1.在服务器端维护一个onlineUsers map[int] *UserProcess
2.创建一个新的文件userMgr.go,完成功能对onlineUsers的增删改查
3.在LoginResMess增加一个字段Users []int //保存在线用户id
4.当用户登录后可以显示当前在线用户列表

代码实现
新增server/process/userMgr.go

package processimport "fmt"// 因为UserMgr实例在服务器端有且仅有一个,在很多机房会用到
// 因此将其定义为全局变量
var (userMgr *UserMgr
)type UserMgr struct {onlineUsers map[int]*UserProcess
}// 完成对UserMgr初始化工作
func init() {userMgr = &UserMgr{onlineUsers: make(map[int]*UserProcess, 1024),}
}// 完成对onlineUsers添加
func (this *UserMgr) AddOnlineUser(up *UserProcess) {this.onlineUsers[up.UserId] = up
}// 删除
func (this *UserMgr) DelOnlineUser(userId int) {delete(this.onlineUsers, userId)
}// 返回当前所有在线用户
func (this *UserMgr) GetAllOnlineUser() map[int]*UserProcess {return this.onlineUsers
}// 根据id返回对应的值
func (this *UserMgr) GetOnlineUserById(userId int) (up *UserProcess, err error) {//从map取出一个值,带检测方式up, ok := this.onlineUsers[userId]if !ok { //说明,要找的用户当前不在线err = fmt.Errorf("用户%d 不在线", userId)return}return
}

修改server/process/userProcess.go

type UserProcess struct {Conn net.Conn//增加一个字段,表示该Conn是哪个用户UserId int
}
	} else {loginResMes.Code = 200//将登录成功的用户的userId赋给thisthis.UserId = loginMes.UserId//将登录成功的用户放入userMgr中userMgr.AddOnlineUser(this)//将当前在线用户的id放到loginResMes.UserIds中for id, _ := range userMgr.onlineUsers {loginResMes.UserIds = append(loginResMes.UserIds, id)}fmt.Println(user.UserName, "账户登录成功")

修改message.go

type LoginResMes struct {Code    int    `json:"code"`    //返回状态码 500 表示该用户未注册 200表示登录成功UserIds []int  `json:"userIds"` //增加字段保存userid的切片Error   string `json:"error"`   //返回错误信息
}

修改client/process/userProcess.go

	if loginResMes.Code == 200 {//可以显示当前在线用户列表fmt.Println("当前在线用户列表如下:")for _, v := range loginResMes.UserIds {//不显示自己if v == userId {continue}fmt.Println("用户id:\t", v)}fmt.Print("\n\n")

优化:当一个新的用户上线后,其他已经登录的用户也能获取最新在线用户列表
思路:

  1. 当用户A上线,服务器九八A用户的上线信息推给所有在线的用户
  2. 客户端也需要维护一个map,map中记录了他的好友(目前就是所有人)map[int]User
  3. 客户端和服务器的通讯通道,要依赖serverProcessMes协程

代码实现
在message.go中增加

const (LoginMesType            = "LoginMes"LoginResMesType         = "LoginResMes"RegisterMesType         = "RegisterMes"RegisterResMesType      = "RegisterResMes"NotifyUserStatusMesType = "NotifyUserStatusMes"
)// 定义几个用户状态常量
const (UserOnline = iotaUserOfflineUserBusyStatus
)// 为了配合服务器端推送用户状态变化的消息
type NotifyUserStatusMes struct {UserId int `json:"userId"` //用户idStatus int `json:"status"` //用户状态
}

修改user.go

// 定义一个用户的结构体
type User struct {//确定字段信息//为了序列化和反序列化成功,需保证用户信息的json字符串的key 和结构体的字段对应的tag名字一致UserId     int    `json:"userId"`UserPwd    string `json:"userPwd"`UserName   string `json:"userName"`UserStatus int    `json:"userStatus"` //用户在线状态
}

修改server/process/userProcess.go

	} else {loginResMes.Code = 200//将登录成功的用户的userId赋给thisthis.UserId = loginMes.UserId//将登录成功的用户放入userMgr中userMgr.AddOnlineUser(this)//通知其他在线用户this.NotifyOtherOnlineUser(this.UserId)//将当前在线用户的id放到loginResMes.UserIds中for id, _ := range userMgr.onlineUsers {loginResMes.UserIds = append(loginResMes.UserIds, id)}fmt.Println(user.UserName, "账户登录成功")}

在server/process/userProcess.go中增加

// 编写通知所有在线的用户的方法
func (this *UserProcess) NotifyOtherOnlineUser(userId int) {//遍历onlineUsers 然后一个个发送NotifyUserStatusMesfor id, up := range userMgr.onlineUsers {//过滤自己if id == userId {continue}up.NotifyMeOnline(userId)}
}func (this *UserProcess) NotifyMeOnline(userId int) {//组装我们的NotifyUserStatusMesvar mes message.Messagemes.Type = message.NotifyUserStatusMesTypevar notifyUserStatusMes message.NotifyUserStatusMesnotifyUserStatusMes.UserId = userIdnotifyUserStatusMes.Status = message.UserOnline//将notifyUserStatusMes序列化data, err := json.Marshal(notifyUserStatusMes)if err != nil {fmt.Println("json.Marshal err = ", err)return}//将序列化后的notifyUserStatusMes复制给mes.Datames.Data = string(data)//对mes再次序列化,准备发送data, err = json.Marshal(mes)if err != nil {fmt.Println("json.Marshal err = ", err)return}//发送,Transfer实例tf := &utils.Transfer{Conn: this.Conn,}err = tf.WritePkg(data)if err != nil {fmt.Println("NotifyMeOnline err = ", err)return}
}

修改client/process/server.go

		case 1:fmt.Println("显示在线用户列表")outpuOnlineUser()
// 和服务器保持通讯
func serverProcessMes(Conn net.Conn) {//创建一个Transfer实例,不停地读取服务器发送的消息tf := &utils.Transfer{Conn: Conn,}for {fmt.Println("客户端正在等待读取服务器发送的消息")mes, err := tf.ReadPkg()if err != nil {fmt.Println("tf.ReadPkg err = ", err)return}//如果读到消息,进入下一步处理逻辑switch mes.Type {case message.NotifyUserStatusMesType: //有人上线//处理//1. 取出NotifyUserStatusMesvar notifyUserStatusMes message.NotifyUserStatusMesjson.Unmarshal([]byte(mes.Data), &notifyUserStatusMes)//2. 把这个用户信息,状态保存到客户map[int]User中updateUserStatus(&notifyUserStatusMes)default:fmt.Println("服务器端返回了未知的消息类型")}//fmt.Printf("mes = %v\n", mes)}
}

新增client/process/userMgt.go

package processimport ("fmt""project/common/message"
)// 客户端维护的map
var onlineUsers map[int]*message.User = make(map[int]*message.User, 10)// 在客户端显示当前在线的用户
func outpuOnlineUser() {//遍历onlilneUsersfmt.Println("当前在线用户列表:")for id, _ := range onlineUsers {fmt.Println("用户id:\t", id)}
}// 编写一个方法,处理返回的NotifyUserStatusMes
func updateUserStatus(notifyUserStatusMes *message.NotifyUserStatusMes) {user, ok := onlineUsers[notifyUserStatusMes.UserId]if !ok {user = &message.User{UserId: notifyUserStatusMes.UserId,}}user.UserStatus = notifyUserStatusMes.StatusonlineUsers[notifyUserStatusMes.UserId] = useroutpuOnlineUser()
}

修改client/process/userProcess.go

	if loginResMes.Code == 200 {//可以显示当前在线用户列表fmt.Println("当前在线用户列表如下:")for _, v := range loginResMes.UserIds {//不显示自己if v == userId {continue}fmt.Println("用户id:\t", v)//完成客户端的onlineUsers初始化user := &message.User{UserId:     v,UserStatus: message.UserOnline,}onlineUsers[v] = user}fmt.Print("\n\n")

3.实现功能-完成登录用户群聊

3.1 完成客户端发送消息

思路
1.新增一个消息结构体smsMes…
2.新增一个model/CurUser
3.在smsProcess.go增加相应的方法SendGroupMes发送一个群聊消息

代码实现
在message中新增

const (LoginMesType            = "LoginMes"LoginResMesType         = "LoginResMes"RegisterMesType         = "RegisterMes"RegisterResMesType      = "RegisterResMes"NotifyUserStatusMesType = "NotifyUserStatusMes"SmsMesType              = "SmsMes"
)// 增加一个SmsMes发送消息
type SmsMes struct {Content string `json:"content"` //消息内容User           //匿名结构体,集继承
}

新增client/model/curUser.go

package modelimport ("net""project/common/message"
)// 在客户端很多地方要用到,需声明为全局
type CurUser struct {Conn net.Connmessage.User
}

在client/process/userMgr.go中新增

var CurUser model.CurUser //在用户登录成功后,完成对CurUser初始化

在client/process/userProcess.go修改

	if loginResMes.Code == 200 {//初始化CurUserCurUser.Conn = connCurUser.UserId = userIdCurUser.UserStatus = message.UserOnline

在client/process/smsProcess.go新增

package processimport ("encoding/json""fmt""project/common/message""project/common/utils"
)type SmsProcess struct {
}// 发送群聊消息
func (this *SmsProcess) SendGroupMes(content string) (err error) {//1.创建一个Mesvar mes message.Messagemes.Type = message.SmsMesType//2.创建一个SmsMes实例var smsMes message.SmsMessmsMes.Content = contentsmsMes.UserId = CurUser.UserIdsmsMes.UserStatus = CurUser.UserStatus//3.序列化smsMesdata, err := json.Marshal(smsMes)if err != nil {fmt.Println("SendGroupMes json.Marshal err = ", err.Error())return}mes.Data = string(data)//4.对mes再次序列化data, err = json.Marshal(mes)if err != nil {fmt.Println("SendGroupMes json.Marshal err = ", err.Error())return}//5.将mes发送给服务器tf := &utils.Transfer{Conn: CurUser.Conn,}//6.发送err = tf.WritePkg(data)if err != nil {fmt.Println("sendGroupMes err = ", err.Error())return}return
}

修改client/process/server.go

		var key intvar content string//用到SmsProcess实例较为频繁,因此定义在外部smsProcess := &SmsProcess{}fmt.Scanf("%d\n", &key)switch key {case 1:fmt.Println("显示在线用户列表")outpuOnlineUser()case 2:fmt.Println("你想对大家说什么:")fmt.Scanf("%s\n", &content)smsProcess.SendGroupMes(content)
3.2 服务器接收群发消息,并发送消息(发送者除外)

思路
1.在服务器端接收到SmsMes消息
2.在server/process/smsProcess.go文件增加群发消息的方法
3.在客户端还要增加去处理服务器转发的群发消息

代码实现
在server/process/smsProcess.go中添加

package processimport ("encoding/json""fmt""net""project/common/message""project/common/utils"
)type SmsProcess struct {
}func (this *SmsProcess) SendGroupMes(mes *message.Message) {var smsMes message.SmsMeserr := json.Unmarshal([]byte(mes.Data), &smsMes)if err != nil {fmt.Println("json.Unmarshal err = ", err)return}data, err := json.Marshal(mes)if err != nil {fmt.Println("json.Marshal err = ", err)return}for id, up := range userMgr.onlineUsers {//过滤自己if id == smsMes.UserId {continue}this.SendMesToEachOnlineUser(data, up.Conn)}}func (this *SmsProcess) SendMesToEachOnlineUser(data []byte, conn net.Conn) {tf := &utils.Transfer{Conn: conn,}err := tf.WritePkg(data)if err != nil {fmt.Println("群发消息失败")return}
}

修改server/main/processor.go

func (this *Processor) ServerProcessMes(mes *message.Message) (err error) {switch mes.Type {case message.LoginMesType://处理登录//创建UserPorcess实例up := &process2.UserProcess{Conn: this.Conn,}err = up.ServerProcessLogin(mes)case message.RegisterMesType:up := &process2.UserProcess{Conn: this.Conn,}err = up.ServerProcessRegister(mes)case message.SmsMesType:smsProcess := &process2.SmsProcess{}smsProcess.SendGroupMes(mes)default:fmt.Println("消息类型不存在,无法处理...")}return
}

新增client/process/smsMgr.go

package processimport ("encoding/json""fmt""project/common/message"
)func outputGroupMes(mes *message.Message) {var smsMes message.SmsMeserr := json.Unmarshal([]byte(mes.Data), &smsMes)if err != nil {fmt.Println("json.Unmarshal err = ", err.Error())return}//显示信息info := fmt.Sprintf("用户id:\t%d 对大家说:\t%s", smsMes.UserId, smsMes.Content)fmt.Println(info)fmt.Println()
}

修改client/process/server.go

		//如果读到消息,进入下一步处理逻辑switch mes.Type {case message.NotifyUserStatusMesType: //有人上线//处理//1. 取出NotifyUserStatusMesvar notifyUserStatusMes message.NotifyUserStatusMesjson.Unmarshal([]byte(mes.Data), &notifyUserStatusMes)//2. 把这个用户信息,状态保存到客户map[int]User中updateUserStatus(&notifyUserStatusMes)case message.SmsMesType: //有人群发消息outputGroupMes(&mes)default:fmt.Println("服务器端返回了未知的消息类型")}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/740953.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的危险物品检测系统(深度学习模型+PySide6界面+训练数据集+Python代码)

摘要:本文深入介绍了一个采用深度学习技术的危险物品识别系统,该系统融合了最新的YOLOv8算法,并对比了YOLOv7、YOLOv6、YOLOv5等早期版本的性能。该系统在处理图像、视频、实时视频流及批量文件时,能够准确识别和分类各种危险物品…

设备点检管理系统的实施

设备点检管理系统的实施包括以下关键步骤: 确定检查对象和范围:根据生产需求和设备重要性,确定需要纳入点检系统的设备范围,以便有针对性地进行后续管理与监控。 制定点检计划:制定详细的点检计划,包括检…

【NR 定位】3GPP NR Positioning 5G定位标准解读(十二)-Multi-RTT定位

前言 3GPP NR Positioning 5G定位标准:3GPP TS 38.305 V18 3GPP 标准网址:Directory Listing /ftp/ 【NR 定位】3GPP NR Positioning 5G定位标准解读(一)-CSDN博客 【NR 定位】3GPP NR Positioning 5G定位标准解读(…

NXP Auto HVBMS S32DS 参数配置卡顿解决办法:使用 EB 替代 S32DS Configuration Tools

一、背景介绍 用户在 Automotive Software Package Manager | NXP Semiconductors 可以下载 S32K344 或者是 S32K358 的 HVBMS 捆绑包。 其中包含有 IDE:S32DS,基于 S32DS 的基础软件包以及 RTD 插件包,MCAL 配置工具:EB …

【PHP+代码审计】PHP基础——流程控制

🍬 博主介绍👨‍🎓 博主介绍:大家好,我是 hacker-routing ,很高兴认识大家~ ✨主攻领域:【渗透领域】【应急响应】 【Java、PHP】 【VulnHub靶场复现】【面试分析】 🎉点赞➕评论➕收…

QT网络编程之实现TCP客户端和服务端

一.QT5.12实现TCP客户端和服务端功能 1.QT中实现TCP通信主要用到了以下类:QTcpServer、QTcpSocket、QHostAddress 2.基本流程: 使用QTcpServer来创建一个TCP服务器,在新的连接建立时,将新建立连接的socket添加到列表中&#xf…

Ubuntu 安装腾讯会议

1.官网下载 进入腾讯会议下载官网下载腾讯会议Linux客户端 选择x86_64格式安装包下载 若不知道自己的系统架构,输入 uname -a 在命令行结果中查看系统架构信息 2.终端命令安装 cd {你的下载路径} sudo dpkg -i TencentMeeting_0300000000_3.19.0.401_x86_64_default.publi…

mysql对索引的选择简述

概述 在业务中经常会优化一些mysql的慢查询,通常都是使用explain去查看分析,检查扫描行数和索引的命中情况; 但是在具体索引的选择上,explain结果中并没有直接展示出来; 此时可以开启mysql的追踪优化器Trace功能&…

如何进行专利布局与专利规避

一、专利布局 WHY 专利布局是指企业或个人在科研或生产过程中,为了保护和利用自身的技术成果,通过综合产业、市场和法律等因素,对专利进行有机结合,构建严密高效的专利保护网,最终形成对企业或个人有利的专利组合。 …

使用TVMC Python

将使用resnet50 v2模型: mkdir myscripts cd myscripts wget https://github.com/onnx/models/raw/b9a54e89508f101a1611cd64f4ef56b9cb62c7cf/vision/classification/resnet/model/resnet50-v2-7.onnx mv resnet50-v2-7.onnx my_model.onnx touch tvmcpythonintro…

Cannot set priority of namenode process 8095

报错信息 报错: Cannot set priority of namenode process 8095 查看日志文件: 2024-03-10 01:36:50,840 INFO org.apache.hadoop.hdfs.server.datanode.DataNode: registered UNIX signal handlers for [TERM, HUP, INT] 2024-03-10 01:36:51,061 I…

10、Redis分布式系统之数据分区算法

Redis分布式系统之数据分区算法 1、什么是Redis分布式系统 ​ Redis分布式系统,官方称为Redis Cluster, Redis集群(这个集群和前面的主从复制集群不同,这个集群可以理解为是多个主从复制集群所组成的集群),其实是Red…

C# RAM Stable Diffusion 提示词反推 Onnx Demo

目录 介绍 效果 模型信息 项目 代码 下载 C# RAM Stable Diffusion 提示词反推 Onnx Demo 介绍 github地址:GitHub - xinyu1205/recognize-anything: Open-source and strong foundation image recognition models. Open-source and strong foundation ima…

基于Redis实现分布式锁、限流操作(基于SpringBoot)的实现

基于Redis实现分布式锁、限流操作——基于SpringBoot实现 本文总结了一种利用Redis实现分布式锁、限流的较优雅的实现方式本文原理介绍较为通俗,希望能帮到有需要的人本文的demo地址:https://gitee.com/rederxu/lock_distributed.git 一、本文基本实现…

《MySQL数据库》day2--连接查询、子查询、union、limit、DML语句

文章目录 1.把查询结果去除重复记录 -》distinct2.连接查询2.1什么是连接查询?2.2连接查询的分类2.3笛卡尔积现象2.4内连接2.4.1内连接之等值连接。2.4.2内连接之非等值连接2.4.3内连接之自连接 2.5外连接2.6三张表,四张表怎么连接? 3.子查询…

SA3D:基于 NeRF 的三维场景分割方法

Paper: Cen J, Zhou Z, Fang J, et al. Segment anything in 3d with nerfs[J]. Advances in Neural Information Processing Systems, 2024, 36. Introduction: https://jumpat.github.io/SA3D/ Code: https://github.com/Jumpat/SegmentAnythingin3D SA3D 是一种用于 NeRF 表…

Java项目:48 ssm008医院门诊挂号系统+jsp(含文档)

作者主页:源码空间codegym 简介:Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 本选题则旨在通过标签分类管理等方式实现 管理员;个人中心、药房管理、护士管理、医生管理、病人信息管理、科室信息管理、挂号管…

Vue3 使用Pinia 存入与取出数据

Pinia简介 Pinia 就是一个实现了上述需求的状态管理库,由 Vue 核心团队维护,对 Vue 2 和 Vue 3 都可用。 现有用户可能对 Vuex 更熟悉,它是 Vue 之前的官方状态管理库。由于 Pinia 在生态系统中能够承担相同的职责且能做得更好,…

【每日一题】2864. 最大二进制奇数-2024.3.13

题目: 2864. 最大二进制奇数 给你一个 二进制 字符串 s ,其中至少包含一个 1 。 你必须按某种方式 重新排列 字符串中的位,使得到的二进制数字是可以由该组合生成的 最大二进制奇数 。 以字符串形式,表示并返回可以由给定组合…

基于GIS技术的智慧农业大数据平台解决方案

1.建设背景 国务院促进大数据发展纲要 纲要提出大力推动政府信息系统和公共数据互联开放共享,加快政府信息平台整合,推动数据资源整合,提升治理水平。按照“五个统一”建设“大平台“,融合“大数据”,构建“大系统”落…