golang Gin framework with websocket
概述
对于 golang 的 web 开发, 之前写过 2 篇 blog, 分别介绍了:
- 在 Gin 框架下, 各类 http API 的开发方法(包括文件上传, 下载等) golang Web 方案
- Gin 框架下反向代理的使用: 反向代理的使用
这里再给之前的 Web 方案中加上 Websocket 的部分, 基本就能涵盖日常开发所需的所有接口类型了.
golang websocket 库
这里使用的 websocket 库来自 Gorilla web toolkit
下面用代码来演示如何在 Gin 框架中结合 websocket API
示例
后端
后端提供 2 种 API, 分别支持 text 格式和 json 格式的消息 示例中的 API 每次收到消息后, 返回 10 次
  1  package main
  2
  3  import (
  4   "log"
  5   "net/http"
  6   "strconv"
  7   "time"
  8
  9   "github.com/gin-contrib/static"
 10   "github.com/gin-gonic/gin"
 11   "github.com/gorilla/websocket"
 12  )
 13
 14  var upGrader = websocket.Upgrader{
 15   CheckOrigin: func(r *http.Request) bool {
 16     return true
 17   },
 18  }
 19
 20  // webSocket返回text 格式
 21  func textApi(c *gin.Context) {
 22   //升级get请求为webSocket协议
 23   ws, err := upGrader.Upgrade(c.Writer, c.Request, nil)
 24   if err != nil {
 25     log.Println("error get connection")
 26     log.Fatal(err)
 27   }
 28   defer ws.Close()
 29   //读取ws中的数据
 30   mt, message, err := ws.ReadMessage()
 31   if err != nil {
 32     log.Println("error read message")
 33     log.Fatal(err)
 34   }
 35
 36   //写入ws数据, pong 10 times
 37   var count = 0
 38   for {
 39     count++
 40     if count > 10 {
 41       break
 42     }
 43
 44     message = []byte(string(message) + " " + strconv.Itoa(count))
 45     err = ws.WriteMessage(mt, message)
 46     if err != nil {
 47       log.Println("error write message: " + err.Error())
 48     }
 49     time.Sleep(1 * time.Second)
 50   }
 51  }
 52
 53  //webSocket返回 json格式
 54  func jsonApi(c *gin.Context) {
 55   //升级get请求为webSocket协议
 56   ws, err := upGrader.Upgrade(c.Writer, c.Request, nil)
 57   if err != nil {
 58     log.Println("error get connection")
 59     log.Fatal(err)
 60   }
 61   defer ws.Close()
 62   var data struct {
 63     A string `json:"a"`
 64     B int    `json:"b"`
 65   }
 66   //读取ws中的数据
 67   err = ws.ReadJSON(&data)
 68   if err != nil {
 69     log.Println("error read json")
 70     log.Fatal(err)
 71   }
 72
 73   //写入ws数据, pong 10 times
 74   var count = 0
 75   for {
 76     count++
 77     if count > 10 {
 78       break
 79     }
 80
 81     err = ws.WriteJSON(struct {
 82       A string `json:"a"`
 83       B int    `json:"b"`
 84       C int    `json:"c"`
 85     }{
 86       A: data.A,
 87       B: data.B,
 88       C: count,
 89     })
 90     if err != nil {
 91       log.Println("error write json: " + err.Error())
 92     }
 93     time.Sleep(1 * time.Second)
 94   }
 95  }
 96
 97  func websocketGin() {
 98   r := gin.Default()
 99   r.GET("/json", jsonApi)
100   r.GET("/text", textApi)
101
102   // static files
103   r.Use(static.Serve("/", static.LocalFile("./public", true)))
104
105   r.NoRoute(func(c *gin.Context) {
106     c.File("./public/index.html")
107   })
108
109   r.Run(":8000")
110  }
后端代码中有个静态文件的路由 r.Use(static.Serve("/", static.LocalFile("./public", true)))
只要将下面的前端代码命名为 index.html 并放在和后端代码根目录下的 public 文件夹中,
就可以在启动后端之后, 直接通过访问 *http://localhost:8000" 来显示页面了
前端
前端很简单, 就是在页面初始化完成后创建 websocket 连接, 然后发送消息并显示接受到的消息
 1  <!DOCTYPE html>
 2  <html lang="en">
 3    <head>
 4      <meta charset="UTF-8" />
 5      <title>index</title>
 6    </head>
 7    <body>
 8      <h1>test websocket</h1>
 9      <p id="message-json"></p>
10      <p id="message-text"></p>
11      <script>
12        function jsonWS() {
13          var ws = new WebSocket("ws://localhost:8000/json");
14          //连接打开时触发
15          ws.onopen = function (evt) {
16            console.log("Connection open ...");
17            var obj = { a: "bb", b: 2 };
18            ws.send(JSON.stringify(obj));
19          };
20          //接收到消息时触发
21          ws.onmessage = function (evt) {
22            console.log("Received Message: " + evt.data);
23            document.getElementById("message-json").innerText += evt.data;
24          };
25          //连接关闭时触发
26          ws.onclose = function (evt) {
27            console.log("Connection closed.");
28          };
29        }
30
31        function textWS() {
32          var ws = new WebSocket("ws://localhost:8000/text");
33          //连接打开时触发
34          ws.onopen = function (evt) {
35            console.log("Connection open ...");
36            ws.send("text message");
37          };
38          //接收到消息时触发
39          ws.onmessage = function (evt) {
40            console.log("Received Message: " + evt.data);
41            document.getElementById("message-text").innerText = evt.data;
42          };
43          //连接关闭时触发
44          ws.onclose = function (evt) {
45            console.log("Connection closed.");
46          };
47        }
48        // 启动 websocket
49        jsonWS();
50        textWS();
51      </script>
52    </body>
53  </html>
结论
运行之后, 就可以看到页面上显示的 message 了, 发送一次信息, 会收到 10 条返回.
golang Gin framework with websocket的更多相关文章
- Golang Gin 项目包依赖管理 godep 使用
		Golang Gin 项目包依赖管理 godep 使用 标签(空格分隔): Go 在按照github.com/tools/godep文档go get完包以后,调整项目结构为$GOPATH/src/$P ... 
- Golang Gin 项目使用 Swagger
		Golang Gin 项目使用 Swagger 标签(空格分隔): Go 首先需要github.com/swaggo/gin-swagger和github.com/swaggo/gin-swagger ... 
- Golang Gin实践 番外 请入门 Makefile
		Golang Gin实践 番外 请入门 Makefile 原文地址:Golang Gin实践 番外 请入门 Makefile 前言 含一定复杂度的软件工程,基本上都是先编译 A,再依赖 B,再编译 C ... 
- golang(gin框架),基于RESTFUL的跨语言远程通信尝试
		golang(gin框架),基于RESTFUL的跨语言远程通信尝试 背景: 在今年的项目实训过程中,遇到了这样的问题: 企业老师讲课实用的技术栈是Java springboot. 实训实际给我们讲课以 ... 
- 前端程序员学习 Golang gin 框架实战笔记之一开始玩 gin
		原文链接 我是一名五六年经验的前端程序员,现在准备学习一下 Golang 的后端框架 gin. 以下是我的学习实战经验,记录下来,供大家参考. https://github.com/gin-gonic ... 
- 我的Vue之旅 10 Gin重写后端、实现页面详情页 Mysql + Golang + Gin
		第三期 · 使用 Vue 3.1 + Axios + Golang + Mysql + Gin 实现页面详情页 使用 Gin 框架重写后端 Gin Web Framework (gin-gonic.c ... 
- 👮 Golang Gin/Ace/Iris/Echo RBAC 鉴权库
		GRBAC 项目地址: https://github.com/storyicon/grbac Grbac是一个快速,优雅和简洁的RBAC框架.它支持增强的通配符并使用Radix树匹配HTTP请求.令人 ... 
- [Golang] Gin框架学习笔记
		0x0 Gin简介 1.Gin 是什么? Gin 是一个用 Go (Golang) 编写的 HTTP web 框架. 它是一个类似于 martini 但拥有更好性能的 API 框架, 由于 httpr ... 
- golang gin框架 使用swagger生成api文档
		github地址:https://github.com/swaggo/gin-swagger 1.下载swag $ go get -u github.com/swaggo/swag/cmd/swag ... 
随机推荐
- 基于django快速开发一个网站(一)
			基于django快速开发一个网站(一) * 创建虚拟环境.基于虚拟环境创建django==2.0.0和图片加载库和mysql数据库驱动 1. 创建目录并创建虚拟环境 ╰$ mkdir Cornuco ... 
- 写给.NET开发者的Python教程(三):运算符、条件判断和循环语句
			本节会介绍Python中运算符的用法,以及条件判断和循环语句的使用方法. 运算符 运算符包括算术运算符.赋值运算符.比较运算符.逻辑运算符等内容,大部分用法和C#基本一致,下面我们来看一下: 算数运算 ... 
- 剑指 Offer 19. 正则表达式匹配
			题目描述 请实现一个函数用来匹配包含'. '和'*'的正则表达式.模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(含0次).在本题中,匹配是指字符串的所有字符匹配整个模式. ... 
- leetcode刷题-39组合总和
			题目 给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合. candidates 中的数字可以无限制重 ... 
- java中整型、浮点型、char型扩展
			怎么区分是什么进制? 二进制:0b开头,eg: int i = 0b10; 八进制:0开头,eg: int k = 010; 十进制: 十六进制:0x开头,eg: int j = 0x10; 浮点数类 ... 
- SpringBoot版不需要配置文件注解获取当前登录用户
			本文讯(2019年3月30日 飞快的蜗牛博客) 我是一个懒人,很久不写博客,想起来看到也不一定会写,只有心血来潮的时候写写,"钱塘江上潮信来,今日方知我是我"...... 空杯 ... 
- tsconfig.json无法写入webpack.config.js 因为它会覆盖输入文件。
			这个错误是什么意思?为什么要写入这个文件?即使我将该文件从项目中排除,该错误仍然存在.我该如何纠正这一点? 我将webpack.config.js文件删除,问题仍然存在. 解决方法: 如果未指定e ... 
- 云计算openstack共享组件——Memcache 缓存系统(4)
			一.缓存系统 一.静态web页面: 1.在静态Web程序中,客户端使用Web浏览器(IE.FireFox等)经过网络(Network)连接到服务器上,使用HTTP协议发起一个请求(Request),告 ... 
- turtle空间坐标系
			利用空间坐标改变行进 以海龟的角度来看,无论往那个方向运行,都叫正方向 turtle.fd向海龟的正前方运行,turtle.bk向反方向运行 
- 对比ERP解读企业资产管理EAM在电力行业应用
			对比ERP解读企业资产管理EAM在电力行业应用 .关于EAMEAM (Enterprise Asset Management)企业资产管理,是面向固定资产占企业资产主要部分的资产密集型(Capital ... 
