Go 实现 WebSockets:2. 如何在 Go 中创建 WebSockets 应用程序

简介: 上一篇文章我们先介绍了什么是 WebSockets 协议。本篇文章将来介绍如何利用 Go 来实现一个 WebSockets。要基于 net/http 库编写一个简单的 WebSocket 响应服务器,我们需要:1.建立握手2.从客户端接收数据帧3.向客户端发送数据帧4.关闭握手

前言

上一篇文章我们先介绍了什么是 WebSockets 协议。本篇文章将来介绍如何利用 Go 来实现一个 WebSockets。要基于 net/http 库编写一个简单的 WebSocket 响应服务器,我们需要:

  1. 建立握手
  2. 从客户端接收数据帧
  3. 向客户端发送数据帧
  4. 关闭握手


WebSockets 无需客户端事先请求即可从服务器传输数据,允许来回传递消息并保持连接打开,直到客户端或服务器终止它。因此,可以在客户端和服务器之间进行双向实时数据传输。 WebSocket 通信通常通过 TCP 端口号 443 完成。


WebSocket 协议规范定义了两种 URI 方案:

  • WebSocket (ws):用于非加密连接
  • WebSocket Secure (wss):用于加密连接

建立 HTTP 服务器

WebSockets 建立在 HTTP 之上,所以首先,我们将设置一个基本的 HTTP 服务器,它可以接受客户端连接并提供消息。将以下代码添加到您的 server.go 文件中:

package main
import (
  "fmt"
  "net/http"
)
func main() {
  http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Welcome to the server!\n")
  })
  http.ListenAndServe(":8080", nil)
}


通过运行 go run server.go  启动服务器。当您访问 localhost:8080 时,您应该会看到以下输出:

Welcome to the server!


image.png


发起握手

由于开销较小,WebSocket 可以在 Web 服务器和 Web 浏览器或客户端应用程序之间实现实时通信和快速数据传输。 WebSocket 通信发起一个握手,它使用 HTTP Upgrade() 标头从 HTTP 协议更改为 WebSocket 协议。


要建立 WebSocket 连接,需要在客户端和服务器之间进行一次握手。握手使用 Upgrade() 方法将 HTTP 服务器连接升级到 WebSocket 协议。一旦服务器停止,我们还将使用 defer 关闭连接。


现在,我们修改 server.go 文件,建立一个 WebSocket 握手:


  1. 首先,我们需要获取 gorilla/websocket  库:
$ go get github.com/gorilla/websocket
  1. 定义一个 upgrader 结构,用来保存 WebSocket 连接的读取和写入缓冲区大小等信息:
var upgrader = websocket.Upgrader{
    ReadBufferSize:  1024,
    WriteBufferSize: 1024,
}


  1. 然后更改 server.go 代码:
package main
import (
    "fmt"
    "net/http"
    "github.com/gorilla/websocket"
)
var upgrader = websocket.Upgrader{
    ReadBufferSize:  1024,
    WriteBufferSize: 1024,
}
func main() {
    http.HandleFunc("/echo", func(w http.ResponseWriter, r *http.Request) {
        conn, _ := upgrader.Upgrade(w, r, nil) // error ignored for sake of simplicity
        for {
            // Read message from browser
            msgType, msg, err := conn.ReadMessage()
            if err != nil {
                return
            }
            // Print the message to the console
            fmt.Printf("%s sent: %s\n", conn.RemoteAddr(), string(msg))
            // Write message back to browser
            if err = conn.WriteMessage(msgType, msg); err != nil {
                return
            }
        }
    })
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        http.ServeFile(w, r, "websockets.html")
    })
    http.ListenAndServe(":8080", nil)
}


  1. 新建一个 websockets.html 文件,写入如下代码:
<!-- websockets.html -->
<input id="input" type="text" />
<button onclick="send()">Send</button>
<pre id="output"></pre>
<script>
    var input = document.getElementById("input");
    var output = document.getElementById("output");
    var socket = new WebSocket("ws://localhost:8080/echo");
    socket.onopen = function () {
        output.innerHTML += "Status: Connected\n";
    };
    socket.onmessage = function (e) {
        output.innerHTML += "Server: " + e.data + "\n";
    };
    function send() {
        socket.send(input.value);
        input.value = "";
    }
</script>


  1. 运行 go run server.go 文件
  2. 打开浏览器,输入 http://localhost:8080/ ,然后就能看到如下界面:

image.png


  1. 当我们向服务器输入 hello 后,然后单击 Send 按钮。界面如下:


image.png

  1. 回到服务器终端也能看到如下信息:
$ go run server.go 
[::1]:58036 sent: Hello

至此,一个简单的 WebSockets 就完全实现了。接下来,我们看一下 WebSockets 有哪些实际运用。

WebSockets 的用例

因为 WebSockets 的主要目的是支持全双工或双向通信。除了提供实时更新外,WebSockets 还包括一个可以支持多个打开的 WebSocket 连接的轻量级服务器。与大多数其他方法相比,WebSockets 可以在更长的时间内维持客户端和服务器之间的连接。


目前,WebSockets 为 Android、iOS、Web 和桌面应用程序提供跨平台支持,WebSockets 常用于以下类型的应用程序:


  • 实时消息
  • 多人游戏
  • 实时比分提要
  • 协作编辑工具
  • 实时位置和方向应用
  • 使用 WebRTC 进行音频和视频聊天

总结

在本文中,我们探索了 WebSockets,并简要介绍了它们的工作原理,并仔细研究了全双工通信。为了了解 WebSocket 在 Go 中的工作原理,我们构建了一个简单的待办事项应用程序,该应用程序具有添加和删除任务的功能。最后,我们查看了使 WebSockets 有用和通用的几个附加特性,并回顾了 WebSockets 的一些实际应用。在 Go 中使用 WebSockets 相当简单明了,但这种组合会对应用程序的性能产生显着影响。

相关文章
|
2月前
|
Cloud Native Go 开发工具
不改一行代码轻松玩转 Go 应用微服务治理
为了更好的进行 Go 应用微服务治理,提高研发效率和系统稳定性,本文将介绍 MSE 微服务治理方案,无需修改业务代码,实现治理能力。
19766 5
|
2月前
|
数据采集 网络协议 测试技术
使用Go Validator在Go应用中有效验证数据
使用Go Validator在Go应用中有效验证数据
|
2月前
|
并行计算 数据挖掘 大数据
[go 面试] 并行与并发的区别及应用场景解析
[go 面试] 并行与并发的区别及应用场景解析
|
8天前
|
Kubernetes Go 持续交付
一个基于Go程序的持续集成/持续部署(CI/CD)
本教程通过一个简单的Go程序示例,展示了如何使用GitHub Actions实现从代码提交到Kubernetes部署的CI/CD流程。首先创建并版本控制Go项目,接着编写Dockerfile构建镜像,再配置CI/CD流程自动化构建、推送Docker镜像及部署应用。此流程基于GitHub仓库,适用于快速迭代开发。
25 3
|
8天前
|
Kubernetes 持续交付 Go
创建一个基于Go程序的持续集成/持续部署(CI/CD)流水线
创建一个基于Go程序的持续集成/持续部署(CI/CD)流水线
|
1月前
|
安全 大数据 Go
深入探索Go语言并发编程:Goroutines与Channels的实战应用
在当今高性能、高并发的应用需求下,Go语言以其独特的并发模型——Goroutines和Channels,成为了众多开发者眼中的璀璨明星。本文不仅阐述了Goroutines作为轻量级线程的优势,还深入剖析了Channels作为Goroutines间通信的桥梁,如何优雅地解决并发编程中的复杂问题。通过实战案例,我们将展示如何利用这些特性构建高效、可扩展的并发系统,同时探讨并发编程中常见的陷阱与最佳实践,为读者打开Go语言并发编程的广阔视野。
|
6天前
|
IDE Go 数据处理
Go to Learn Go之第一个Go程序
Go to Learn Go之第一个Go程序
11 0
|
2月前
|
Linux Shell Go
如何构建和安装 Go 程序
如何构建和安装 Go 程序
32 1
|
2月前
|
安全 Java Go
为什么选择Go语言编写网络应用程序
为什么选择Go语言编写网络应用程序
|
2月前
|
存储 缓存 安全
下一篇
无影云桌面