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. Node.js 命令行程序开发教程 ---------http://www.ruanyifeng.com/blog/2015/05/command-line-with-node.html

    五.yargs 模块 shelljs 只解决了如何调用 shell 命令,而 yargs 模块能够解决如何处理命令行参数.它也需要安装. $ npm install --save yargs yarg ...

  2. css中有些属性的前面会加上“*”或“_(兼容IE浏览器)

    给不同浏览器识别: color{ background-color: #CC00FF; /*所有浏览器都会显示为紫色*/ background-color: #FF0000\9; /*IE6.IE7. ...

  3. Git学习总结三(工作区和暂存区、撤销修改)

    工作区和暂存区 工作区(Working Directory) 就是你在电脑里能看到的目录,比如我的learngit文件夹就是一个工作区: 版本库(Repository) 工作区有一个隐藏目录.git, ...

  4. Java-Class-Miniprogram:com.ylbtech.common.utils.miniprogram.TemplateMessage

    ylbtech-Java-Class-Miniprogram:com.ylbtech.common.utils.miniprogram.TemplateMessage 1.返回顶部 1.1. pack ...

  5. c++ list双向链表管理对象

    #cat list.cc #include <cstdlib> #include <iostream> #include <stdio.h> using names ...

  6. Django REST framework 分页

    三种分页:根据页码.根据索引.根据加密 http://www.xx.com/courses/?page=1&size=10 http://www.xx.com/courses/?offset= ...

  7. linux的ulimit各种限制之深入分析

    一般可以通过ulimit命令或编辑/etc/security/limits.conf重新加载的方式使之生效 通过ulimit比较直接,但只在当前的session有效,limits.conf中可以根据用 ...

  8. E. Rusty String

    E. Rusty String time limit per test 3 seconds memory limit per test 512 megabytes input standard inp ...

  9. (42)Spring Boot多数据源【从零开始学Spring Boot】

    我们在开发过程中可能需要用到多个数据源,我们有一个项目(MySQL)就是和别的项目(SQL Server)混合使用了.其中SQL Server是别的公司开发的,有些基本数据需要从他们平台进行调取,那么 ...

  10. Ajax 请求之_请求类型详解

    $.ajax({ url: "规定发送请求的 URL.默认是当前页面.", type: "post", // 请求类型,默认get // 在回调函数中,无需将j ...