英文:
How to make an OUTGOING websocket connection request in GO
问题
我发现很多关于如何在Go中创建接受ws连接的websocket服务的示例,但没有一个示例是用于发送ws连接的。
由于ws请求最初是作为普通的rest请求执行的,我尝试了以下代码:
request, err := http.NewRequest("GET", "ws://localhost:8081/ws", nil)
if err != nil {
fmt.Println(err)
return
}
_, err = http.DefaultClient.Do(request)
if err != nil {
fmt.Println(err)
return
}
client := newClient(*websocket.Conn) // 我如何获取*websocket.Conn?
go client.Read()
go client.Write()
clientsMap.Add(client)
但显然这不起作用,我得到了一个不支持的协议方案"ws"的错误。
我该如何建立ws连接并获取*websocket.Conn?
英文:
I find a lot of examples of how to make a websocket service in Go that accepts ws connections, but not one to send them.
Since the ws request is initially executed as a normal rest request, I try something like this
request, err := http.NewRequest("GET", "ws://localhost:8081/ws", nil)
if err != nil {
fmt.Println(err)
return
}
_, err = http.DefaultClient.Do(request)
if err != nil {
fmt.Println(err)
return
}
client := newClient(*websocket.Conn) // how i can get *websocket.Conn?
go client.Read()
go client.Write()
clientsMap.Add(client)
But this obviously doesn't work, I get an unsupported protocol scheme "ws" error.
How do I make a ws connection and get *websocket.Conn?
答案1
得分: 2
如果你正在使用godoc websocket,你可以使用该包中的Dialer.Dial或Dialer.DialContext。以下是如何使用的示例代码。
dial, _, err := websocket.DefaultDialer.Dial("ws://localhost:8081/ws", nil)
if err != nil {
log.Fatalln(err)
}
defer dial.Close()
err = dial.WriteMessage(websocket.TextMessage, []byte("hello"))
if err != nil {
log.Fatalln(err)
}
err = dial.WriteMessage(websocket.TextMessage, []byte("world"))
if err != nil {
log.Fatalln(err)
}
完整的代码可以在这里查看。
package main
import (
"log"
"net/http"
"sync"
"github.com/gorilla/websocket"
)
func main() {
wg := sync.WaitGroup{}
wg.Add(2)
// 服务器
go func() {
defer wg.Done()
var (
upgrader = &websocket.Upgrader{}
stopChan = make(chan struct{})
)
http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {
defer func() {
close(stopChan)
}()
upgrade, err := upgrader.Upgrade(w, r, nil)
if err != nil {
return
}
for {
msgType, msg, err := upgrade.ReadMessage()
if err != nil {
log.Println("连接已关闭,", err)
return
}
log.Println(msgType, string(msg))
}
})
go func() {
err := http.ListenAndServe("localhost:8081", nil)
if err != nil {
log.Fatalln(err)
}
}()
<-stopChan
}()
// Dialer (客户端)
go func() {
defer wg.Done()
dial, _, err := websocket.DefaultDialer.Dial("ws://localhost:8081/ws", nil)
if err != nil {
log.Fatalln(err)
}
defer dial.Close()
err = dial.WriteMessage(websocket.TextMessage, []byte("hello"))
if err != nil {
log.Fatalln(err)
}
err = dial.WriteMessage(websocket.TextMessage, []byte("world"))
if err != nil {
log.Fatalln(err)
}
}()
wg.Wait()
}
// 输出
// 2022/09/17 07:18:57 1 hello
// 2022/09/17 07:18:57 1 world
// 2022/09/17 07:18:57 连接已关闭, websocket: close 1006 (异常关闭): 意外的 EOF
英文:
If you are using gorilla websocket, you can use Dialer.Dial or Dialer.DialContext from that package. Below is the example on how to use it.
dial, _, err := websocket.DefaultDialer.Dial("ws://localhost:8081/ws", nil)
if err != nil {
log.Fatalln(err)
}
defer dial.Close()
err = dial.WriteMessage(websocket.TextMessage, []byte("hello"))
if err != nil {
log.Fatalln(err)
}
err = dial.WriteMessage(websocket.TextMessage, []byte("world"))
if err != nil {
log.Fatalln(err)
}
For the full code, you can check this.
package main
import (
"log"
"net/http"
"sync"
"github.com/gorilla/websocket"
)
func main() {
wg := sync.WaitGroup{}
wg.Add(2)
// Server
go func() {
defer wg.Done()
var (
upgrader = &websocket.Upgrader{}
stopChan = make(chan struct{})
)
http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {
defer func() {
close(stopChan)
}()
upgrade, err := upgrader.Upgrade(w, r, nil)
if err != nil {
return
}
for {
msgType, msg, err := upgrade.ReadMessage()
if err != nil {
log.Println("connection closed,", err)
return
}
log.Println(msgType, string(msg))
}
})
go func() {
err := http.ListenAndServe("localhost:8081", nil)
if err != nil {
log.Fatalln(err)
}
}()
<-stopChan
}()
// Dialer (Client)
go func() {
defer wg.Done()
dial, _, err := websocket.DefaultDialer.Dial("ws://localhost:8081/ws", nil)
if err != nil {
log.Fatalln(err)
}
defer dial.Close()
err = dial.WriteMessage(websocket.TextMessage, []byte("hello"))
if err != nil {
log.Fatalln(err)
}
err = dial.WriteMessage(websocket.TextMessage, []byte("world"))
if err != nil {
log.Fatalln(err)
}
}()
wg.Wait()
}
// output
// 2022/09/17 07:18:57 1 hello
// 2022/09/17 07:18:57 1 world
// 2022/09/17 07:18:57 connection closed, websocket: close 1006 (abnormal closure): unexpected EOF
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论