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

本文中代码可以在 github.com/alfred-zhong/wserver 获取。

背景

最近拿到需求要在网页上展示报警信息。以往报警信息都是通过短信,微信和 App 推送给用户的,现在要让登录用户在网页端也能实时接收到报警推送。

依稀记得以前工作的时候遇到过类似的需求。因为以前的浏览器标准比较陈旧,并且那时用 Java 较多,所以那时候解决这个问题就用了 Comet4J。具体的原理就是长轮询,长链接。但现在毕竟 html5 流行开来了,IE 都被 Edge 接替了,再用以前这种技术就显得过时。

很早以前就听过 WebSocket 的大名,但因为那时很多用户的浏览器还不支持,所以对这个技术也就是浅尝辄止,没有太深入研究过。现在趁着项目需要,就来稍微深入了解一下。

websocket 简介

以往浏览器要获取服务端数据,都是通过发送 HTTP 请求,然后等待服务端回应的。也就是说浏览器端一直是整个请求的发起者,只有它主动,才能获取到数据。而要让浏览器一侧能够获取到服务端的实时数据,就需要不停地向服务端发起请求。虽然大多数情况下并没有获取到实际数据,但这大大增加了网络压力,对于服务端来说压力也直线上升。

后来我们学会了使用长连接 + 长轮询的方式。换句话说,也就是延长 HTTP 请求的存在时间,尽量保持 HTTP 连接。虽然这在一定程度上降低了不少压力,但仍然需要不停地进行轮询,也做不到真正的实时性。(借用一张图)

随着 HTML5 的到来,WebSocket 在 2011 年被定为标准(详情请参见 RFC 6455)。

借用 《Go Web 编程》的话。WebSocket 采用了一些特殊的报头,使得浏览器和服务器只需要做一个握手的动作,就可以在浏览器和服务器之间建立一条连接通道。且此连接会保持在活动状态,你可以使用 JavaScript 来向连接写入或从中接收数据,就像在使用一个常规的 TCP Socket 一样。它解决了 Web 实时化的问题。

由于 WebSocket 是全双工通信,所以当建立了 WebSocket 连接之后,接下来的通信就类似于传统的 TCP 通信了。客户端和服务端可以相互发送数据,不再有实时性的问题。

开发包的选择

在 Go 官方的 SDK 中,并不包含对 WebSocket 的支持,所以必须使用第三方库。

要使用 Golang 开发 WebSocket,选择基本就在 x/net/websocketgorilla/websocket 之间。《Go Web 编程》一书中的例子使用了 x/net/websocket 作为开发包,而且貌似它也更加官方且正式。而实际根据我在网上查询得到的反馈看来,并非如此。x/net/websocket 貌似 Bug 较多,且较为不稳定,问题解决也并不及时。相比之下,gorilla/websocket 则更加优秀。

还有对于 Gorilla web toolkit 组织的贡献,必须予以感谢。

用 Go 编写一个简单的 WebSocket 推送服务的更多相关文章

  1. SSM项目使用GoEasy 实现web消息推送服务

      一.背景 之前项目需要做一个推送功能,最开始我用websocket实现我的功能.使用websocket的好处是免费自主开发,但是有几个问题:1)浏览器的兼容问题,尤其是低版本的ie:2)因为是推送 ...

  2. 移动互联网实战--Apple的APNS桩推送服务的实现(2)

    前记: 相信大家在搞IOS推送服务的开发时, 会直接使用javapns api来简单实现, 调试也直连Apple的APNS服务(产品/测试版)来实现. 很少有人会写个APNS的桩服务, 事实也是如此. ...

  3. springboot搭建一个简单的websocket的实时推送应用

    说一下实用springboot搭建一个简单的websocket 的实时推送应用 websocket是什么 WebSocket是一种在单个TCP连接上进行全双工通信的协议 我们以前用的http协议只能单 ...

  4. 编写一个简单的C++程序

    编写一个简单的C++程序 每个C++程序都包含一个或多个函数(function),其中一个必须命名为main.操作系统通过调用main来运行C++程序.下面是一个非常简单的main函数,它什么也不干, ...

  5. 使用Java编写一个简单的Web的监控系统cpu利用率,cpu温度,总内存大小

    原文:http://www.jb51.net/article/75002.htm 这篇文章主要介绍了使用Java编写一个简单的Web的监控系统的例子,并且将重要信息转为XML通过网页前端显示,非常之实 ...

  6. 编写一个简单的Web Server

    编写一个简单的Web Server其实是轻而易举的.如果我们只是想托管一些HTML页面,我们可以这么实现: 在VS2013中创建一个C# 控制台程序 编写一个字符串扩展方法类,主要用于在URL中截取文 ...

  7. javascript编写一个简单的编译器(理解抽象语法树AST)

    javascript编写一个简单的编译器(理解抽象语法树AST) 编译器 是一种接收一段代码,然后把它转成一些其他一种机制.我们现在来做一个在一张纸上画出一条线,那么我们画出一条线需要定义的条件如下: ...

  8. Java入门篇(一)——如何编写一个简单的Java程序

    最近准备花费很长一段时间写一些关于Java的从入门到进阶再到项目开发的教程,希望对初学Java的朋友们有所帮助,更快的融入Java的学习之中. 主要内容包括JavaSE.JavaEE的基础知识以及如何 ...

  9. 用C语言编写一个简单的词法分析程序

    问题描述: 用C或C++语言编写一个简单的词法分析程序,扫描C语言小子集的源程序,根据给定的词法规则,识别单词,填写相应的表.如果产生词法错误,则显示错误信息.位置,并试图从错误中恢复.简单的恢复方法 ...

随机推荐

  1. Docker 小记 — Compose & Swarm

    前言 任何相对完整的应用服务都不可能是由单一的程序来完成支持,计划使用 Docker 来部署的服务更是如此.大型服务需要进行拆分,形成微服务集群方能增强其稳定性和可维护性.本篇随笔将对 Docker ...

  2. 深度优先搜索DFS和广度优先搜索BFS简单解析(新手向)

    深度优先搜索DFS和广度优先搜索BFS简单解析 与树的遍历类似,图的遍历要求从某一点出发,每个点仅被访问一次,这个过程就是图的遍历.图的遍历常用的有深度优先搜索和广度优先搜索,这两者对于有向图和无向图 ...

  3. 反射(C#编程)

    反射提供了封装程序集.模块和类型的对象(Type 类型).可以使用反射动态创建类型的实例,将类型绑定到现有对象,或从现有对象获取类型并调用其方法或访问其字段和属性.如果代码中使用了属性,可以利用反射对 ...

  4. 【BZOJ1855】股票交易(动态规划,单调队列)

    [BZOJ1855]股票交易(动态规划,单调队列) 题面 BZOJ 题解 很显然,状态之和天数以及当天剩余的股票数有关 设\(f[i][j]\)表示第\(i\)天进行了交易,剩余股票数为\(j\)的最 ...

  5. [Luogu3041][USACO12JAN]视频游戏的连击Video Game Combos

    题面 sol 设\(f_{i,j}\)表示填了前\(i\)个字母,在\(AC\)自动机上跑到了节点\(j\)的最大得分.因为匹配需要暴跳\(fail\)所以预先把\(fail\)指针上面的匹配数传下来 ...

  6. [BZOJ1004] [HNOI2008] Cards (Polya定理)

    Description 小春现在很清闲,面对书桌上的N张牌,他决定给每张染色,目前小春只有3种颜色:红色,蓝色,绿色.他询问Sun有多少种染色方案,Sun很快就给出了答案.进一步,小春要求染出Sr张红 ...

  7. Idea工具开发 SpringBoot整合JSP(毕设亲测可用)

    因为,临近毕业了,自己虽然也学了很多框架.但是,都是在别人搭建好的基础上进行项目开发.但是springboot的官方文档上明确指出不提倡使用jsp进行前端开发,但是在校期间只学了jsp作为前端页面.所 ...

  8. ORM Basic

    ORM即object relational mapping 对象关系映射程序,可以在操作数据库的时候使用自有的语言而不必使用数据库的语言. 在python中,最强大的ORM框架就是SQLAlchemy ...

  9. LTS和其他解决方案的比较(官方)

    主要根据LTS支持的几种任务(实时任务.定时任务.Cron任务,Repeat任务)和其他一些 开源框架在应用场景上做比较. 实时任务,实时执行 这种场景下,当任务量比较小的时候,单机都可以完成的时候. ...

  10. Android Screen Monito

    1.下载 Android Screen Monitor http://code.google.com/p/android-screen-monitor/ (1) 下載 ASM_2_40.zip 并解压 ...