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单点推送的更多相关文章

  1. Golang websocket推送

    Golang websocket推送 在工作用主要使用的是Java,也做过IM(后端用的netty websocket).最近想通过Golang重写下,于是通过websocket撸了一个聊天室. 项目 ...

  2. golang实现ios推送

    生成pem文件 打开Keychain Access 导出推送证书和私钥 推送证书 cert.p12 私钥 key.p12 导出.pem文件 转换推送证书 openssl pkcs12 -clcerts ...

  3. 用kafka实现消息推送

    一个人知道的Topic是单点推送,大家都知道Topic是广播. kafka消息消费机制: 1.广播消费:通过定义topic前缀来标识属于广播的消息(例如:topicname:gonggao153568 ...

  4. golang实现kafka的消息推送

    Kafka的安装与启动 kafka中涉及的名词 消息记录:由一个key,一个value和一个时间戳构成,消息最终存储在主题下的分区中,记录在生产中称为生产者记录,在消费者中称为消费记录.Kafka集群 ...

  5. #研发中间件介绍#异步消息可靠推送Notify

    郑昀 基于朱传志的设计文档 最后更新于2014/11/11 关键词:异步消息.订阅者集群.可伸缩.Push模式.Pull模式 本文档适用人员:研发   电商系统为什么需要 NotifyServer? ...

  6. 用c#开发微信 (4) 基于Senparc.Weixin框架的接收事件推送处理 (源码下载)

    本文讲述使用Senparc.Weixin框架来快速处理各种接收事件推送.这里的消息指的是传统的微信公众平台消息交互,微信用户向公众号发送消息后,公众号回复消息给微信用户.包括以下类型: 1 subsc ...

  7. iOS 10 消息推送(UserNotifications)秘籍总结(二)

    背景 上一篇博客iOS 10 消息推送(UserNotifications)秘籍总结(一)发布后被 简书编辑推荐至首页,这着实让我受宠若惊啊.可是好事不长,后面发生了让我伤心欲绝的事,我的女朋友不要我 ...

  8. 安卓推送——个推服务端api使用误区

    首先你需要在个推开放着平台上注册你的应用,以及获得以下几个必要的值APPID |APPKEY | MASTERSECRET,本文假设你已经完成上述步骤以及完成客户端SDK的集成. 原理 个推服务端ap ...

  9. 用 Go 编写一个简单的 WebSocket 推送服务

    用 Go 编写一个简单的 WebSocket 推送服务 本文中代码可以在 github.com/alfred-zhong/wserver 获取. 背景 最近拿到需求要在网页上展示报警信息.以往报警信息 ...

随机推荐

  1. js的三种对象

    JS中,可以将对象分为“内部对象”.“宿主对象”和“自定义对象”三种. 1,内部对象 js中的内部对象包括Array.Boolean.Date.Function.Global.Math.Number. ...

  2. 为什么Java中的密码优先使用 char[] 而不是String?

    可以看下壁虎的回答:https://www.zhihu.com/question/36734157 String是常量(即创建之后就无法更改),会保存到常量池中,如果有其他进程可以dump这个进程的内 ...

  3. BZOJ 2501 [usaco2010 Oct]Soda Machine

    [题意概述] 给出一个[0,1,000,000,000]的整数数轴,刚开始每个位置都为0,有n个区间加操作,最后询问数轴上最大的数是多少. [题解] 我写的是离散化后线段树维护区间最值. 其实貌似不用 ...

  4. BZOJ 1641 USACO 2007 Nov. Cow Hurdles 奶牛跨栏

    [题解] 弗洛伊德.更新距离的时候把$f[i][j]=min(f[i][j],f[i][k]+f[k][j])$改为$f[i][j]=min(f[i][j],max(f[i][k],f[k][j])) ...

  5. 前端开发神器之chrome 综述

    作为前端工程师,也许你对chrome开发工具不陌生,但也谈不上对各个模块有深入了解. 本文主要是为chrome开发工具使用这个系列做个开篇. 参考资料: 谷歌开发者: https://develope ...

  6. Java8新特性之forEach遍历

    参考文章: https://www.cnblogs.com/billyu/p/6118008.html

  7. noip模拟赛 gcd

    题目更正:输出的a<b. 分析:这是一道数学题,范围这么大肯定是有规律的,打个表可以发现f(a,b)=k,a+b最小的a,b是斐波那契数列的第k+1项和k+2项.矩阵快速幂搞一搞就好了. #in ...

  8. 接水问题(2010年NOIP全国联赛普及组)

    时间限制: 1 s    空间限制: 128000 KB 题目描述 Description 学校里有一个水房,水房里一共装有m 个龙头可供同学们打开水,每个龙头每秒钟的供水量相等,均为1. 现在有n ...

  9. [bzoj2213][Poi2011]Difference_动态规划

    Difference bzoj-2213 Poi-2011 题目大意:已知一个长度为n的由小写字母组成的字符串,求其中连续的一段,满足该段中出现最多的字母出现的个数减去该段中出现最少的字母出现的个数最 ...

  10. asciiflow

    http://asciiflow.com/ https://maxiang.io/# http://www.jianshu.com/p/19432b5e3c60