拉模式和推模式

拉模式

1、数据更新频率低,则大多数请求是无效的

2、在线用户量多,则服务端的查询负载高

3、定时轮询拉取,实时性低

推模式

1、仅在数据更新时才需要推送

2、需要维护大量的在线长连接

3、数据更新后可以立即推送

基于webSocket推送

1、浏览器支持的socket编程,轻松维持服务端长连接

2、基于TCP可靠传输之上的协议,无需开发者关心通讯细节

3、提供了高度抽象的编程接口,业务开发成本较低

webSocket协议与交互

通讯流程

客户端->upgrade->服务端

客户端<-switching<-服务端

客户端->message->服务端

客户端<-message<-服务端

实现http服务端

1、webSocket是http协议upgrade而来

2、使用http标准库快速实现空接口:/ws

webSocket握手

1、使用webSocket.Upgrader完成协议握手,得到webSocket长连接

2、操作webSocket api,读取客户端消息,然后原样发送回去

封装webSocket

缺乏工程化设计

1、其他代码模块,无法直接操作webSocket连接

2、webSocket连接非线程安全,并发读/写需要同步手段

隐藏细节,封装api

1、封装Connection结构,隐藏webSocket底层连接

2、封装Connection的api,提供Send/Read/Close等线程安全接口

api原理(channel是线程安全的)

1、SendMessage将消息投递到out channel

2、ReadMessage从in channel读取消息

内部原理

1、启动读协程,循环读取webSocket,将消息投递到in channel

2、启动写协程,循环读取out channel,将消息写给webSocket

// server.go
package main import (
"net/http"
"github.com/gorilla/websocket"
"./impl"
"time"
) var (
upgrader = websocket.Upgrader{
//允许跨域
CheckOrigin: func(r *http.Request) bool {
return true
},
}
) func wsHandler(w http.ResponseWriter, r *http.Request) {
var (
wsConn *websocket.Conn
err error
conn *impl.Connection
data []byte
) //Upgrade:websocket
if wsConn, err = upgrader.Upgrade(w, r, nil); err != nil {
return
}
if conn, err = impl.InitConnection(wsConn); err != nil {
goto ERR
} go func() {
var (
err error
)
for {
if err =conn.WriteMessage([]byte("heartbeat")); err != nil {
return
}
time.Sleep(1 * time.Second)
}
}() for {
if data, err = conn.ReadMessage(); err != nil {
goto ERR
}
if err = conn.WriteMessage(data); err != nil {
goto ERR
} } ERR:
//关闭连接
conn.Close()
} func main() {
//http:localhost:7777/ws
http.HandleFunc("/ws", wsHandler)
http.ListenAndServe("0.0.0.0:7777", nil)
}
// connection.go
package impl import (
"github.com/gorilla/websocket"
"sync"
"github.com/influxdata/platform/kit/errors"
) var once sync.Once type Connection struct {
wsConn *websocket.Conn
inChan chan []byte
outChan chan []byte
closeChan chan byte
isClosed bool
mutex sync.Mutex
} func InitConnection(wsConn *websocket.Conn) (conn *Connection, err error) {
conn = &Connection{
wsConn:wsConn,
inChan:make(chan []byte, 1000),
outChan:make(chan []byte, 1000),
closeChan:make(chan byte, 1),
} //启动读协程
go conn.readLoop() //启动写协程
go conn.writeLoop() return
} //API
func (conn *Connection) ReadMessage() (data []byte, err error) {
select {
case data = <- conn.inChan:
case <- conn.closeChan:
err = errors.New("connection is closed")
}
return
} func (conn *Connection) WriteMessage(data []byte) (err error) {
select {
case conn.outChan <- data:
case <- conn.closeChan:
err = errors.New("connection is closed")
}
return
} func (conn *Connection) Close() {
// 线程安全的close,可重入
conn.wsConn.Close()
conn.mutex.Lock()
if !conn.isClosed {
close(conn.closeChan)
conn.isClosed = true
}
conn.mutex.Unlock()
} //内部实现
func (conn *Connection) readLoop() {
var (
data []byte
err error
)
for {
if _, data, err = conn.wsConn.ReadMessage(); err != nil {
goto ERR
} //阻塞在这里,等待inChan有空位置
//但是如果writeLoop连接关闭了,这边无法得知
//conn.inChan <- data select {
case conn.inChan <- data:
case <-conn.closeChan:
//closeChan关闭的时候,会进入此分支
goto ERR
}
}
ERR:
conn.Close()
} func (conn *Connection) writeLoop() {
var (
data []byte
err error
)
for {
select {
case data = <- conn.outChan:
case <- conn.closeChan:
goto ERR } if err = conn.wsConn.WriteMessage(websocket.TextMessage, data); err != nil {
goto ERR
}
conn.outChan <- data
}
ERR:
conn.Close()
}

Go实现基于WebSocket的弹幕服务的更多相关文章

  1. 使用JMeter测试基于WebSocket协议的服务

    使用JMeter测试基于WebSocket协议的服务 :first-child{margin-top:0!important}img.plugin{box-shadow:0 1px 3px rgba( ...

  2. day112:MoFang:种植园使用websocket代替http&服务端基于flask-socketio提供服务&服务端响应信息&种植园页面显示初始化

    目录 1.种植园使用websocket代替http 2.服务端基于socket提供服务 3.服务端响应信息 4.种植园页面展示 1.种植园使用websocket代替http 我们需要完成的种植园,是一 ...

  3. 基于 WebSocket 实现 WebGL 3D 拓扑图实时数据通讯同步(二)

    我们上一篇<基于 WebSocket 实现 WebGL 3D 拓扑图实时数据通讯同步(一)>主要讲解了如何搭建一个实时数据通讯服务器,客户端与服务端是如何通讯的,相信通过上一篇的讲解,再配 ...

  4. 高效简易开发基于websocket 的通讯应用

    websocket的主要是为了解决在web上应用长连接进行灵活的通讯应用而产生,但websocket本身只是一个基础协议,对于消息上还不算灵活,毕竟websocket只提供文本和二进制流这种基础数据格 ...

  5. Socket.IO – 基于 WebSocket 构建跨浏览器的实时应用

     Socket.IO 是一个功能非常强大的框架,能够帮助你构建基于 WebSocket 的跨浏览器的实时应用.支持主流浏览器,多种平台,多种传输模式,还可以集合 Exppress 框架构建各种功能复杂 ...

  6. 基于 WebSocket 构建跨浏览器的实时应用

    Socket.IO – 基于 WebSocket 构建跨浏览器的实时应用 Socket.IO 是一个功能非常强大的框架,能够帮助你构建基于 WebSocket 的跨浏览器的实时应用.支持主流浏览器,多 ...

  7. 分享基于 websocket 网页端聊天室

    博客地址:https://ainyi.com/67 有一个月没有写博客了,也是因为年前需求多.回家过春节的原因,现在返回北京的第二天,想想,应该也要分享技术专题的博客了!! 主题 基于 websock ...

  8. 第一节:.Net版基于WebSocket的聊天室样例

    一. 说在前面的话 该篇文章为实时通讯系列的第一节,基于WebSocket编写了一个简易版聊天样例,主要作用是为引出后面SignalR系列的用法及其强大方便之处,通过这个样例与后续的SignalR对比 ...

  9. 基于WebSocket实现聊天室(Node)

    基于WebSocket实现聊天室(Node) WebSocket是基于TCP的长连接通信协议,服务端可以主动向前端传递数据,相比比AJAX轮询服务器,WebSocket采用监听的方式,减轻了服务器压力 ...

随机推荐

  1. 【设计经验】4、SERDES关键技术总结

    一.SERDES介绍 随着大数据的兴起以及信息技术的快速发展,数据传输对总线带宽的要求越来越高,并行传输技术的发展受到了时序同步困难.信号偏移严重,抗干扰能力弱以及设计复杂度高等一系列问题的阻碍.与并 ...

  2. MSMQ队列的简单使用

    微软消息队列-MicroSoft Message Queue(MSMQ) 使用感受:简单. 一.windows安装MSMQ服务 控制面板->控制面板->所有控制面板项->程序和功能- ...

  3. 使用sklearn估计器构建K-Means聚类模型

    实例要求:以sklearn库自带的iris数据集为例,使用sklearn估计器构建K-Means聚类模型,并且完成预测类别功能以及聚类结果可视化. 实例代码: import pandas as pd ...

  4. 【渗透技术】渗透测试技术分析_TomCat

    [渗透技术]渗透测试技术分析_TomCat 本文转自:i春秋论坛 渗透测试-中间人攻击(原理)说起“中间人攻击”我想大多数对渗透测试又了解的朋友都多少有所了解,因为我们用到的次数真是非常的多.它可以将 ...

  5. Python爬虫1-使用urlopen

    GitHub代码练习地址:https://github.com/Neo-ML/PythonPractice/blob/master/SpiderPrac01_urlopen.py 爬虫简介- 爬虫定义 ...

  6. 博客Hexo + github pages + 阿里云绑定域名搭建个人博客

    申请域名 万网购买的域名,地址:https://wanwang.aliyun.com/domain/com?spm=5176.8142029.388261.137.LoKzy7 控制台进行解析 控制台 ...

  7. [Postman]Postman导航(3)

    Postman提供了一个多窗口和多标签界面,供您使用API​​. 此界面设计为您提供尽可能多的API空间. 侧边栏 邮差侧边栏可让您查找和管理请求和集合.侧边栏有两个主要选项卡:  历史记录  和   ...

  8. Rpc框架dubbo-server(v2.6.3) 源码阅读(一)

    额,dubbo的前世今生咱就不说了,有用的人都知道.(最新版本已更名 incubator-dubbo,预计版本3.0,不过咱们就先不掺和别人的开发过程了,以v2.6.3为蓝本) 首先,是工作需要,用到 ...

  9. 一份从0到1的java项目实践清单

    虽说工作就是简单的事情重复做,但不是所有简单的事你都能有机会做的. 我们平日工作里,大部分时候都是在做修修补补的工作,而这也是非常重要的.做好修补工作,做好优化工作,足够让你升职加薪! 但是如果有机会 ...

  10. JSON库的使用研究(一)

    最近用到JSON,收集了一些资料,整理如下: 选择一个合适的JSON库要从多个方面进行考虑: 字符串解析成JSON性能 字符串解析成Java Object性能 Java Object转JSON性能 集 ...