使用Go Hijack和jQuery轻松实现异步推送服务

2023-11-12

使用Go Hijack和jQuery轻松实现异步推送服务

首先要说明的是,这里实现的异步推送服务采用的是Long Polling方式,并不是Comet。

 
如果想用Comet来实现的话,可以参考这个开源项目: http://cometd.org/。不过其中的服务端实现只有Java版和Python版。如果要用Go来做后端的话需要自己实现Bayeux协议。
 
关于异步推送服务的解决方案的资料有很多,在这里就不在赘述了。当然,当前最先进的两个方案就是Long Polling和Comet。
 
1. 预备知识
 
1.1 Go语言
 
关于Go语言,其实要说的很多。但是为了不跑题,请大家移步到这里: http://code.google.com/p/golang-china/。另外,Go语言的官网地址是: http://golang.org/
 
1.2 Hijack
 
Hijack其实是一个单词,虽然有很多人把它和电影《泰坦尼克号》中Rose的召唤联系到一起。Hijack被译为劫持,在“处理HTTP请求”的这个上下文中,就意味着可以让我们“劫持”(或者说“保持”)HTTP请求链接,做一些其他操作(比如根据需要修改HTTP响应的内容),然后再在之后的某个时间将响应“推送”回去。说到这,我想这就与Long Polling的运作方式很相似了。
 
Go语言的Hijack接口非常简单,我们在官方的文档站点上可以找到说明: http://godoc.org/net/http#Hijacker。本文中的核心代码也是来自于此文档。
 
1.3 jQuery
 
jQuery作为当今最流行的Javascript开发框架,我想基本上每一个做过Web开发的人都会知道,所以在这里我就不多说了。如果你不知道,可以看这里: http://jquery.com/
 
2. 实战
 
2.1 需求
 
在本案例中,我需要做一个能实时查看当前授权码的页面,而且我不想手动刷新页面。另外,我还想记录一下从页面打开到当前时刻授权码改变过多少次。因为授权码在被使用后会自动变更一次,所以授权的变更次数就等于使用授权码服务的人数。
 
2.2 编写服务端代码
 
之前说了,我们使用Go语言来编写后端代码。我们要使用Go语言的官方http库。
 
其中,我们需要用http.HandleFunc来注册针对某个url的请求处理器。如下:
 http.HandleFunc("/auth_code", getAuthCodeForAdmin) //向http服务器注册一个对指定url进行处理的函数。 
在函数getAuthCodeForAdmin的签名中,有两个参数——http.Request对象指针和http.ResponseWriter对象。http.Request对象指针用来获取请求信息,http.ResponseWriter对象用来写入响应。
 
如果要使用Go的Hijack方式来处理HTTP请求,就需要先import其官方的http包:
 import (
    "net/http"

之后,我们在处理函数getAuthCodeForAdmin中先将http.ResponseWriter对象显式转换为http.Hijacker接口:
 hj, ok := w.(http.Hijacker) 
返回值中赋给“ok”变量的值代表转换是否成功,如果不成功就说明http.ResponseWriter对象未实现http.Hijacker接口。
 
如果转换成功,我们就可以调用http.Hijacker接口的Hijack方法来获取连接对象及其读写缓存对象了:
 conn, bufrw, err := hj.Hijack() 
返回值中,“conn”代表连接对象,“bufrw”代表该连接的读写缓存对象。
 
如果返回值“err”等于nil就说明获取成功,我就可以继续下面的事情了。但首先需要在函数推出前关闭连接,不论函数是否执行成功以及是否有错误发生:
 defer conn.Close() 
使用defer关键字意味着,让程序执行流程退出该函数前先执行紧随其后的语句或函数。这样就保证了资源的及时释放。
 
接下来,我们先观测新的授权码的出现,当其出现后我们就使用连接读写缓存对象bufrw返回给http客户端。从观测到返回给http客户端的时间并不确定,也许时间会很长,这也从侧面体现了Long Polling中的Long。看下面的代码:
 nacChan := make(chan string)
triggerFunc := func(newAuthCode string) {
    nacChan <- newAuthCode }
triggerId := fmt.Sprintf("long-polling|%s|%s|%d", loginName, groupName, time.Now().UnixNano())
request.AddNewAuthCodeTrigger(triggerId, triggerFunc)
defer request.DelNewAuthCodeTrigger(triggerId) 
这段代码其中包含的东西很多,我们不需要全搞明白,只要知道这是为新授权码产生时间注册一个触发器就行了。
 
当新授权码被产生后,充当触发器的函数triggerFunc会被调用。它会向名为nacChan的Channel中添加一个元素。注意,这个Channel是字符串类型的,并且是阻塞式。阻塞式意味着获取元素的语句会一直阻塞,直到该Channel被添入元素。另外,当Channel中已有一个元素时,添加元素的语句也会被阻塞。我们在这里只用到了阻塞式Channel的前一个特性。元素获取语句是这样写的:
 newAuthCode := <-nacChan 
获取到新授权码后,程序会立即把它“push”给http客户端。
 done := pushResponse(bufrw, newAuthCode) 
函数pushResponse的完整定义如下:
 func pushResponse(bufrw *bufio.ReadWriter, authCode string) bool {
    _, err := bufrw.Write([]byte(authCode))
    if err == nil {
        err = bufrw.Flush()
    }
    if err != nil {
        go_lib.LogErrorf("PushAuthCodeError: %s\n", err)
        return false
    }
    return true

其中用到了很多“net/http”以外的包,关于它们的说明可以到Go文档站点 http://godoc.org/中查找。另外,“go_lib”是我为了自己开发方便而写的一个函数库,源码在这里: https://github.com/hyper-carrot/go_lib,有兴趣的读者可以查看。
 
至此,基于Long Polling的异步推送服务的服务端就完成了。函数getAuthCodeForAdmin的完整代码可以参看: https://github.com/hyper-carrot/hypermind/blob/master/server.go#L244linux
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用Go Hijack和jQuery轻松实现异步推送服务 的相关文章

  • 深入了解golang 的channel

    文章目录 1 channel 是什么 channel的特点 2 channel 的数据结构 hchan 等待队列和发送队列的类型包装 sudog 3 channel 分类 有缓冲channel 无缓冲channel 4 channel 的创
  • Go语言函数

    http www jb51 net article 56831 htm Go语言中的函数有系统函数和自定义函数 1 系统函数 系统函数就是Go语言自带的函数 系统函数一般根据功能封装在不同的包内 比如Print Printf Println
  • 在Windows上搭建Go开发环境

    Go语言是由谷歌开发的一个高性能 跨平台的编程语言 安装Go 首先先来安装一下Go语言的SDK 目前Go语言的最新版本为Go 1 8 3 Go下载页面列出了各种操作系统的安装包 如果选择Windows MSI安装包的话 会将Go安装到C G
  • 将切片作为参数传入函数并使用append方法遇到的问题

    切片的内部结构 type SliceHeader struct Data uintptr Len int Cap int 由切片的结构定义可知 切片的结构由三个信息组成 指针Data 指向底层数组中切片指定的开始位置 长度Len 即切片的长
  • Go语言学习5-切片类型

    切片类型 引言 1 切片 1 1 类型表示法 1 2 值表示法 1 3 属性和基本操作 1 4 切片使用的复杂用法 总结 引言 上篇我们介绍了 Go语言的数组类型 本篇将介绍Go语言的切片类型 主要如下 1 切片 切片可以看作是对数组的一种
  • Windows 上Go env 命令设置Go环境变量

    在旧版本中使用下面的命令设置 Enable the go modules feature env GO111MODULE on Set the GOPROXY environment variable env GOPROXY https g
  • 用Go实现的简易TCP通信框架

    接触到GO之后 GO的网络支持非常令人喜欢 GO实现了在语法层面上可以保持同步语义 但是却又没有牺牲太多性能 底层一样使用了IO路径复用 比如在LINUX下用了EPOLL 在WINDOWS下用了IOCP 但是在开发服务端程序的时候 很多都是
  • go语言重大bug,make缓存读取数据漏洞,4096漏洞

    做一个小程序 需要对文件内容分片读取 但是读取过程中发现数据读取不全 经测试多个make缓存读取文件时发现问题 以下为漏洞测试部分 一 生成测试文件 AAA txt 创建一个AAA txt文件 写入1万个A wFile os OpenFil
  • Go+Together——Go+1.0发布会暨Go+开发者基金会启动仪式重磅来袭!

    你想参与iPhone13抽奖吗 你想和大咖面对面交流吗 你想收获最前沿的行业动态吗 10 月15 日 Go Together Go 1 0发布会暨Go 开发者基金会启动仪式重磅来袭 活动中除七牛云 CEO Go 语言发明人许式伟以及Go 开
  • 【go基础】变量声明

    1 第一个go语言程序 package main 声明所属的包 import fmt func main fmt Println hello world go run hello go 执行当前文件 输出 hello world 也可以构建
  • fabric2.X以上系统用test-network环境测试自己的链码

    首先 我们需要安装好fabric2 X的环境 具体参考我之前的文章 这里默认已经有了fabric2 X的环境 进入test network文件夹 在开始测试之前 先把gopath项目路径全部解锁 sudo chmod R 777 GOPAT
  • Go语言中的rune数据类型

    写在前面 最近开始学习Go语言 因为自己是从Java逐步转Go原因 在感慨Go语言简便的同时 也因为其封装的数据类型和包较多 所以还得慢慢学习 今天来谈谈Go语言中的rune数据类型 名词解释 Go语言中的整数类型也有有符号数和无符号数之别
  • go语言标准库

    在Go语言的安装文件里包含了一些可以直接使用的包 即标准库 Go语言的标准库 通常被称为语言自带的电池 提供了清晰的构建模块和公共接口 包含 I O 操作 文本处理 图像 密码学 网络和分布式应用程序等 并支持许多标准化的文件格式和编解码协
  • golang的hijack篡取劫持

    一直不太明白golang的hijack是干什么的 只知道hijack这个词是篡取的意思 难道跟网关的作用一样 把client的请求发到这个服务上 然后这个服务帮忙转发到远端server 但是看了源码后就明白这个golang hijack是干
  • VMware+CentOS7搭建私有云桌面服务

    VMware CentOS7搭建私有云桌面服务 1 安装VMware虚拟机工作台 官网下载安装包 版本 14 1 3 Pro 地址 https my vmware com en web vmware info slug desktop en
  • Go Web编程实战(2)----流程控制语句

    目录 流程控制语句 if else语句 for循环语句 用for循环实现do while 用for循环实现while break指定跳出循环 continue语句 for range循环 遍历数组 遍历字符串 遍历map 遍历通道 chan
  • go语言RSA加密算法(一):生成密钥对

    生成密钥对 分别存储到公钥文件 files public pem 私钥文件中 files private pem package main import crypto rand crypto rsa crypto x509 encoding
  • golang json性能分析详解

    原文地址 https www jb51 net article 135264 htm json格式可以算我们日常最常用的序列化格式之一了 Go语言作为一个由Google开发 号称互联网的C语言的语言 自然也对JSON格式支持很好 下面这篇文
  • 【Go语言核心手册11】context.Context

    往期精选 欢迎转发 如何看待程序员35岁职业危机 Java全套学习资料 14W字 耗时半年整理 我肝了三个月 为你写出了GO核心手册 消息队列 从选型到原理 一文带你全部掌握 肝了一个月的ETCD 从Raft原理到实践 更多 11 1 内容
  • go语言学习 1 -- 类型

    Go语言接受了函数式编程的一些想法 支持匿名函数与闭包 接受了以Erlang语言为代表的面向消息编程思想 支持goroutine和通道 并推荐使用消息而不是共享内存来进行并发编程 总体来说 Go语言是一个非常现代化的语言 精小但非常强大 学

随机推荐