文章目录
- 目的
- 使用示例与说明
- 总结
目的
WebSocket是Web开发应用中非常常用的功能,用于客户端和服务器间长时间的实时双向数据通讯。Golang中官方并没有实现这个功能,需要借助第三方的包来实现。
目前被最广泛使用的包是 gorilla/websocket
https://pkg.go.dev/github.com/gorilla/websocket 。这个包实现的功能相对来说比较基础,所以也有很多在这之上进行封装的包,比如本文将使用的 olahol/melody
https://pkg.go.dev/github.com/olahol/melody 。
这篇文章将简单介绍使用 olahol/melody
包(当前版本为 v1.1.3
)进行WebSocket通讯。
使用示例与说明
olahol/melody
包是自带几个例程的:https://github.com/olahol/melody/tree/master/examples
这里将通过简单的示例介绍下这个包的内容,首先准备两个下面两个文件:
test.go
package main
import (
"fmt"
"net/http"
"github.com/olahol/melody"
)
func main() {
m := melody.New() // New()方法中也可以配置一些参数
m.HandleConnect(func(s *melody.Session) {
fmt.Println("会话连接建立")
fmt.Println("Session.Request: ", s.Request)
fmt.Println("Session.Keys: ", s.Keys)
fmt.Println("LocalAddr: ", s.LocalAddr(), "RemoteAddr: ", s.RemoteAddr())
})
m.HandleDisconnect(func(s *melody.Session) {
fmt.Println("会话连接断开")
})
m.HandleError(func(s *melody.Session, err error) {
fmt.Println("会话出现错误")
fmt.Println(err)
})
m.HandleMessage(func(s *melody.Session, msg []byte) {
fmt.Println("收到来自客户端的消息: ", string(msg))
s.Write([]byte("naisu233~~~~")) // 向客户端发送消息
})
http.HandleFunc("/ws-m", func(w http.ResponseWriter, r *http.Request) {
m.HandleRequest(w, r) // 访问 /ws-m 时将转交给melody处理,以实现websocket功能
})
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "index.html") // 访问 / 时打开index.html
})
http.ListenAndServe(":8080", nil) // 启动服务器,访问 http://localhost:8080/ 进行测试
}
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<script>
const socket = new WebSocket('ws://localhost:8080/ws-m'); // 创建WebSocket连接
socket.onopen = (event) => {
console.log('连接成功');
socket.send('Hello Naisu!'); // 通过WebSocket向服务器发送消息
};
socket.onclose = (event) => {
console.log('连接被关闭');
};
socket.onerror = (event) => {
console.log('连接因错误而关闭');
};
socket.onmessage = (event) => {
console.log('收到数据: ', event.data); // 打印来自服务器的消息
};
setTimeout(() => {
socket.close(); // 关闭当前连接
}, 3000);
</script>
</body>
</html>
上面的例子展现了WebSocket客户端和服务器整个连接通讯的流程,及相关内容:
- 对于WebSocket而言主要的有
连接 / 断开 / 错误 / 收到消息
这四个事件。 melody.Session
是客户端对象的会话,保存了特定客户端相关的内容;melody.Session.Keys
中可以用来临时记录一些客户信息,使用(s) Set(key, value)
方法设置其中内容,使用(s) Get(key)
方法获取设置的内容;- 可以使用
melody.Session
的Write
或WriteBinary
方法向客户端发送消息; - 可以使用
melody
的func (m *Melody) Sessions() ([]*Session, error)
方法获取所有的Session
;
WebSocket除了上面单点的发送消息外,作为服务器还可以向所有已连接的客户端广播消息:
test.go
package main
import (
"net/http"
"github.com/olahol/melody"
)
func main() {
m := melody.New() // New()方法中也可以配置一些参数
m.HandleMessage(func(s *melody.Session, msg []byte) {
m.Broadcast(msg) // 向所有客户端广播消息
})
http.HandleFunc("/ws-m", func(w http.ResponseWriter, r *http.Request) {
m.HandleRequest(w, r) // 访问 /ws-m 时将转交给melody处理,以实现websocket功能
})
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "index.html") // 访问 / 时打开index.html
})
http.ListenAndServe(":8080", nil) // 启动服务器,访问 http://localhost:8080/ 进行测试
}
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<input type="text" placeholder="输入内容并回车" >
<pre></pre>
<script>
const socket = new WebSocket('ws://localhost:8080/ws-m'); // 创建WebSocket连接
socket.onmessage = (event) => { // 收到来自服务器的WebSocket消息
document.querySelector('pre').innerText += event.data + '\n';
};
document.querySelector('input').onkeydown = (event) => {
if (event.keyCode === 13) { // 如果按下的是回车键
socket.send(document.querySelector('input').value);
}
};
</script>
</body>
</html>
上面演示中向所有客户端广播了消息,事实上 olahol/melody
包中还有很多广播方法,可以精细的控制向指定的一些客户端广播消息,更多内容可以参考官方文档。
总结
使用melody包进行WebSocket通讯操作上是比较简单的,总体使用上不会存在障碍。