golang实现WebSocket的商业化使用的开发逻辑(1)
WebSocket是什么
WebSocket 是一种在单个 TCP 连接上进行
全双工
通信的协议。其最大特点之一就是:服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话。
开发前期准备(默认已经安装了golang
语言环境)
我这里通过两个库来实现整个WebSocket的开发,这两个库分别是
gin
和gorilla/websocket
。这里有两种方法来获取这两个库,其一就是用go get
,其二是使用git bash
中的git clone
拉取。我使用的是第二种方法,具体使用方法如下。
拉取
gorilla/websocket
到GOPATH
的src
下的github.com
目录里面git clone https://github.com/gorilla/websocket
拉取
gin-gonic/gin
到GOPATH
的src
下的github.com
目录里面git clone https://github.com/gin-gonic/gin
WebSocket 简单使用开发(内部并发不安全,服务端server
)
开发逻辑
定义将
HTTP
升级成WebSocket
的全局变量upgrade
,并默认允许跨域。var (
upgrade = &websocket.Upgrader{
// 允许跨域
CheckOrigin: func(r *http.Request) bool {
return true
}, }
)确定服务的基本结构,即确定
main
函数的结构func main(){
r := gin.Default()
r.GET("/test",func(c *gin.Context){})
err := r.Run(":1234")
if err != nil{
return
}
}
这就是用
gin
框架搭载的一个简单HTTP
服务,这里可以看出WebSocket就是由HTTP
进行升级得到的。现在我们只要把r.GET()
里面的func(c *gin.Context){}
进行封装,即可完善整个服务。完善内部逻辑
func handler(c *gin.Context) {
// 定义两个变量,其一就是*websocket.Conn,其二就是error
var (
conn *websocket.Conn
err error
)
// 赋值变量,这里就用到了前面定义的upgrade
// conn这结构体内有许多功能,可以都尝试一下,当一般常使用:
// conn.ReadMessage()
// conn.WriteMessage()
// conn.Close()
if conn, err = upgrade.Upgrade(c.Writer, c.Request, nil); err != nil {
return
}
// 为了防止忘记关闭WebSocket连接,使用defer
defer func(conn *websocket.Conn) {
if err = conn.Close(); err != nil {
return
}
}(conn) // 这里只处理客户端传什么就返回什么
for {
// 定义数据变量
var (
msgType int // 数据类型
data []byte // 数据
errMsg error //错误信息
)
// 接收数据
if msgType, data, errMsg = conn.ReadMessage(); errMsg != nil {
break
}
// 响应数据
if errMsg = conn.WriteMessage(msgType,data); errMsg != nil{
break
}
}
}
这里解释一下为什么说这个使用为什么内部线程不安全,因为
conn.ReadMessage()
和conn.WriteMessage()
这两个接口是并发不安全的,它们在同一时刻不能被不同线程同时调用,否者会使服务中断。具体情况可以在函数里面写过几个goroutine
就可以深刻体会它们的这种不安全
。这就导致了一种情况做不到,就是若是想做一个心跳机制,这里就不能再开一个goroutine
。将
main
函数调整func main() {
r := gin.Default()
r.GET("/test", handler)
err := r.Run(":1234")
if err != nil {
return
}
}
只要把
r.GET()
里面的func(c *gin.Context){}
提到成handler
函数即可。
完整代码如下
package main
import (
"github.com/gin-gonic/gin"
"golang.org/websocket"
"net/http"
)
var (
upgrade = &websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
return true
},
}
)
func handler(c *gin.Context) {
// 定义两个变量,其一就是*websocket.Conn,其二就是error
var (
conn *websocket.Conn
err error
)
// 赋值变量,这里就用到了前面定义的upgrade
// conn这结构体内有许多功能,可以都尝试一下,当一般常使用:
// conn.ReadMessage()
// conn.WriteMessage()
// conn.Close()
if conn, err = upgrade.Upgrade(c.Writer, c.Request, nil); err != nil {
return
}
// 为了防止忘记关闭WebSocket连接,使用defer
defer func(conn *websocket.Conn) {
if err = conn.Close(); err != nil {
return
}
}(conn)
// 这里只处理客户端传什么就返回什么
for {
// 定义数据变量
var (
msgType int // 数据类型
data []byte // 数据
errMsg error //错误信息
)
// 接收数据
if msgType, data, errMsg = conn.ReadMessage(); errMsg != nil {
break
}
// 响应数据
if errMsg = conn.WriteMessage(msgType,data); errMsg != nil{
break
}
}
}
func main() {
r := gin.Default()
r.GET("/test", handler)
err := r.Run(":1234")
if err != nil {
return
}
}
WebSocket 商业化使用开发 (内部并发安全,服务端server
)
逻辑结构图
说明:
封装
服务函数封装
完整代码
golang实现WebSocket的商业化使用的开发逻辑(1)的更多相关文章
- golang之websocket 源码分析
下载go的websocket包. 1. 通过google官方的方法, 需要hg来同步代码. 由于墙的原因, 还需要设置代理. 比较麻烦 2. http://gopm.io/ 通过该网站下载, 这是go ...
- golang gorilla websocket例子
WebSocket协议是基于TCP的一种新的网络协议.它实现了浏览器与服务器全双工(full-duplex)通信--允许服务器主动发送信息给客户端. WebSocket通信协议于2011年被IETF定 ...
- 使用golang对海康sdk进行业务开发
目录 准备工作 开发环境信息 改写HCNetSDK.h头文件 开发过程 基本数据类型转换 业务开发 参考 项目最近需要改造升级:操作海康摄像头(包括登录,拍照,录像)等基本功能.经过一段时间研究后,发 ...
- go语言系列--golang在windows上的安装和开发环境goland的配置
在windows上安装golang软件 golang中国网址为:https://studygolang.com/dl 我的学习选择版本:1.12.5 golang 1.12.5版本更新的内容:gola ...
- 基于golang的websocket通信实现
代码: https://gitee.com/knox_xzk/websocket
- GoLang语言环境搭建及idea集成开发(超详细)
一.所需安装包(windows) 1. https://golang.org/dl/ 下载 MSI installer.不会翻墙的自己找国内下载,双击运行,按照提示安装即可.环境变量自动配置 2.i ...
- 【GoLang】GO语言系列--001.GO开发环境搭建
- 微信小程序开发---逻辑层(App Service)
再说逻辑层之前,先说说微信小程序框架(MINA) 小程序开发框架的目标是通过尽可能简单.高效的方式让开发者可以在微信中开发具有原生APP体验的服务. 框架提供了自己的视图层描述语言WXML和WXSS, ...
- 20181220 Oracle程序包基本开发逻辑
做事情,开始也许比较迷茫,也可能工具不会,也可能语言不会,但不要害怕 多去思考而不是盲目的开始工作,盲目的听从,程序开发都是不断训练自己的思维能力. 做每件事情都是有意义的,思考为什么这么做,这么做的 ...
随机推荐
- JAVA 对象的创建与克隆
目录 一.对象的4种创建方式 二.通过new创建对象 三.反射 四.克隆对象 浅拷贝 深拷贝 五.反序列化 六.补充 一.对象的4种创建方式 new 创建 反射 克隆 反序列化 二.通过new创建对象 ...
- opencv笔记--meanshift&camshift
meanshift 被应用于 object track 中,其主要思想如下: 如下图所示,对该点集应用 meanshift 算法可以定位到点集最稠密位置,而点集最稠密位置即为我们需要跟踪的物体位置. ...
- 我们一起来学Shell - shell的条件判断
文章目录 Shell 条件测试语法 符号说明 Shell 测试表达式 文件测试表达式 字符串测试表达式 整数操作符 逻辑操作符 测试表达式的区别总结 Shell 条件判断之if语句 单分支 IF 条件 ...
- mysql数据库怎么存入emoji表情
第一步 设置数据库字符编码为utf8mb4_general_ci 设置相应表字段字符编码为utf8mb4_general_ci 第二步 设置my.cnf增加以下配置信息 [client] defau ...
- volatile关键字的相关学习记录
1:volatile是什么? Volatile是java虚拟机提供的一种轻量级的同步机制,具有 三大特性,分别是:保证可见性.不保证原子性.禁止指令重排 可见性: 概念:每一个线程都有自己的工作内存, ...
- 5大知名的BI工具对比介绍
工欲善其事,必先利其器.企业对于BI工具的需求,已经刻不容缓.国内国外的BI工具不少,如Tableau.FineBI.Power BI.Smartbi等等.本文就对当下市面上最热门的5款知名的BI工具 ...
- 【windows 访问控制】三、访问控制列表 ACL=DACL+SACL
访问控制列表(ACL:Access Control List) ACL列表的结构 ACL 中的每个 ACE 标识一个受信者,并指定该受信者访问规则.安全对象的安全描述符 可以包含两种类型的 ACL:D ...
- C#foreach 本质( 鸭子类型遍历)
探讨关于C#中Foreach的本质 要实现foreach需要满足什么条件? 只要类中实现类中的GetEnumerator()方法.MoveNext()方法.Current属性(俗称鸭子类型)都可以使用 ...
- Java -- next()和nextLine()的区别
next()读取有效字符串,遇到Tab.空格.回车结束,所以不能接收带空格的字符串 nextLine()读取一行,只是以回车结束,所以可以接收带空格的字符串 https://blog.csdn.net ...
- 如何给远程桌面发送“Ctrl+Alt+Delete”命令
转至:https://www.yunweiku.com/forum.php?mod=viewthread&tid=925 当我们远程桌面需要是用ctrl+alt+delete组合键时无法使用, ...