沪深websocket level2/level1行情推送接入示例

server/2024/12/22 14:08:34/

行情接入包

golang packge:

package hangqingimport ("bufio""bytes""compress/flate""encoding/json""github.com/gorilla/websocket""io/ioutil""log""net/http""net/url""strings""sync""time"
)type ServerAddrRsp struct {Code   string `json:"code"`Server string `json:"server"`
}type Hq struct {token    string          //jvQuant Tokenserver   string          //websocket服务器地址conn     *websocket.Conn //websocket连接cmdChan  chan stringexitChan chan intlv1Deal  func(string string) //level1行情处理方法lv2Deal  func(string string) //level2行情处理方法wg       *sync.WaitGroup
}//实例初始化
func (hq *Hq) Construct(token, serAddr string, lv1Handle, lv2Handle func(string string)) {hq.token = tokenif serAddr == "" {hq.server = hq.initServer()}hq.lv1Deal = lv1Handlehq.lv2Deal = lv2Handlehq.conn = hq.connect()hq.wg = &sync.WaitGroup{}hq.cmdChan = make(chan string, 128)hq.exitChan = make(chan int)//接收协程hq.wg.Add(2)go func() {hq.receive()hq.wg.Done()}()//发送协程go func() {hq.cmd()hq.wg.Done()}()
}//获取行情服务器地址
func (hq *Hq) initServer() (server string) {params := url.Values{"market": []string{"ab"},"type":   []string{"websocket"},"token":  []string{hq.token},}req := "http://jvquant.com/query/server?" + params.Encode()rb, err := HttpOnce(req, nil, nil, 3000)if err != nil {log.Fatalln("获取行情服务器地址失败:", req, err)}rspMap := ServerAddrRsp{}err = json.Unmarshal(rb, &rspMap)if err != nil {log.Fatalln("解析行情服务器地址失败:", string(rb), err)}server = rspMap.Serverif rspMap.Code != "0" || server == "" {log.Fatalln("解析行情服务器地址失败:", string(rb))}log.Println("获取行情服务器地址成功:", server)return
}//连接行情服务器
func (hq Hq) connect() (conn *websocket.Conn) {wsUrl := hq.server + "?token=" + hq.tokenconn, _, err := websocket.DefaultDialer.Dial(wsUrl, nil)if err != nil {log.Fatalln("行情服务器连接错误:", err)}return
}//增加level1行情订阅
func (hq Hq) AddLv1(codeArr []string) {cmd := "add="cmdArr := []string{}for _, code := range codeArr {cmdArr = append(cmdArr, "lv1_"+code)}cmd = cmd + strings.Join(cmdArr, ",")hq.SendRawCmd(cmd)
}//增加level2行情订阅
func (hq Hq) AddLv2(codeArr []string) {cmd := "add="cmdArr := []string{}for _, code := range codeArr {cmdArr = append(cmdArr, "lv2_"+code)}cmd = cmd + strings.Join(cmdArr, ",")hq.SendRawCmd(cmd)
}//指令入队列
func (hq Hq) SendRawCmd(cmd string) {hq.cmdChan <- cmd
}//关闭行情连接
func (hq Hq) Close() {close(hq.cmdChan)hq.exitChan <- 1hq.conn.Close()
}//线程阻塞等待
func (hq Hq) Wait() {hq.wg.Wait()
}//websocket指令发送
func (hq Hq) cmd() {for cmd := range hq.cmdChan {log.Println("发送指令:" + cmd)err := hq.conn.WriteMessage(websocket.TextMessage, []byte(cmd))if err != nil {log.Println("指令发送错误:", err)}}
}//websocket行情接收处理
func (hq Hq) receive() {for {select {case <-hq.exitChan:log.Print("接收协程退出")returndefault://阻塞接收messageType, rb, err := hq.conn.ReadMessage()if err != nil {log.Print("接收错误:", err)}//文本消息if messageType == websocket.TextMessage {log.Println("Text响应:", string(rb))}//二进制消息if messageType == websocket.BinaryMessage {unZipByte := DeCompress(rb)text := string(unZipByte)ex1 := strings.Split(text, "\n")for _, ex1r := range ex1 {ex2 := strings.Split(ex1r, "=")if len(ex2) == 2 {code := ex2[0]hqs := ex2[1]if strings.HasPrefix(code, "lv1_") {hq.lv1Deal(hqs)}if strings.HasPrefix(code, "lv2_") {hq.lv2Deal(hqs)}}}}}}
}//二进制数据解压方法
func DeCompress(b []byte) []byte {var buffer bytes.Bufferbuffer.Write([]byte(b))reader := flate.NewReader(&buffer)var result bytes.Bufferresult.ReadFrom(reader)reader.Close()return result.Bytes()
}
//http请求封装
func HttpOnce(Url string, headers, postData map[string]string, msTimeOut int) (r []byte, err error) {client := &http.Client{Timeout: time.Duration(time.Duration(msTimeOut) * time.Millisecond),}method := http.MethodGetr = []byte{}err = nilif len(headers) == 0 {headers = map[string]string{}}if len(postData) != 0 {method = http.MethodPostheaders["Content-Type"] = "application/x-www-form-urlencoded"}postParam := url.Values{}for k, v := range postData {postParam.Set(k, v)}postParamBuff := bytes.NewBufferString(postParam.Encode())req, err := http.NewRequest(method, Url, postParamBuff)if err != nil {return r, err}for k, v := range headers {req.Header.Add(k, v)}resp, er := client.Do(req)if er != nil {err = erreturn}defer resp.Body.Close()if err != nil {return r, err}br := bufio.NewReader(resp.Body)r, err = ioutil.ReadAll(br)return r, err
}

参考地址:https://github.com/jvQuant/OpenAPIDemo


http://www.ppmy.cn/server/26891.html

相关文章

WIN10 anaconda 安装 CondaError: Run ‘conda init‘ before ‘conda activate‘

1 下载 https://www.anaconda.com/download/success 2 安装 3 修改环境变量 安装后修改环境变量 4 winrun 进入命令窗口 输入cmd 输入 conda info 5 创建 虚拟环境 conda create -n yolov8 python3.8 -y 6 CondaError: Run ‘conda init’ before ‘conda activate’ c…

【网络安全】安全事件管理处置 — 安全事件处置思路指导

专栏文章索引&#xff1a;网络安全 有问题可私聊&#xff1a;QQ&#xff1a;3375119339 目录 一、处理DDOS事件 1.准备工作 2.预防工作 3.检测与分析 4.限制、消除 5.证据收集 二、处理恶意代码事件 1.准备 2.预防 3.检测与分析 4.限制 5.证据收集 6.消除与恢复 …

GO语言核心30讲 进阶技术 (第二部分)

原站地址&#xff1a;Go语言核心36讲_Golang_Go语言-极客时间 一、接口类型的合理运用 1. 接口类型只包含方法&#xff0c;不包含字段。 方法集合就是它的全部特征。 任何数据类型&#xff0c;只要实现了接口的方法集合全部&#xff0c;那么它就是这个接口的实现类型 2. 怎么…

easyExcel - 带图片导出

目录 前言一、情景介绍二、问题分析三、代码实现1. 单图片导出2. 多图片导出3. 多图片导出&#xff08;优化&#xff09; 前言 Java-easyExcel入门教程&#xff1a;https://blog.csdn.net/xhmico/article/details/134714025 之前有介绍过如何使用 easyExcel&#xff0c;以及写…

Android创建快捷方式到桌面

效果图 参考 https://blog.51cto.com/u_16175498/8811197https://blog.51cto.com/u_16175498/8811197 权限 <uses-permission android:name"com.android.launcher.permission.INSTALL_SHORTCUT" /> 实现 if (Build.VERSION.SDK_INT > Build.VERSION_C…

Centos7安装完ifconfig命令出错:bash: command not found

Centos7安装完ifconfig命令出错&#xff1a;bash: command not found 安装完Centos 7后&#xff0c;ifconfig&#xff0c;yum&#xff0c;ping都不能使用&#xff0c;原因在于无法连网 1&#xff1a;虚拟机设置中网络&#xff0c;选择桥接网络 2&#xff1a;输入hostname -i&a…

centos7 openresty lua 自适应webp和缩放图片

目录 背景效果图准备安装cwebp等命令&#xff0c;转换文件格式安装ImageMagick&#xff0c;压缩文件下载Lua API 操控ImageMagick的依赖包 代码参考 背景 缩小图片体积&#xff0c;提升加载速度&#xff0c;节省流量。 效果图 参数格式 &#xff1a; ?image_processformat,…

Java面试题:解释Java中的并发工具类ConcurrentHashMap的工作原理,并列举经典应用案例

Java中的ConcurrentHashMap是Java并发包(java.util.concurrent)中的一个线程安全的HashMap实现。它是为高并发场景设计的&#xff0c;能够在多线程环境下提供高效的键值存储和查询操作。以下是ConcurrentHashMap的工作原理和一些经典应用案例的解释。 工作原理 数据结构&#…