当前位置: 首页 > news >正文

百姓网网站开发的意义站长之家音效

百姓网网站开发的意义,站长之家音效,网站排名哪家好,中国建设银行网上银行网站目录 1.前言 2.锁解决方案 3.管道解决方案 4.总结 1.前言 在写H5小游戏的时候#xff0c;由于需要对多个WebSocket连接进行增、删、查的管理和对已经建立连接的WebSocket通过服务端进行游戏数据交换的需求。于是定义了一个全局的map集合进行连接的管理#xff0c;让所有…目录 1.前言 2.锁解决方案 3.管道解决方案 4.总结 1.前言 在写H5小游戏的时候由于需要对多个WebSocket连接进行增、删、查的管理和对已经建立连接的WebSocket通过服务端进行游戏数据交换的需求。于是定义了一个全局的map集合进行连接的管理让所有的协程共享操作同一个map集合进行各种WebSocket连接的操作。由于多个协程操作共享同一块内容这时候就会遇到数据竞争和并发访问。 H5小游戏介绍基于WebSocket通信的H5小游戏总结-CSDN博客 解决并发问题的常见方法有两种 在结构体中增加 sync.RWMutex字段每一个协程操作map集合的时候进行加锁操作操作结束后进行解锁操作保证同时只有一个协程操作map,避免并发问题。但是频繁的加锁和解锁操作会成为后期的性能瓶颈。使用管道进行通信由于管道本身就是线程安全的所以我们在操作层面无需进行加锁和解锁操作只需要另启一个协程进行管道的读取如果有数据写入则进行map操作。我们在需要对map进行操作的时候向管道中写入数据即可。 由于第一次在项目中遇到并发问题一开始没有意识到多个协程对同一个map进行操作需要保证线程安全。在老师查看代码后说出map是线程不安全的时候才意识到需要进行加锁操作或者其他方案来保证线程安全。 2.锁解决方案 第一版本的代码——加锁解锁保证线程安全 在结构体中的ClientsMap进行操作的时候进行加锁和解锁的操作保证线程安全。 // HupCenter ---使用锁操作一个多线程共享的Map---// type HupCenter struct {//第一个string-roomId 第二个string-userIdClientsMap map[string]map[string]*Client json:- mutex sync.RWMutex }// JoinHub 写操作 --将连接加入中心 前提RoomId不为空, 加入房间的时候需要检测当前房间里面的人数 func (h *HupCenter) JoinHub(c *Client) (flag bool) {h.mutex.Lock()defer h.mutex.Unlock()//先查询是否存在此一个roomId keyif myMap, ok : c.Hub.ClientsMap[c.User.RoomId]; ok { //有,加入房间//检测人数if len(myMap) 1 {myMap[c.User.UserId] cflag true}} else { //没有,创建房间myMap : make(map[string]*Client)myMap[c.User.UserId] c //userIdc.Hub.ClientsMap[c.User.RoomId] myMap //roomIdflag true}return }// DeleteFromHub 写操作 --逻辑删除 将传入的参数c从hub连接池中删除 func (h *HupCenter) DeleteFromHub(c *Client) {h.mutex.Lock()defer h.mutex.Unlock()if c.User.RoomId {return}if value, ok1 : c.Hub.ClientsMap[c.User.RoomId]; ok1 {if _, ok2 : value[c.User.UserId]; ok2 {delete(value, c.User.UserId)}}if len(c.Hub.ClientsMap[c.User.RoomId]) 0 {delete(c.Hub.ClientsMap, c.User.RoomId)} }// QueryOtherUser 读操作 -- 根据当前用户寻找另一位用户返回user对象 func (h *HupCenter) QueryOtherUser(c *Client) *Client {if roomMap, ok : h.ClientsMap[c.User.RoomId]; ok { //roomfor userId, user : range roomMap {if userId ! c.User.UserId {return user}}}return nil } 3.管道解决方案 使用锁是能够基本解决问题的但是对于读写较为频繁的场景读写锁可能会成为性能瓶颈再加上自己对管道的运用不是很熟练就开始思考如何使用channel去解决这一个并发的问题代码如下 type HupCenter struct {ClientsMap map[string]map[string]*Client json:- //第一个string-roomId 第二个string-userIdRegister chan *ClientUnRegister chan *Client }// NewHub 初始化一个hub func NewHub() *HupCenter {return HupCenter{ClientsMap: make(map[string]map[string]*Client),Register: make(chan *Client, 1),UnRegister: make(chan *Client, 1),} }// Run 用户向hub中的逻辑注册、删除、心跳检测全方法,在代码执行后开始协程去执行Run方法 func (h *HupCenter) Run() {checkTicker : time.NewTicker(time.Duration(pkg.HeartCheckSecond) * time.Second)defer checkTicker.Stop()for {select {case client : -h.Register://先查询是否存在此一个roomId keyif myMap, ok : client.Hub.ClientsMap[client.User.RoomId]; ok { //有,加入房间//检测人数if len(myMap) 1 {myMap[client.User.UserId] client}} else { //没有,创建房间myMap : make(map[string]*Client)myMap[client.User.UserId] client //userIdclient.Hub.ClientsMap[client.User.RoomId] myMap //roomId}fmt.Println(有人加入房间:, client.Hub.ClientsMap)case client : -h.UnRegister:client.User.Close()if value, ok1 : client.Hub.ClientsMap[client.User.RoomId]; ok1 {if _, ok2 : value[client.User.UserId]; ok2 {delete(value, client.User.UserId)}}if len(client.Hub.ClientsMap[client.User.RoomId]) 0 {delete(client.Hub.ClientsMap, client.User.RoomId)}case -checkTicker.C:for _, roomMap : range h.ClientsMap {for _, client : range roomMap {if client.User.HealthCheck.Before(time.Now()) {h.UnRegister - client}}}fmt.Println(time.Now().Format(time.DateTime), h.ClientsMap)}} }// QueryOtherUser 读操作 -- 根据当前用户寻找另一位用户返回user对象 func (h *HupCenter) QueryOtherUser(c *Client) *Client {if roomMap, ok : h.ClientsMap[c.User.RoomId]; ok { //roomfor userId, user : range roomMap {if userId ! c.User.UserId {return user}}}return nil } 在代码中我们在结构体中定义了两个管道一个管道接收注册的客户端对象原JoinHub方法另一个管道接收注销的客户端对象原DeleteFormHub方法); 在Run方法中我们创建了一个10秒的ticker对象来进行客户端连接的心跳检测。之后使用for循环来执行select来监听多个管道并执行对应的分支操作。select会随机挑选一个可执行的case语句如果没有可执行的case,则进行等待。在本代码中如果没有注册、注销的操作会每隔10秒进行一次心跳检测并打印当前存活的客户端对象集合。 4.总结 在使用锁解决并发问题的时候一定要使用延迟函数解锁防止出现死锁问题 在使用管道解决并发问题的时候设计好管道的缓冲区和管道的关闭操作防止出现死锁和向已经关闭的管道中写入数据发生panic异常。 结语学会一个知识点最好的方法就是在项目、实战中去应用它。
http://www.dnsts.com.cn/news/72667.html

相关文章:

  • 花店网站模板 html诸城网站建设0536s
  • 手机网站是怎么制作的公司网站开发费用济南兴田德润o评价
  • 查看网站是否备案网站开发者yotoon
  • 哪个网站可以接广告做谷歌 wordpress 插件
  • 郑州网站建设公司有哪些公司logo形象墙效果图
  • 检察院门户网站建设工作成效许昌市建设路小学网站
  • 杨凌网站开发常见的微网站平台有哪些
  • 互联网产品做网站好还是小程序软件源码购买一般在哪个网站
  • 诏安县城乡规划建设局网站保定建设网站
  • 南通做百度网站的公司哪家好南京网站开发推南京乐识
  • 搜索引擎网站免费空间访客网站
  • 公司门户网站开发网络营销策略优化
  • 专业建设润滑油网站电商详情页模板免费套用
  • 创建网站 英文手机360优化大师官网
  • 巩义企业网站建设报价深圳房管局官网查询系统
  • 广州seo网络营销培训山东关键词优化推广
  • 北京手机网站开发电话h5响应式网站公司
  • 国内做的比较好的网站是什么网站建设设计费会计分录
  • html5网站开发方案丰台体育馆网站建设
  • 单一产品网站如何做seowordpress 房屋租赁
  • 兰州市门户网站网上注册公司流程及材料
  • 网站dns国外的优秀网站
  • 网站不备案可以么做网站 套模板 后端
  • 旅游网站的广告预算怎么做西部数码网站管理助手搭建织梦
  • 佛山做网站的公司河源新闻头条最新新闻
  • 1 高端品牌网站定制画册设计模板图片
  • 电商网站建设与维护意味着什么html文档模板
  • 网站引导页一般是什么格式建社个人网站
  • 怎样免费做网站视频讲解清徐北京网站建设
  • 局域网内建设网站什么是网站的功能模块