golang单点推送
package main import (
"encoding/json"
"flag"
"fmt"
"log"
"net/http"
"time" "config"
"framework/logger"
"global"
"models/function"
"models/schema" "github.com/go-redis/redis"
"github.com/gorilla/websocket"
"github.com/labstack/echo"
) var clients = make(map[*websocket.Conn]bool)
var broadcast = make(chan Message)
var upgrader = websocket.Upgrader{CheckOrigin: func(r *http.Request) bool { return true }} //不使用默认设置,如果线上环境可能需要使用默认配置
var chananel = make(chan schema.Listening) //数据chan var configFile *string = flag.String("config", "./bin/etc/conf.yaml", "agency config file")//这是数据库的配置文件解析,单写的时候提出来
var agentSlice []map[string]*websocket.Conn //socket对应关系存储 //发送消息结构体
type Message struct {
Message interface{} `json:"message"`
SiteId string `json:"site_id"`
SiteIndexId string `json:"site_index_id"`
Count int64 `json:"count"`
} //测试用[正式修改之后可以删除]
func hu(w http.ResponseWriter, r *http.Request) {
siteid := r.FormValue("site_id")
siteIndexId := r.FormValue("site_index_id")
fmt.Println(siteIndexId, siteid)
s := schema.Listening{"zym", "b", 1}
chananel <- s
} func main() {
//数据库初始化
cfg, err := config.ParseConfigFile(*configFile)
if err != nil {
log.Fatalf("parse config file error:%v\n", err.Error())
return
}
//初始化数据库
err = global.InitMysql(cfg.Mysqls)
if err != nil {
//数据库连接错误
global.GlobalLogger.Error("InitDb error:%v\n", err.Error())
return
}
http.HandleFunc("/o", hu)
http.HandleFunc("/ws", handleConnections)
go handleMessages()
err = http.ListenAndServe(cfg.Wesocketport, nil)
if err != nil {
log.Fatal(err.Error())
}
}
func handleConnections(w http.ResponseWriter, r *http.Request) {
//如果限制连接就可以使用ip+port限制,根据ip区分客户端,其他的可以根据r.Request提交的数据查找相应的内容
siteId := r.FormValue("site_id")
siteIndexId := r.FormValue("site_index_id")//这里是用来唯一区分客户端的判断条件
if siteId == "" || siteIndexId == "" {
http.Error(w, "site_id and site_index_id must not empty", 403)
}
//注册成为websocket
ws, err := upgrader.Upgrade(w, r, nil)
if err != nil {
global.GlobalLogger.Error("error:%s", err.Error())
return
}
defer ws.Close()
//存储连接[todo 这里可能还要考虑map并发读写问题]
agent := make(map[string]*websocket.Conn)
agent[s] = ws
agentSlice = append(agentSlice, agent)
clients[ws] = true
//监听接收一个[models/schema]schema.Listening,
for {
var msg Message
s := <-chananel
if s.Types == 1 {
//todo 这里解析取出来的数据可能还需要加工
//获取最新的没有确认得公司入款
newincome := new(function.MemberCompanyIncomeBean)
info, count, err := newincome.GetNotConfirm(s.SiteId, s.SiteIndexId)
if err != nil {
global.GlobalLogger.Error("error:%s", err.Error())
return
}
msg = Message{SiteIndexId: s.SiteIndexId, SiteId: s.SiteId, Message: info, Count: count}
} else if s.Types == 2 {
//获取最新的线上入款
onLineBean := new(function.OnlineEntryRecordBean)
info, count, err := onLineBean.GetNotConfirm(s.SiteId, s.SiteIndexId)
if err != nil {
global.GlobalLogger.Error("error:%s", err.Error())
return
}
msg = Message{SiteIndexId: s.SiteIndexId, SiteId: s.SiteId, Message: info, Count: count}
} else {
//获取没有确认得最新的出款管理
makeMoney := new(function.MakeMoneyBean)
info, count, err := makeMoney.GetOperateRecord(s.SiteId, s.SiteIndexId)
if err != nil {
global.GlobalLogger.Error("error:%s", err.Error())
return
}
msg = Message{SiteIndexId: s.SiteIndexId, SiteId: s.SiteId, Count: count, Message: info}
}
broadcast <- msg
}
} //单点推送
func handleMessages() {
for {
msg := <-broadcast
var pushClient []*websocket.Conn
newS := fmt.Sprintf("%s%s", msg.SiteId, msg.SiteIndexId)
lenAgent := len(agentSlice)
for i := 0; i < lenAgent; i++ {
for k, v := range agentSlice[i] {
if newS == k {
pushClient = append(pushClient, v)
}
}
}
for i := 0; i < len(pushClient); i++ {
for client := range clients {
if pushClient[i] == client {
err := client.WriteJSON(msg)
if err != nil {
global.GlobalLogger.Error("error:%s", err.Error())
client.Close()
delete(clients, client)
}
}
}
}
}
}
golang单点推送的更多相关文章
- Golang websocket推送
Golang websocket推送 在工作用主要使用的是Java,也做过IM(后端用的netty websocket).最近想通过Golang重写下,于是通过websocket撸了一个聊天室. 项目 ...
- golang实现ios推送
生成pem文件 打开Keychain Access 导出推送证书和私钥 推送证书 cert.p12 私钥 key.p12 导出.pem文件 转换推送证书 openssl pkcs12 -clcerts ...
- 用kafka实现消息推送
一个人知道的Topic是单点推送,大家都知道Topic是广播. kafka消息消费机制: 1.广播消费:通过定义topic前缀来标识属于广播的消息(例如:topicname:gonggao153568 ...
- golang实现kafka的消息推送
Kafka的安装与启动 kafka中涉及的名词 消息记录:由一个key,一个value和一个时间戳构成,消息最终存储在主题下的分区中,记录在生产中称为生产者记录,在消费者中称为消费记录.Kafka集群 ...
- #研发中间件介绍#异步消息可靠推送Notify
郑昀 基于朱传志的设计文档 最后更新于2014/11/11 关键词:异步消息.订阅者集群.可伸缩.Push模式.Pull模式 本文档适用人员:研发 电商系统为什么需要 NotifyServer? ...
- 用c#开发微信 (4) 基于Senparc.Weixin框架的接收事件推送处理 (源码下载)
本文讲述使用Senparc.Weixin框架来快速处理各种接收事件推送.这里的消息指的是传统的微信公众平台消息交互,微信用户向公众号发送消息后,公众号回复消息给微信用户.包括以下类型: 1 subsc ...
- iOS 10 消息推送(UserNotifications)秘籍总结(二)
背景 上一篇博客iOS 10 消息推送(UserNotifications)秘籍总结(一)发布后被 简书编辑推荐至首页,这着实让我受宠若惊啊.可是好事不长,后面发生了让我伤心欲绝的事,我的女朋友不要我 ...
- 安卓推送——个推服务端api使用误区
首先你需要在个推开放着平台上注册你的应用,以及获得以下几个必要的值APPID |APPKEY | MASTERSECRET,本文假设你已经完成上述步骤以及完成客户端SDK的集成. 原理 个推服务端ap ...
- 用 Go 编写一个简单的 WebSocket 推送服务
用 Go 编写一个简单的 WebSocket 推送服务 本文中代码可以在 github.com/alfred-zhong/wserver 获取. 背景 最近拿到需求要在网页上展示报警信息.以往报警信息 ...
随机推荐
- Redis 之order set有序集合结构及命令详解
1.zadd key score1 value1 score2 value2 添加元素 2.zrem key value1 value2 .. 删除集合中的元素 3.zremrangebyscor ...
- VS2015编译ffmpeg的问题解决
刚装了vs2015,打开一些ffmpeg项目,发现不能编译通过,包括stdio.h都无法找到,可能是vs2015的bug吧. 现在记录一下解决方法: 我的目录是这样定义的: C:\Program Fi ...
- Josephus problem(约瑟夫问题,丢手绢问题)
约瑟夫问题 约瑟夫环问题是一个数学应用题:已知n个人(以编号1,2,3.....,n)围坐在一张圆桌的周围.从编号为k的人开始报数,数到m的那个人出列:他的下一个人又从1开始报数,数到m的那个人又出列 ...
- Django - ORM实现用户登陆
1.路由分发cmdb(app)下urls.py中,建立url与函数对应关系 2.login.html代码: 3.views.py中,login函数,确认是否登陆成功 备注:从前端 获取用户名,密码,在 ...
- Python-----基本操作
Python是一种简单易学,且功能强大的编程语言.它是面向对象的编程语言. 对象的意义: 对象可以通过一个“.” 的方式来调用这个对象的方法. Python环境安装配置: Python是一种通用的计算 ...
- (转)window.location.hash 属性使用说明
location是javascript里边管理地址栏的内置对象,比如location.href就管理页面的url,用location.href=url就可以直接将页面重定向url.而location. ...
- [转]如何有效地报告Bug
英文原文:Simon Tatham,编译:Dasn 引言 为公众写过软件的人,大概都收到过很拙劣的bug报告,例如: 在报告中说“不好用”: 所报告内容毫无意义: 在报告中用户没有提供足够的信息: 在 ...
- RestEasy用户指南---第6章.@QueryParam
转载说明出处:http://blog.csdn.net/nndtdx/article/details/6870391 原文地址 http://docs.jboss.org/resteasy/docs/ ...
- 手动扩栈#pragma comment(linker, "/STACK:1024000000,1024000000")
#pragma comment(linker, "/STACK:1024000000,1024000000")
- python浅拷贝与深拷贝
今天写程序,人为制造了一个由浅拷贝引起的bug,有必要归纳一下.先附上源代码: class PerformanceTest(object): def __init__(self): ....... s ...